Example #1
0
            private bool AssignPlayerActions(Round round, RoundPlayer throwerPlayer)
            {
                //TODO: Support multiple winner
                bool foundActionForUser = false;
                var  roundTiles         = round.RoundTiles;

                //there will be action except for the player that throw the tile
                var players = round.RoundPlayers.Where(rp => rp.GamePlayer.Player.UserName != throwerPlayer.GamePlayer.Player.UserName);

                var boardActiveTile = roundTiles.FirstOrDefault(rt => rt.Status == TileStatus.BoardActive);

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

                var nextPlayer = RoundHelper.GetNextPlayer(round.RoundPlayers, throwerPlayer.Wind);

                //there could be more than one possible action given user's turn  and the tile's thrown
                foreach (var player in players)
                {
                    var userTiles = roundTiles.Where(rt => rt.Owner == player.GamePlayer.Player.UserName);
                    List <RoundPlayerAction> rpas = new List <RoundPlayerAction>();

                    if (RoundHelper.DetermineIfUserCanWin(round, player, _pointCalculator))
                    {
                        rpas.Add(new RoundPlayerAction {
                            ActionType = ActionType.Win, ActionStatus = ActionStatus.Inactive
                        });
                    }

                    if (DetermineIfUserCanKongFromBoard(userTiles, boardActiveTile))
                    {
                        rpas.Add(new RoundPlayerAction {
                            ActionType = ActionType.Kong, ActionStatus = ActionStatus.Inactive
                        });
                    }

                    if (DetermineIfUserCanPong(userTiles, boardActiveTile))
                    {
                        rpas.Add(new RoundPlayerAction {
                            ActionType = ActionType.Pong, ActionStatus = ActionStatus.Inactive
                        });
                    }

                    if (player.GamePlayer.Player.UserName == nextPlayer.GamePlayer.Player.UserName)
                    {
                        var nextPlayerTiles = round.RoundTiles.Where(rt => rt.Owner == nextPlayer.GamePlayer.Player.UserName);
                        if (DetermineIfUserCanChow(nextPlayerTiles, boardActiveTile))
                        {
                            rpas.Add(new RoundPlayerAction {
                                ActionType = ActionType.Chow, ActionStatus = ActionStatus.Inactive
                            });
                        }
                    }

                    if (rpas.Count() > 0)
                    {
                        foundActionForUser = true;
                        foreach (var pa in rpas)
                        {
                            player.RoundPlayerActions.Add(pa);
                        }
                    }
                }

                return(foundActionForUser);
            }
Example #2
0
            public async Task <IEnumerable <RoundDto> > Handle(Command request, CancellationToken cancellationToken)
            {
                //Note to consider when picking tile:
                //-tile is flower
                //-no more tile to pick
                //-only 1 more tile to pick because player have an option not to take the last tile.
                var round = await _context.Rounds.FindAsync(request.RoundId);

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

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

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

                currentPlayer.MustThrow = true;

                //TODO only allow pick tile when it's player's turn

                var newTiles = RoundTileHelper.PickTile(round, request.UserName);

                if (newTiles == null)
                {
                    round.IsEnding = true;
                }

                //pick action now only available on last tile
                //check if user can win if they pick on last tile
                var remainingTiles = round.RoundTiles.FirstOrDefault(t => string.IsNullOrEmpty(t.Owner));

                if (remainingTiles == null)
                {
                    currentPlayer.RoundPlayerActions.Clear();
                    if (RoundHelper.DetermineIfUserCanWin(round, currentPlayer, _pointCalculator))
                    {
                        currentPlayer.RoundPlayerActions.Add(new RoundPlayerAction {
                            ActionType = ActionType.Win
                        });
                    }
                }

                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 = "player status was modified" });
                }

                throw new Exception("Problem picking tile");
            }