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 }); }
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(); }