示例#1
0
        public async Task <Result <Deck> > Handle(NewDeckCommand request, CancellationToken cancellationToken)
        {
            var user = await _context.UserDbs
                       .Include(u => u.Deck)
                       .Include(d => d.Deck.Tiles)
                       .AsNoTracking()
                       .FirstOrDefaultAsync(
                u => u.Email == request.Email, cancellationToken);

            if (user == null)
            {
                //create user and deck
                var logicDeck = new LogicDeck(4);

                do
                {
                    logicDeck.Unsort();
                } while (!logicDeck.CheckWinIsPossible());
                logicDeck.Tiles         = logicDeck.Tiles.OrderBy(t => t.Pos).ToList();
                logicDeck.User.Email    = request.Email;
                logicDeck.User.UserName = request.UserName;

                var deckDb = _mapper.Map <DeckDb>(logicDeck);
                _context.Add(deckDb);
                try
                {
                    await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

                    return(Result.Ok <Deck>(_mapper.Map <Deck>(deckDb)));
                }
                catch (DbUpdateException ex)
                {
                    return(Result.Fail <Deck>(ex.Message));
                }
            }

            //reset deck
            try
            {
                var deckDb = user.Deck;

                var logicDeck = _mapper.Map <LogicDeck>(deckDb);
                logicDeck.User.Email    = request.Email;
                logicDeck.User.UserName = request.UserName;
                do
                {
                    logicDeck.Unsort();
                } while (!logicDeck.CheckWinIsPossible());
                logicDeck.Tiles   = logicDeck.Tiles.OrderBy(t => t.Pos).ToList();
                logicDeck.Victory = false;
                logicDeck.Score   = 0;
                _context.Update(_mapper.Map <DeckDb>(logicDeck));
                await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

                return(Result.Ok <Deck>(_mapper.Map <Deck>(logicDeck)));
            }
            catch (DbUpdateException ex)
            {
                return(Result.Fail <Deck>(ex.Message));
            }
        }
        public async Task <Result <Deck> > Handle([NotNull] MoveTileCommand request, CancellationToken cancellationToken)
        {
            //validate tile
            var result = await _validator.ValidateAsync(request, ruleSet : "MoveTileSet", cancellationToken : cancellationToken)
                         .ConfigureAwait(false);

            if (!result.IsValid)
            {
                return(Result.Fail <Deck>(result.Errors.First().ErrorMessage));
            }



            var user = await _context.UserDbs.AsNoTracking()
                       .Include(u => u.Deck)
                       .Include(u => u.Deck.Tiles)
                       .Include(u => u.Records)
                       .FirstOrDefaultAsync(
                u => u.Email == request.Email, cancellationToken);

            if (user == null)
            {
                return(Result.Fail <Deck>("There is no user with such id."));
            }

            try
            {
                var deckDb = user.Deck;
                if (deckDb.Victory)
                {
                    return(Result.Fail <Deck>("this deck already won"));
                }
                var logicDeck = _mapper.Map <LogicDeck>(deckDb);
                logicDeck.SetNearbyTiles();
                if (logicDeck.TileCanMove(request.Tile))
                {
                    logicDeck.Move(request.Tile);
                    logicDeck.Tiles  = logicDeck.Tiles.OrderBy(t => t.Pos).ToList();
                    logicDeck.Score += 1;
                    if (logicDeck.CheckWin())
                    {
                        logicDeck.Victory = true;
                        var recordDb = logicDeck.User.Records.FirstOrDefault(r => r.UserId == logicDeck.UserId);
                        if (recordDb != null)
                        {
                            if (recordDb.Score > logicDeck.Score)
                            {
                                recordDb.Score = logicDeck.Score;
                                await _hubContext.Clients.All.SendAsync("Notice", $"Player {logicDeck.User.UserName} has set new record - {logicDeck.Score}!", CancellationToken.None);
                            }
                        }
                        else
                        {
                            logicDeck.User.Records.Add(new RecordDb()
                            {
                                Score = logicDeck.Score, User = user
                            });
                        }
                    }
                    _context.Update(_mapper.Map <DeckDb>(logicDeck));
                    await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

                    return(Result.Ok <Deck>(_mapper.Map <Deck>(logicDeck)));
                }

                var strTiles = string.Join(',', logicDeck.Tiles.First(t => t.Num == 0).NearbyTiles.Select(t => t.Num));
                return(Result.Fail <Deck>("Selected tile can not be moved. Possible: " + strTiles));
            }
            catch (DbUpdateException ex)
            {
                return(Result.Fail <Deck>(ex.Message));
            }
        }