コード例 #1
0
ファイル: Chow.cs プロジェクト: tthiatma/MahjongBuddy-React
            public async Task <IEnumerable <RoundDto> > Handle(Command request, CancellationToken cancellationToken)
            {
                //Note to consider when chow tile:
                //-when chow tile user need to throw a tile.
                //assign tile ownership to current user
                var round = await _context.Rounds.FindAsync(request.RoundId);

                if (round == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, new { Round = "Could not find round" });
                }

                //TODO only allow chow when it's user's turn

                if (request.ChowTiles == null || request.ChowTiles.Count() != 2)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "invalid data to chow tiles" });
                }

                var boardActiveTiles = round.RoundTiles.Where(t => t.Status == TileStatus.BoardActive);

                if (boardActiveTiles == null || boardActiveTiles.Count() > 1)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "there are no tile or more than one tiles to chow" });
                }

                var tileToChow = boardActiveTiles.First();

                if (tileToChow.Tile.TileType == TileType.Dragon || tileToChow.Tile.TileType == TileType.Flower || tileToChow.Tile.TileType == TileType.Wind)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "tile must be money, round, or stick for chow" });
                }

                var dbTilesToChow = round.RoundTiles.Where(t => request.ChowTiles.Contains(t.Id)).ToList();

                dbTilesToChow.Add(tileToChow);

                var sortedChowTiles = dbTilesToChow.OrderBy(t => t.Tile.TileValue).ToArray();

                //check if its straight
                if (sortedChowTiles[0].Tile.TileValue + 1 == sortedChowTiles[1].Tile.TileValue &&
                    sortedChowTiles[1].Tile.TileValue + 1 == sortedChowTiles[2].Tile.TileValue)
                {
                    int groupIndex = 1;
                    var tileSets   = round.RoundTiles.Where(t => t.Owner == request.UserName && t.TileSetGroup != TileSetGroup.None);
                    if (tileSets.Count() > 0)
                    {
                        var lastIndex = tileSets.GroupBy(t => t.TileSetGroupIndex).Select(g => g.Last()).First().TileSetGroupIndex;
                        groupIndex = lastIndex + 1;
                    }

                    sortedChowTiles.GoGraveyard(request.UserName, TileSetGroup.Chow, round.RoundTiles.GetLastGroupIndex(request.UserName));
                }
                else
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "tile is not in sequence to chow" });
                }

                var currentPlayer = round.RoundPlayers.FirstOrDefault(u => u.GamePlayer.Player.UserName == request.UserName);

                if (currentPlayer == null)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "there are no user with this username in the round" });
                }

                currentPlayer.IsMyTurn  = true;
                currentPlayer.MustThrow = true;

                var otherPlayers = round.RoundPlayers.Where(u => u.IsMyTurn == true && u.GamePlayer.Player.UserName != request.UserName);

                foreach (var otherPlayerTurn in otherPlayers)
                {
                    otherPlayerTurn.IsMyTurn  = false;
                    otherPlayerTurn.MustThrow = false;
                }

                if (round.IsEnding)
                {
                    round.IsEnding = false;
                }

                //if user chow, then there's no way that user can win/pong/chow
                var actionsToBeRemoved = currentPlayer.RoundPlayerActions.Where(a => a.ActionType != ActionType.SelfKong).ToList();

                foreach (var action in actionsToBeRemoved)
                {
                    currentPlayer.RoundPlayerActions.Remove(action);
                }
                RoundHelper.CheckPossibleSelfKong(round, currentPlayer);

                try
                {
                    var success = await _context.SaveChangesAsync() > 0;

                    List <RoundDto> results = new List <RoundDto>();

                    foreach (var p in round.RoundPlayers)
                    {
                        results.Add(_mapper.Map <Round, RoundDto>(round, opt => opt.Items["MainRoundPlayer"] = p));
                    }

                    if (success)
                    {
                        return(results);
                    }
                }
                catch (DbUpdateConcurrencyException)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "tile was modified" });
                }

                throw new Exception("Problem chow ing tile");
            }
コード例 #2
0
            public async Task <IEnumerable <RoundDto> > Handle(Command request, CancellationToken cancellationToken)
            {
                //Note to consider when pong tile:
                //-player turn changed
                //-flag when user can pong
                //-when pong tile user need to throw a tile.
                //assign tile ownership to current user

                var updatedTiles = new List <RoundTile>();
                var round        = await _context.Rounds.FindAsync(request.RoundId);

                if (round == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, new { Round = "Could not find round" });
                }

                var boardActiveTiles = round.RoundTiles.Where(t => t.Status == TileStatus.BoardActive);

                if (boardActiveTiles == null)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "there are no tile to pong" });
                }

                var tileToPong = boardActiveTiles.First();

                updatedTiles.Add(tileToPong);

                //check if user currently have two tile to pong

                var matchingUserTiles = round.RoundTiles
                                        .Where(t => t.Owner == request.UserName &&
                                               t.Status == TileStatus.UserActive &&
                                               t.Tile.TileType == tileToPong.Tile.TileType &&
                                               t.Tile.TileValue == tileToPong.Tile.TileValue);

                if (matchingUserTiles == null || matchingUserTiles.Count() < 2)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "there are more than one tiles to pong" });
                }

                //if there is Userjustpicked status then pong is invalid
                var justPickedTile = round.RoundTiles.FirstOrDefault(t => t.Status == TileStatus.UserJustPicked);

                if (justPickedTile != null)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "someone already picked tile, no pong is allowed" });
                }

                foreach (var tile in matchingUserTiles.Take(2))
                {
                    updatedTiles.Add(tile);
                }

                updatedTiles.GoGraveyard(request.UserName, TileSetGroup.Pong, round.RoundTiles.GetLastGroupIndex(request.UserName));

                var currentPlayer = round.RoundPlayers.FirstOrDefault(u => u.GamePlayer.Player.UserName == request.UserName);

                if (currentPlayer == null)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "there are no user with this username in the round" });
                }

                currentPlayer.IsMyTurn  = true;
                currentPlayer.MustThrow = true;

                var actionsToBeRemoved = currentPlayer.RoundPlayerActions.Where(a => a.ActionType != ActionType.SelfKong).ToList();

                foreach (var action in actionsToBeRemoved)
                {
                    currentPlayer.RoundPlayerActions.Remove(action);
                }
                RoundHelper.CheckPossibleSelfKong(round, currentPlayer);

                if (round.IsEnding)
                {
                    round.IsEnding = false;
                }

                var otherPlayers = round.RoundPlayers.Where(u => u.IsMyTurn == true && u.GamePlayer.Player.UserName != request.UserName);

                foreach (var otherPlayerTurn in otherPlayers)
                {
                    otherPlayerTurn.IsMyTurn  = false;
                    otherPlayerTurn.MustThrow = false;
                }

                try
                {
                    var success = await _context.SaveChangesAsync() > 0;

                    List <RoundDto> results = new List <RoundDto>();

                    foreach (var p in round.RoundPlayers)
                    {
                        results.Add(_mapper.Map <Round, RoundDto>(round, opt => opt.Items["MainRoundPlayer"] = p));
                    }

                    if (success)
                    {
                        return(results);
                    }
                }
                catch (DbUpdateConcurrencyException)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Round = "tile was modified" });
                }

                throw new Exception("Problem pong ing tile");
            }