/* * [Command("🤥")] * public async Task LiarAnytimeOption() * { * var game = await GetGameAsync(GameState.Setup); * if (Context.Message.Id != game.StatusMessage) return; * * game.CanCallLiarAnytime = !game.CanCallLiarAnytime; * _db.SaveChanges(); * await UpdateStatus(game); * } * [Command("🏅")] * public async Task RankedOption() * { * var game = await GetGameAsync(GameState.Setup); * if (Context.Message.Id != game.StatusMessage) return; * * game.IsRanked = !game.IsRanked; * _db.SaveChanges(); * await UpdateStatus(game); * } * * [Command("🤖")] * public async Task RobotOption() * { * var game = await GetGameAsync(GameState.Setup); * if (Context.Message.Id != game.StatusMessage) return; * * game.TerminatorMode = !game.TerminatorMode; * _db.SaveChanges(); * await UpdateStatus(game); * } * * private async Task<Game> GetGameAsync(params GameState[] gameStates) * { * return await _perudoGameService.GetGameAsync(Context.Channel.Id, gameStates); * } * * [Command("🙃")] * public async Task ReverseOption() * { * var game = await GetGameAsync(GameState.Setup); * if (Context.Message.Id != game.StatusMessage) return; * * game.PenaltyGainDice = !game.PenaltyGainDice; * _db.SaveChanges(); * await UpdateStatus(game); * } * */ private async Task UpdateStatus(CommandContext context, Game game) { var gamemode = "Variable"; if (game.Penalty > game.NumberOfDice) { gamemode = "SuddenDeath"; } var players = _perudoGameService.GetGamePlayers(game).OrderByDescending(x => x.Player.EloRatings.FirstOrDefault(x => x.GameMode == gamemode)?.Rating); var options = _perudoGameService.GetOptions(game); var playersListString = string.Join("\n", players.Select(x => $"{x.PlayerId.GetChristmasEmoji(game.Id)} `{x.Player.EloRatings.FirstOrDefault(x => x.GameMode == gamemode)?.Rating}` {x.Player.Nickname}")); if (players.Count() == 0) { playersListString = "none"; } var builder = new EmbedBuilder() .WithTitle($"Game set up") .AddField($"Players ({players.Count()})", $"{playersListString}", inline: false) .AddField("Options", $"{string.Join("\n", options)}", inline: false); var embed = builder.Build(); await context.Message.ModifyAsync(x => x.Embed = embed); //var monkey = await Context.Channel.SendMessageAsync( // embed: embed) // .ConfigureAwait(false); //game.StatusMessage = monkey.Id; //_db.SaveChanges(); }
private GamePlayer GetCurrentPlayer(Game game) { var playerTurnId = game.PlayerTurnId; return(_db.GamePlayers .Include(gp => gp.Player) .Include(gp => gp.GamePlayerRounds) .AsQueryable() .Single(x => x.Id == playerTurnId)); }
private void AddUsers(Game game, SocketUserMessage message) { if (message.MentionedUsers.Count == 0) { //_perudoGameService.AddUserToGame(game, (SocketGuildUser)message.Author); } foreach (var userToAdd in message.MentionedUsers) { var socketGuildUser = Context.Guild.GetUser(userToAdd.Id); _perudoGameService.AddUserToGame(game, socketGuildUser); } }
private void SetTurnPlayerToRoundStartPlayer(Game game) { game.PlayerTurnId = game.RoundStartPlayerId; var thatUser = _perudoGameService.GetGamePlayers(game).Single(x => x.Id == game.PlayerTurnId); if (thatUser.NumberOfDice == 0) { SetNextPlayer(game, thatUser); } _db.SaveChanges(); }
private GamePlayer GetActivePlayer(Game game) { var playerTurnId = game.PlayerTurnId; if (game.DealCurrentGamePlayerId != 0) { playerTurnId = game.DealCurrentGamePlayerId; } return(_db.GamePlayers .Include(gp => gp.Player) .Include(gp => gp.GamePlayerRounds) .AsQueryable() .Single(x => x.Id == playerTurnId)); }
private int GetNumberOfDiceMatchingBid(Game game, int pips) { var players = _perudoGameService.GetGamePlayers(game).Where(x => x.NumberOfDice > 0).ToList(); if (game.FaceoffEnabled && players.Sum(x => x.NumberOfDice) == 2) { var allDice2 = players.SelectMany(x => x.Dice.Split(",").Select(x => int.Parse(x))); return(allDice2.Sum()); } var allDice = players.Where(x => x.Dice != "").SelectMany(x => x.Dice.Split(",").Select(x => int.Parse(x))); //if (game.NextRoundIsPalifico) //{ // return allDice.Count(x => x == pips); //} return(allDice.Count(x => x == pips || x == 1)); }
private async Task SendRoundSummary(Game game) { var players = _perudoGameService.GetGamePlayers(game).Where(x => x.Dice != "").Where(x => x.NumberOfDice > 0).ToList(); var playerDice = players.Select(x => $"{x.Player.Nickname}: {string.Join(" ", x.Dice.Split(",").Select(x => int.Parse(x).GetEmoji()))}".TrimEnd()); var allDice = players.SelectMany(x => x.Dice.Split(",").Select(x => int.Parse(x))); var allDiceGrouped = allDice .GroupBy(x => x) .OrderBy(x => x.Key); var countOfOnes = allDiceGrouped.SingleOrDefault(x => x.Key == 1)?.Count(); var listOfAllDiceCounts = allDiceGrouped.Select(x => $"`{x.Count()}` ˣ {x.Key.GetEmoji()}"); List <string> totals = new List <string>(); for (int i = game.LowestPip; i <= game.HighestPip; i++) { var countOfX = allDiceGrouped.SingleOrDefault(x => x.Key == i)?.Count(); var count1 = countOfOnes ?? 0; if (i == 1) { count1 = 0; } var countX = countOfX ?? 0; totals.Add($"`{count1 + countX }` ˣ {i.GetEmoji()}"); } var builder = new EmbedBuilder() .WithTitle($":leaves: Round {game.CurrentRound.RoundNumber} Summary :leaves:") .AddField("Players", $"{string.Join("\n", playerDice)}", inline: true) .AddField("Dice", $"{string.Join("\n", listOfAllDiceCounts)}", inline: true); //if (game.CurrentRound is StandardRound) builder.AddField("Totals", $"{string.Join("\n", totals)}", inline: true); var embed = builder.Build(); await Context.Channel.SendMessageAsync( embed : embed) .ConfigureAwait(false); }
private async Task SendRoundSummaryForBots(Game game) { return; // Andrey: Don't need bot summary for now, disabled to message spam var players = _perudoGameService.GetGamePlayers(game); if (!players.Any(x => x.Player.IsBot)) { return; } var playerDice = players.Where(x => x.NumberOfDice > 0).ToList() .Select(x => new { Username = x.Player.Nickname, x.Dice }); await SendMessageAsync($"Round summary for bots: ||{JsonConvert.SerializeObject(playerDice)}||"); }
public bool PlayerEligibleForSafeguard(Game game, int numberOfDice, int penalty) { return(false); if (game.PenaltyGainDice && game.Penalty == 0 && numberOfDice < 5 && penalty + numberOfDice > 5) { return(true); } if (game.PenaltyGainDice) { return(false); } // eligible if variable mode and player is about to lose all his dice without getting down to 1 if (game.Penalty == 0 && numberOfDice > 1 && penalty >= numberOfDice) { return(true); } return(false); }
private void SetNextPlayer(Game game, GamePlayer currentPlayer) { var playerIds = _db.GamePlayers .AsQueryable() .Where(x => x.GameId == game.Id) .Where(x => x.NumberOfDice > 0 || x.Player.Username == currentPlayer.Player.Username) // in case the current user is eliminated and won't show up .OrderBy(x => x.TurnOrder) .Select(x => x.Id) .ToList(); var playerIndex = playerIds.FindIndex(x => x == currentPlayer.Id); if (playerIndex >= playerIds.Count - 1) { game.PlayerTurnId = playerIds.ElementAt(0); } else { game.PlayerTurnId = playerIds.ElementAt(playerIndex + 1); } _db.SaveChanges(); }
private bool AreBotsInGame(Game game) { var gamePlayers = _perudoGameService.GetGamePlayers(game); return(gamePlayers.Any(x => x.Player.IsBot)); }
private void RemovePayupPlayer(Game game) { game.DealCurrentGamePlayerId = 0; _db.SaveChanges(); }
private void RemoveActiveDeals(Game game) { game.GamePlayers.All(x => x.HasActiveDeal = false); _db.SaveChanges(); }
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(); }
private async Task HandlePipBid(string[] bidText, Game game, GamePlayer biddingPlayer) { int quantity = 0; int pips = 0; try { quantity = int.Parse(bidText[0]); pips = int.Parse(bidText[1].Trim('s')); } catch { return; } if (quantity <= 0) { return; } if (pips < game.LowestPip || pips > game.HighestPip) { return; } var bid = new Bid { Pips = pips, Quantity = quantity, GamePlayer = biddingPlayer, Round = game.CurrentRound, ParentAction = game.CurrentRound.LatestAction, GamePlayerRound = biddingPlayer.CurrentGamePlayerRound, IsSuccess = true }; if (await VerifyBid(bid) == false) { return; } var currentPlayer2 = GetCurrentPlayer(game); if (game.CanBidAnytime && currentPlayer2.Player.Username != Context.User.Username) { var prevCurrentPlayer = GetCurrentPlayer(game); var currentPlayer = _perudoGameService.GetGamePlayers(game) .Where(x => x.NumberOfDice > 0) .SingleOrDefault(x => x.Player.Username == Context.User.Username); if (currentPlayer == null) { return; } game.PlayerTurnId = currentPlayer.Id; // reset turn order var players = _perudoGameService.GetGamePlayers(game).Where(x => x.NumberOfDice > 0).Where(x => x.Id != currentPlayer.Id).ToList(); var insertIndex = players.FindIndex(x => x.Id == prevCurrentPlayer.Id); players.Insert(insertIndex, currentPlayer); var order = 0; foreach (var player in players) { player.TurnOrder = order; order += 1; } _db.SaveChanges(); } bid.SetDuration(); _db.Bids.Add(bid); _db.SaveChanges(); var activePlayer = GetActivePlayer(game); if (activePlayer.HasActiveDeal && Context.User.Id != activePlayer.Player.UserId) { biddingPlayer.PendingUserDealIds = $"{biddingPlayer.PendingUserDealIds},{activePlayer.Id}"; await SendMessageAsync($":money_mouth: {biddingPlayer.Player.Nickname} has accepted the deal! {biddingPlayer.Player.Nickname}, on your turn use `!payup @{activePlayer.Player.Nickname}` to force them to take your turn for you."); } RemoveActiveDeals(game); RemovePayupPlayer(game); SetNextPlayer(game, currentPlayer2); var nextPlayer = GetCurrentPlayer(game); DeleteCommandFromDiscord(); var bidderNickname = biddingPlayer.Player.Nickname; var nextUser = GetUser(nextPlayer.Player.Username); var nextPlayerMention = nextUser.Mention; var snowflakeRound = ""; if (game.CurrentRound is PalificoRound) { snowflakeRound = ":four_leaf_clover: "; } var dealer = ""; if (currentPlayer2.Id != biddingPlayer.Id) { dealer = $" (bidding for {currentPlayer2.Player.Nickname})"; } var userMessage = $"{snowflakeRound}{ bidderNickname }{dealer} bids `{ quantity}` ˣ { pips.GetEmoji()}. { nextPlayerMention } is up."; IUserMessage sentMessage; sentMessage = await SendMessageAsync(userMessage); if (AreBotsInGame(game)) { var botMessage = new { nextPlayer = nextUser.Id.ToString(), diceCount = _perudoGameService.GetGamePlayers(game).Sum(x => x.NumberOfDice), round = game.Rounds.Count, action = BidToActionIndex(bid), }; await SendMessageAsync($"||`@bots update {JsonConvert.SerializeObject(botMessage)}`||"); } bid.MessageId = sentMessage.Id; activePlayer.HasActiveDeal = false; _db.SaveChanges(); await CheckIfNextPlayerHasAutoLiarSetAsync(nextPlayer); }
private async Task DecrementDieFromPlayerAndSetThierTurnAsync(Game game, GamePlayer player, int penalty) { if (game.PenaltyGainDice) { player.NumberOfDice += penalty; if (player.NumberOfDice > game.NumberOfDice) { player.NumberOfDice = 0; } } else { player.NumberOfDice -= penalty; } player.CurrentGamePlayerRound.Penalty = penalty; if (player.NumberOfDice < 0) { player.NumberOfDice = 0; } if (player.NumberOfDice == 1 && game.Palifico) { game.NextRoundIsPalifico = true; } else { game.NextRoundIsPalifico = false; } if (player.NumberOfDice <= 0) { player.CurrentGamePlayerRound.IsEliminated = true; await SendMessageAsync($":wood::axe: {player.Player.Nickname} was cut down :wood::axe:"); var deathrattle = _db.Rattles.SingleOrDefault(x => x.Username == player.Player.Username); if (deathrattle != null) { await SendMessageAsync(deathrattle.Deathrattle); } if (game.CanCallExactToJoinAgain) { if (_perudoGameService.GetGamePlayers(game).Where(x => x.NumberOfDice > 0).Count() > 2) { if (player.GhostAttemptsLeft != -1) { player.GhostAttemptsLeft = 3; _db.SaveChanges(); await SendMessageAsync($":hourglass::hourglass: {player.Player.Nickname} you have `3` attempts at an `!exact` call to win your way back into the game (3+ players)."); } } } SetNextPlayer(game, player); } else { game.PlayerTurnId = player.Id; _db.SaveChanges(); } }
private async Task HandleFaceoffBid(string[] bidText, Game game, GamePlayer biddingPlayer) { int quantity = 0; try { quantity = int.Parse(bidText[0]); } catch { return; } if (quantity < game.LowestPip * 2 || quantity > game.HighestPip * 2) { return; } var bid = new Bid { Pips = 0, Quantity = quantity, Round = game.CurrentRound, GamePlayer = biddingPlayer, ParentAction = game.CurrentRound.LatestAction, GamePlayerRound = biddingPlayer.CurrentGamePlayerRound }; if (await VerifyBid(bid) == false) { return; } /// MONKEY... working here. /// TODO: Add Exact bid too /// TODO: Add Liar bid too /// _db.Actions.Add(bid); _db.SaveChanges(); var currentPlayer = GetCurrentPlayer(game); var activePlayer = GetActivePlayer(game); if (activePlayer.HasActiveDeal && Context.User.Id != activePlayer.Player.UserId) { biddingPlayer.PendingUserDealIds = $"{biddingPlayer.PendingUserDealIds},{activePlayer.Id}"; await SendMessageAsync($":money_mouth: {biddingPlayer.Player.Nickname} has accepted the deal! {biddingPlayer.Player.Nickname}, on your turn use `!payup @{activePlayer.Player.Nickname}` to force them to take your turn for you."); } RemoveActiveDeals(game); RemovePayupPlayer(game); SetNextPlayer(game, currentPlayer); var nextPlayer = GetCurrentPlayer(game); DeleteCommandFromDiscord(); var bidderNickname = biddingPlayer.Player.Nickname; var nextPlayerMention = GetUser(nextPlayer.Player.Username).Mention; var dealer = ""; if (currentPlayer.Id != biddingPlayer.Id) { dealer = $" (bidding for {currentPlayer.Player.Nickname})"; } var userMessage = $"{ bidderNickname }{dealer} bids `{ quantity}` ˣ :record_button:. { nextPlayerMention } is up."; await SendMessageAsync(userMessage); await CheckIfNextPlayerHasAutoLiarSetAsync(nextPlayer); }
private Bid GetMostRecentBid(Game game) { return(game.CurrentRound .Actions.OfType <Bid>() .LastOrDefault()); }