示例#1
0
        public async Task LeaveGame(string gameCode)
        {
            await Groups.RemoveFromGroupAsync(Context.ConnectionId, gameCode);

            Game game   = GameStore.GetGame(gameCode);
            var  player = game.Players.FirstOrDefault(e => e.ConnectionId == Context.ConnectionId);

            if (player == null || game.Status == GameStatus.Completed)
            {
                return;
            }
            if (game.Status == GameStatus.NotStarted)
            {
                game.Players.Remove(player);
                if (game.Players.Count == 0)
                {
                    GameStore.RemoveGame(gameCode);
                    await Clients.Group(GameList).GameListUpdated(GameStore.GetGames());
                }

                return;
            }

            player.ChallengesRemaining = 0;
            if (game.Players.Count == 1)
            {
                game.Status = GameStatus.Completed;
            }
        }
示例#2
0
        public IActionResult StartGame([FromRoute] string code, string adminCode)
        {
            var game = GameStore.GetGame(code);

            if (game == null)
            {
                return(NotFound());
            }
            if (game.Status != GameStatus.NotStarted)
            {
                return(StatusCode(403, "Can only start unstarted games"));
            }
            if (game.Players.First().ConnectionId != adminCode)
            {
                return(Unauthorized());
            }

            game.Status = GameStatus.NormalTurn;

            TimerStore.SetupAnswerTimeout(game);

            // TODO _gameClient.GameUpdated(game);

            return(Ok());
        }
示例#3
0
        public IActionResult SendAnswer([FromRoute] string code, string playerCode, string answer, string rule)
        {
            var game = GameStore.GetGame(code);

            if (game == null)
            {
                return(NotFound());
            }
            if (game.CurrentPlayer.ConnectionId != playerCode)
            {
                return(Unauthorized());
            }
            if (game.Status == GameStatus.NameAnother && rule != null)
            {
                return(BadRequest("Adding rule not allowed when naming another"));
            }

            game.Turns.Add(new Turn(game.Turns.Count, game.CurrentPlayer, game.Status, answer, rule));
            game.CurrentPlayer = game.FindNextPlayer();

            TimerStore.SetupAnswerTimeout(game);

            // TODO _gameClient.GameUpdated(game);

            return(Ok());
        }
示例#4
0
        public async Task JoinGame(Guid gameId)
        {
            await Groups.AddToGroupAsync(Context.ConnectionId, gameId.ToString());

            Game g = GameStore.GetGame(gameId);

            await Clients.Group(gameId.ToString()).GameUpdated(g);
        }
示例#5
0
        public async Task Assassinate(Guid gameId, Guid assassinationTargetId)
        {
            Game g = GameStore.GetGame(gameId);

            g.Assassinate(assassinationTargetId);

            await Clients.Group(gameId.ToString()).GameUpdated(g);
        }
示例#6
0
        public async Task ChangeSelectedTeam(Guid gameId, IEnumerable <Guid> playerIds)
        {
            Game g = GameStore.GetGame(gameId);

            g.SetCurrentTeam(playerIds);

            await Clients.Group(gameId.ToString()).GameUpdated(g);
        }
示例#7
0
        public async Task SubmitSelectedTeam(Guid gameId)
        {
            Game g = GameStore.GetGame(gameId);

            g.SubmitCurrentTeam();

            await Clients.Group(gameId.ToString()).GameUpdated(g);
        }
示例#8
0
        public async Task SkipRevealTeamVotes(Guid gameId)
        {
            Game g = GameStore.GetGame(gameId);

            g.SkipRevealTeamVote();

            await Clients.Group(gameId.ToString()).GameUpdated(g);
        }
示例#9
0
        public async Task SubmitTeamVote(Guid gameId, bool votedSuccess)
        {
            Game g = GameStore.GetGame(gameId);

            g.AddTeamVote(votedSuccess);

            await Clients.Group(gameId.ToString()).GameUpdated(g);
        }
示例#10
0
        public async Task SubmitTeam(GameAndPlayerIdDto model)
        {
            Game g = GameStore.GetGame(model.GameId);

            g.CurrentRound.Status = RoundStatus.VotingForTeam;
            GameStore.AddOrUpdateGame(g);
            await _gameHub.Clients.Group(model.GameId.ToString()).SendAsync("UpdateAll");
        }
示例#11
0
        public async Task RemovePlayer(Guid GameId, Guid PlayerId)
        {
            Game g = GameStore.GetGame(GameId);

            g.Players.RemoveAll(p => p.Id == PlayerId);
            GameStore.AddOrUpdateGame(g);
            await _gameHub.Clients.Group(GameId.ToString()).SendAsync("UpdateAll");
        }
示例#12
0
        public async Task UpdateAvatar(Guid gameId, Guid playerId, Avatar avatar)
        {
            Game g = GameStore.GetGame(gameId);

            g.GetPlayer(playerId).Avatar = avatar;

            await Clients.Group(gameId.ToString()).GameUpdated(g);
        }
示例#13
0
        public async Task SkipExpeditionVotes(Guid gameId)
        {
            Game g = GameStore.GetGame(gameId);

            g.NextRound();

            await Clients.Group(gameId.ToString()).GameUpdated(g);
        }
示例#14
0
        public IActionResult GetGame([FromRoute] string code)
        {
            var game = GameStore.GetGame(code);

            if (game == null)
            {
                return(NotFound());
            }

            // TODO Subscribe caller to game updates

            return(Ok(game));
        }
示例#15
0
        public async Task Assassinate(GameAndPlayerIdDto model)
        {
            Game   g = GameStore.GetGame(model.GameId);
            Player p = g.GetPlayer(model.PlayerId);

            if (p.RoleId == GameRole.Merlin)
            {
                g.PointsEvil += 100;
            }
            g.Status = GameStatus.Ended;
            GameStore.AddOrUpdateGame(g);
            await _gameHub.Clients.Group(g.Id.ToString()).SendAsync("UpdateAll");
        }
示例#16
0
        public async Task SetRoundStatus(SetRoundStatusDto model)
        {
            Game g = GameStore.GetGame(model.GameId);

            g.CurrentRound.Status = model.Status;
            if (model.Status == RoundStatus.SelectingTeam)
            {
                g.CurrentRound.VotesForTeam     = 0;
                g.CurrentRound.VotesAgainstTeam = 0;
            }
            GameStore.AddOrUpdateGame(g);
            await _gameHub.Clients.Group(model.GameId.ToString()).SendAsync("UpdateAll");
        }
示例#17
0
        public async Task JoinGame(string playerName, string code)
        {
            Game game = GameStore.GetGame(code);

            Player player = new Player(Context.ConnectionId, playerName);

            game.Players.Add(player);

            await Groups.AddToGroupAsync(Context.ConnectionId, game.Code);

            await Clients.Group(game.Code).GameUpdated(game);

            await Clients.Group("gameList").GameListUpdated(GameStore.GetGames());
        }
示例#18
0
        public async Task SetTeam(SetTeamDto model)
        {
            Game          g    = GameStore.GetGame(model.GameId);
            List <Player> team = new List <Player>();

            g.CurrentRound.CurrentTeam.Clear();
            foreach (Guid playerId in model.CurrentTeam)
            {
                team.Add(g.GetPlayer(playerId));
            }
            g.CurrentRound.CurrentTeam = team;
            GameStore.AddOrUpdateGame(g);
            await _gameHub.Clients.Group(model.GameId.ToString()).SendAsync("UpdateHost");
        }
示例#19
0
        public async Task <Round> ExpeditonVote(VoteDto model)
        {
            Game g = GameStore.GetGame(model.GameId);

            g.CurrentRound.ExpeditionVote(model.Vote);
            if (g.CurrentRound.TotalMissionVotes >= g.CurrentRound.CurrentTeam.Count)
            {
                await ExpeditionResults(g);
            }
            else
            {
                GameStore.AddOrUpdateGame(g);
                await _gameHub.Clients.Group(model.GameId.ToString()).SendAsync("UpdateHost");
            }
            return(g.CurrentRound);
        }
示例#20
0
        public async Task <Round> VoteForTeam(VoteDto model)
        {
            Game g = GameStore.GetGame(model.GameId);

            g.CurrentRound.TeamVote(model.Vote);
            if (g.CurrentRound.TotalTeamVotes >= g.Players.Count)
            {
                await VoteForTeamResults(g);
            }
            else
            {
                GameStore.AddOrUpdateGame(g);
                await _gameHub.Clients.Group(model.GameId.ToString()).SendAsync("UpdateHost");
            }
            return(g.CurrentRound);
        }
示例#21
0
        public async Task <string> SubmitExpeditionVote(Guid gameId, Guid playerId, bool votedSuccess)
        {
            Game g = GameStore.GetGame(gameId);

            Player p = g.GetPlayer(playerId);

            if (!votedSuccess && (int)p.RoleId <= 3)
            {
                return("You cannot vote fail when you are good");
            }

            g.AddExpeditionVote(votedSuccess);

            await Clients.Group(gameId.ToString()).GameUpdated(g);

            return("");
        }
示例#22
0
        public async Task NextRound(GameAndPlayerIdDto model)
        {
            Game g = GameStore.GetGame(model.GameId);

            if (g.PointsEvil >= 3 || g.PointsInnocent >= 3)
            {
                await GameEnd(model.GameId);
            }
            else
            {
                g.CurrentRound.TeamString = String.Join(' ', g.CurrentRound.CurrentTeam.Select(p => p.Name));
                g.PreviousRounds.Add(g.CurrentRound);
                g.CurrentRound = new Round(g.PreviousRounds.Count, g.Players.Count);
            }
            GameStore.AddOrUpdateGame(g);
            await _gameHub.Clients.Group(g.Id.ToString()).SendAsync("UpdateAll");
        }
示例#23
0
        public async Task <GameDto> StartGame(StartGameDto model)
        {
            Game g = GameStore.GetGame(model.Id);

            for (int i = 0; i < g.Players.Count; i++)
            {
                g.Players[i].Order = i;
            }
            g.CurrentRound  = new Round(1, g.Players.Count);
            g.CurrentPlayer = g.Players[0];
            g.Status        = GameStatus.Playing;
            await AssertRoles(model.Id, model.Roles);

            GameStore.AddOrUpdateGame(g);
            await _gameHub.Clients.Group(g.Id.ToString()).SendAsync("UpdateAll");

            return(ObjectMapper.Map <GameDto>(g));
        }
示例#24
0
        public async Task <string> StartGame(Guid gameId, List <int> roles)
        {
            Game g = GameStore.GetGame(gameId);

            try
            {
                g.ValidateStart(roles);
            } catch (Exception e)
            {
                return(e.Message);
            }

            g.Start(roles);

            await Clients.Group(gameId.ToString()).GameUpdated(g);

            return("");
        }
示例#25
0
        public async Task <GameDto> AssertRoles(Guid id, List <string> rollene)
        {
            Game g     = GameStore.GetGame(id);
            var  roles = rollene.Select(int.Parse).ToList();

            roles.ForEach(role =>
            {
                var random = new Random();
                // Random player that is not yet assigned a role
                var notYetChosenPlayers = g.Players.FindAll(p => p.RoleId == GameRole.NotYetChosen);
                var randomPlayer        = notYetChosenPlayers[random.Next(notYetChosenPlayers.Count)];
                randomPlayer.RoleId     = (GameRole)role;
                if (role >= 4)
                {
                    randomPlayer.IsEvil = true;
                }
                g.Players[g.Players.FindIndex(p => p.Id == randomPlayer.Id)] = randomPlayer;
            });
            var numberOfGood    = roles.FindAll(r => r <= 3).Count;
            var numberOfEvil    = roles.Count - numberOfGood;
            var numberOfMinions = GetHowManyEvils(g.Players.Count) - numberOfEvil;

            for (int i = 0; i < numberOfMinions; i++)
            {
                var random = new Random();
                // Random player that is not yet assigned a role
                var notYetChosenPlayers = g.Players.FindAll(p => p.RoleId == GameRole.NotYetChosen);
                var randomPlayer        = notYetChosenPlayers[random.Next(notYetChosenPlayers.Count)];
                randomPlayer.RoleId = GameRole.Minion;
                randomPlayer.IsEvil = true;
                g.Players[g.Players.FindIndex(p => p.Id == randomPlayer.Id)] = randomPlayer;
            }
            g.Players.ForEach(p =>
            {
                if (p.RoleId == GameRole.NotYetChosen)
                {
                    p.RoleId = GameRole.Servant;
                }
                p.RoleName = p.RoleId.ToString();
                p.RoleInfo = ReturnInfo(g, p.RoleId);
            });
            GameStore.AddOrUpdateGame(g);
            return(ObjectMapper.Map <GameDto>(g));
        }
示例#26
0
        public IActionResult Challenge([FromRoute] string code, string playerCode, int turnId)
        {
            var game = GameStore.GetGame(code);

            if (game == null)
            {
                return(NotFound());
            }
            if (game.Turns.Last().TurnId != turnId)
            {
                return(StatusCode(403, "Cannot challenge answer other than latest"));
            }
            if (game.Turns.Last().TurnType == GameStatus.Challenge)
            {
                return(StatusCode(403, "Challenge can only be posited once per answer"));
            }
            if (game.Status == GameStatus.NameAnother)
            {
                return(StatusCode(403, "Name another answer cannot be challenged"));
            }

            Player player           = game.FindActivePlayer(playerCode);
            Player challengedPlayer = game.FindPreviousPlayer();

            if (player == null || player == challengedPlayer)
            {
                return(Unauthorized());
            }

            game.Status            = GameStatus.Challenge;
            game.CurrentPlayer     = challengedPlayer;
            game.ChallengingPlayer = player;

            TimerStore.SetupChallengeTimeout(game);

            // TODO _gameClient.GameUpdated(game);

            return(Ok());
        }
示例#27
0
        public IActionResult Vote([FromRoute] string code, string playerCode, bool vote)
        {
            var game = GameStore.GetGame(code);

            if (game == null)
            {
                return(NotFound());
            }
            if (game.Status != GameStatus.Challenge)
            {
                return(StatusCode(403, "Can only vote if challenge is ongoing"));
            }

            Player player = game.FindActivePlayer(playerCode);

            if (player == null || player == game.CurrentPlayer)
            {
                return(Unauthorized());
            }
            if (game.Votes.Exists(v => v.Player == player))
            {
                return(Conflict("Cannot vote twice on one challenge"));
            }

            game.Votes.Add(new Vote(player, vote));

            // Check if everyone but challenged player has voted
            if (game.Votes.Count == game.CountActivePlayers() - 1)
            {
                game.ResolveChallenge();

                TimerStore.SetupAnswerTimeout(game);
            }

            // TODO _gameClient.GameUpdated(game);

            return(Ok());
        }
示例#28
0
        public async Task GameEnd(Guid id)
        {
            Game g = GameStore.GetGame(id);

            g.Status = GameStatus.Ended;
            if (g.PointsEvil < 3)
            {
                bool AssassinGame = false;
                g.Players.ForEach(x =>
                {
                    if (x.RoleId == GameRole.Assassin)
                    {
                        AssassinGame = true;
                    }
                });
                if (AssassinGame)
                {
                    g.Status = GameStatus.AssassinTurn;
                }
            }
            GameStore.AddOrUpdateGame(g);
            await _gameHub.Clients.Group(g.Id.ToString()).SendAsync("UpdateAll");
        }
示例#29
0
        public IActionResult JoinGame([FromRoute] string code, string playerName)
        {
            var game = GameStore.GetGame(code);

            if (game == null)
            {
                return(NotFound());
            }
            if (game.Status != GameStatus.NotStarted)
            {
                return(StatusCode(403, "Can only join game before start"));
            }

            var player = new Player("", playerName);

            game.Players.Add(player);

            // TODO Subscribe caller to game update

            // TODO _gameClient.GameUpdated(game);

            return(Ok(player.ConnectionId));
        }
示例#30
0
        public IActionResult RequestNameAnother([FromRoute] string code, string playerCode, int turnId)
        {
            var game = GameStore.GetGame(code);

            if (game == null)
            {
                return(NotFound());
            }
            if (game.Turns.Last().TurnId != turnId)
            {
                return(StatusCode(403, "Cannot request name another for rule other than latest"));
            }
            if (game.Turns.Last().TurnType == GameStatus.NameAnother)
            {
                return(StatusCode(403, "Name another can only be requested once per answer"));
            }
            if (game.Status == GameStatus.NameAnother)
            {
                return(Conflict("Name another has already been requested"));
            }

            Player player = game.FindActivePlayer(playerCode);

            if (player == null || player == game.CurrentPlayer)
            {
                return(Unauthorized());
            }

            game.Status        = GameStatus.NameAnother;
            game.CurrentPlayer = game.FindPreviousPlayer();

            TimerStore.SetupAnswerTimeout(game);

            // TODO _gameClient.GameUpdated(game);

            return(Ok());
        }