Exemplo n.º 1
0
        public RoundStatus StartNewRound()
        {
            if (_game.GamePlayerTurnId == 0)
            {
                var firstPlayer = _game.GamePlayers.OrderBy(x => x.TurnOrder).First();
                _game.GamePlayerTurnId = firstPlayer.Id;
            }

            var activeGamePlayers = _game.GamePlayers.Where(x => x.NumberOfDice > 0);

            if (activeGamePlayers.Count() == 1)
            {
                // end the game they won!
                var winner = activeGamePlayers.Single();
                winner.Rank          = 1;
                _game.WinnerPlayerId = winner.Player.Id;
                _game.State          = (int)GameState.Finished;

                _db.SaveChanges();
                OnEndOfRound();

                return(new RoundStatus
                {
                    IsActive = false,
                    Winner = activeGamePlayers.Single().ToPlayerObject(),
                    Players = _game.GamePlayers.Select(x => new PlayerData
                    {
                        //IsBot = x.Player.IsBot,
                        Name = x.Player.Name,
                        Rank = x.Rank,
                        NumberOfDice = x.NumberOfDice,
                        PlayerId = x.Player.Id,
                        PlayerMetadata = x.Player.Metadata.ToDictionary(x => x.Key, x => x.Value),
                        GamePlayerMetadata = x.Metadata.ToDictionary(x => x.Key, x => x.Value)
                    }).ToList()
                });
            }

            // create new round
            var newRound = new StandardRound
            {
                GameId           = _game.Id,
                RoundNumber      = _game.Rounds.Count + 1,
                StartingPlayerId = _game.GamePlayerTurnId
            };

            _db.Rounds.Add(newRound);


            // and set dice
            var r           = new Random();
            var gamePlayers = _game.GamePlayers.ToList();

            foreach (var player in gamePlayers)
            {
                var dice = new List <int>();
                for (int i = 0; i < player.NumberOfDice; i++)
                {
                    dice.Add(r.Next(1, 6 + 1));
                }
                dice.Sort();
                var gamePlayerRound = new GamePlayerRound
                {
                    Round      = newRound,
                    Dice       = string.Join(",", dice),
                    GamePlayer = player
                };

                _db.GamePlayerRounds.Add(gamePlayerRound);
            }

            _db.SaveChanges();

            //TODO: DO I have to do this every time??
            LoadActiveGame();

            return(new RoundStatus
            {
                IsActive = true,
                Players = GetAllPlayers(),
                RoundNumber = _game.CurrentRoundNumber
            });
        }
Exemplo n.º 2
0
        private async Task RollDiceStartNewRoundAsync(Game game)
        {
            // mark the end of the current round
            if (game.CurrentRound != null)
            {
                game.CurrentRound.EndRound();
            }
            _db.SaveChanges();
            // IF THERE IS ONLY ONE PLAYER LEFT, ANNOUNCE THAT THEY WIN
            var gamePlayers = _perudoGameService.GetGamePlayers(game);

            var  activeGamePlayers = gamePlayers.Where(x => x.NumberOfDice > 0);
            bool onlyOnePlayerLeft = activeGamePlayers.Count() == 1;

            if (onlyOnePlayerLeft)
            {
                await SendMessageAsync($":trophy: {GetUser(activeGamePlayers.Single().Player.Username).Mention} is the winner with `{activeGamePlayers.Single().NumberOfDice}` dice remaining! :trophy:");

                var rattles = _db.Rattles.SingleOrDefault(x => x.Username == activeGamePlayers.Single().Player.Username);
                if (rattles != null)
                {
                    await SendMessageAsync(rattles.Winrattle);
                }
                game.EndGame();

                // todo: I'd move this into game.EndGame() but honestly I'm scared it will break
                game.Winner = activeGamePlayers.Single().Player.Username;
                _db.SaveChanges();

                await _perudoGameService.UpdateGamePlayerRanksAsync(game.Id);

                await new EloRatingService(_db).GenerateEloRatingsForGameAsync(game.Id);
                await GetGameSummaryAsync(game.Id);

                return;
            }

            var r = new Random();

            var botKeys = _db.BotKeys.AsQueryable()
                          .ToList();

            if (game.RandomizeBetweenRounds)
            {
                ShufflePlayers(game);
            }

            await DisplayCurrentStandingsForBots(game);
            await DisplayCurrentStandings(game);

            _db.SaveChanges();
            game.RoundStartPlayerId = GetCurrentPlayer(game).Id;
            _db.SaveChanges();

            Round round;

            if (activeGamePlayers.Sum(x => x.NumberOfDice) == 2 && game.FaceoffEnabled && !AreBotsInGame(game))
            {
                round = new FaceoffRound()
                {
                    GameId           = game.Id,
                    RoundNumber      = (game.CurrentRound?.RoundNumber ?? 0) + 1,
                    StartingPlayerId = GetCurrentPlayer(game).Id
                };

                await SendTempMessageAsync("!gif lumberjack");
                await SendMessageAsync($":carpentry_saw: Faceoff Round :carpentry_saw: {GetUser(GetCurrentPlayer(game).Player.Username).Mention} goes first. Bid on total pips only (eg. `!bid 4`)");
            }
            else if (game.NextRoundIsPalifico && !AreBotsInGame(game))
            {
                round = new PalificoRound()
                {
                    GameId           = game.Id,
                    RoundNumber      = (game.CurrentRound?.RoundNumber ?? 0) + 1,
                    StartingPlayerId = GetCurrentPlayer(game).Id
                };

                await SendMessageAsync($":four_leaf_clover: Palifico Round :four_leaf_clover: {GetUser(GetCurrentPlayer(game).Player.Username).Mention} goes first.\n" +
                                       $"`wilds count now` `only players at 1 die can change the pips`");
            }
            else
            {
                round = new StandardRound()
                {
                    GameId           = game.Id,
                    RoundNumber      = (game.CurrentRound?.RoundNumber ?? 0) + 1,
                    StartingPlayerId = GetCurrentPlayer(game).Id
                };
                await SendMessageAsync($"A new round has begun. {GetUser(GetCurrentPlayer(game).Player.Username).Mention} goes first.");
            }

            _db.Rounds.Add(round);

            foreach (var gamePlayer in activeGamePlayers)
            {
                var deals = new List <int>();
                if (!string.IsNullOrWhiteSpace(gamePlayer.UserDealIds))
                {
                    var currentDeals = gamePlayer.UserDealIds
                                       .Split(',', StringSplitOptions.RemoveEmptyEntries)
                                       .ToList()
                                       .Select(x => int.Parse(x));

                    deals.AddRange(currentDeals);
                }

                if (!string.IsNullOrWhiteSpace(gamePlayer.PendingUserDealIds))
                {
                    var pendingDeals = gamePlayer.PendingUserDealIds
                                       .Split(',', StringSplitOptions.RemoveEmptyEntries)
                                       .ToList()
                                       .Select(x => int.Parse(x));

                    deals.AddRange(pendingDeals);
                }
                gamePlayer.UserDealIds        = string.Join(',', deals);
                gamePlayer.PendingUserDealIds = "";

                var dice         = new List <int>();
                var numberOfDice = gamePlayer.NumberOfDice;

                //if (game.CurrentRoundNumber == 1 && game.PenaltyGainDice) numberOfDice = 1;

                for (int i = 0; i < numberOfDice; i++)
                {
                    dice.Add(r.Next(game.LowestPip, game.HighestPip + 1));
                }

                dice.Sort();

                var gamePlayerRound = new GamePlayerRound()
                {
                    GamePlayer   = gamePlayer,
                    Round        = round,
                    Dice         = string.Join(",", dice),
                    IsGhost      = gamePlayer.GhostAttemptsLeft == -1,
                    NumberOfDice = gamePlayer.NumberOfDice,
                    TurnOrder    = -1 // Figure out out to assign turnorder based off starting
                };
                gamePlayer.Dice = string.Join(",", dice);
                _db.Add(gamePlayerRound);

                var user    = Context.Guild.Users.Single(x => x.Username == gamePlayer.Player.Username);
                var message = $"Your dice: {string.Join(" ", dice.Select(x => x.GetEmoji()))}";

                var botKey = botKeys.FirstOrDefault(x => x.Username == gamePlayer.Player.Username);

                if (user.IsBot)
                {
                    var botKeyString = (botKey != null) ? botKey.BotAesKey : gamePlayer.Player.Username;
                    await SendEncryptedDiceAsync(gamePlayer, user, botKeyString);
                }
                else
                {
                    var requestOptions = new RequestOptions()
                    {
                        RetryMode = RetryMode.RetryRatelimit
                    };
                    await user.SendMessageAsync(message, options : requestOptions);
                }
            }

            if (AreBotsInGame(game) && round is StandardRound)
            {
                var botMessage = new
                {
                    nextPlayer = GetUser(GetCurrentPlayer(game).Player.Username).Id.ToString(),
                    diceCount  = _perudoGameService.GetGamePlayers(game).Sum(x => x.NumberOfDice),
                    round      = round.RoundNumber,
                };

                await SendMessageAsync($"||`@bots update {JsonConvert.SerializeObject(botMessage)}`||");
            }

            await _db.SaveChangesAsync();
        }