/*
         * [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();
        }
Esempio n. 2
0
        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);
     }
 }
Esempio n. 4
0
        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();
        }
Esempio n. 5
0
        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));
        }
Esempio n. 6
0
        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));
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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)}||");
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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();
        }
Esempio n. 11
0
        private bool AreBotsInGame(Game game)
        {
            var gamePlayers = _perudoGameService.GetGamePlayers(game);

            return(gamePlayers.Any(x => x.Player.IsBot));
        }
Esempio n. 12
0
 private void RemovePayupPlayer(Game game)
 {
     game.DealCurrentGamePlayerId = 0;
     _db.SaveChanges();
 }
Esempio n. 13
0
 private void RemoveActiveDeals(Game game)
 {
     game.GamePlayers.All(x => x.HasActiveDeal = false);
     _db.SaveChanges();
 }
Esempio n. 14
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();
        }
Esempio n. 15
0
        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);
        }
Esempio n. 16
0
        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();
            }
        }
Esempio n. 17
0
        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);
        }
Esempio n. 18
0
 private Bid GetMostRecentBid(Game game)
 {
     return(game.CurrentRound
            .Actions.OfType <Bid>()
            .LastOrDefault());
 }