예제 #1
0
        private void DistributeWinnings(HandRanker handRanker)
        {
            foreach (var pot in _potMan.Pots)
            {
                // get all players who are involved in this pot
                var playersInvolved = pot.ListPlayersInvolved();

                // loop through hand ranks from highest to lowest
                // find highest ranked handRank that includes at least one of these players
                foreach (var hri in handRanker.HandRanks)
                {
                    var playersInRank = hri.Players;

                    var winningPlayers = playersInvolved.Intersect(playersInRank).ToList();

                    if (winningPlayers.Count > 0)
                    {
                        // split pot equally between winning players - then handle remainder, remove cash from pot, add to players stack
                        var amountWon       = new Dictionary <int, int>();
                        var potRemaining    = pot.Size();
                        var shareOfWinnings = potRemaining / winningPlayers.Count;

                        foreach (var i in winningPlayers)
                        {
                            amountWon[i]  = shareOfWinnings;
                            potRemaining -= shareOfWinnings;
                        }

                        // if remainder left in pot then allocate 1 chip at a time starting at player in worst position (closest to small blind)
                        var currPlayer = _dealerPlayerNum;

                        while (potRemaining > 0)
                        {
                            do
                            {
                                currPlayer = GetNextActivePlayer(currPlayer);
                            } while (!winningPlayers.Contains(currPlayer));

                            amountWon[currPlayer]++;
                            potRemaining--;
                        }

                        pot.EmptyPot();

                        // broadcast win
                        foreach (var pair in amountWon)
                        {
                            _players[pair.Key].StackSize += pair.Value;
                            BroadcastAction(Stage.StageShowdown, pair.Key, ActionType.Win, pair.Value);
                        }

                        BroadcastWinnings(amountWon);

                        break;
                    }
                }
            }

            _potMan.EmptyPot();
        }
예제 #2
0
        private void Showdown(Card[] board, ref HandRanker handRanker, int lastToAct)
        {
            var  firstToAct = GetNextActivePlayer(lastToAct);
            Hand playerBestHand;
            var  uncontestedPots = new List <int>();

            for (var potNum = 0; potNum < _potMan.Pots.Count; potNum++)
            {
                uncontestedPots.Add(potNum);
            }

            // evaluate and show hand for first player to act - flag them as winning for now
            playerBestHand = Hand.FindPlayersBestHand(_players[firstToAct].HoleCards(), board);
            BroadcastPlayerHand(firstToAct, playerBestHand);

            handRanker.AddHand(firstToAct, playerBestHand);
            uncontestedPots = uncontestedPots.Except(_potMan.GetPotsInvolvedIn(firstToAct)).ToList();

            // Loop through other active players
            var currPlayer = GetNextActivePlayer(firstToAct);

            do
            {
                var         player = _players[currPlayer];
                EActionType playersAction;
                int         playersAmount;

                // if not first to act then player may fold without showing cards (unless all in)
                // Also don't allow a player to fold if they are involved in a currently uncontested (side) pot
                var potsInvolvedIn = _potMan.GetPotsInvolvedIn(currPlayer);
                if (player.StackSize > 0 && (uncontestedPots.Intersect(potsInvolvedIn).Count() == 0))
                {
                    player.GetAction(EStage.StageShowdown, 0, 0, 0, 0, _potMan.Size(), out playersAction, out playersAmount);
                }
                else
                {
                    playersAction = EActionType.ActionShow;
                }

                if (playersAction == EActionType.ActionFold)
                {
                    _players[currPlayer].IsActive = false;
                    BroadcastAction(EStage.StageShowdown, currPlayer, playersAction, 0);
                }
                else
                {
                    playerBestHand = Hand.FindPlayersBestHand(player.HoleCards(), board);
                    handRanker.AddHand(currPlayer, playerBestHand);
                    uncontestedPots = uncontestedPots.Except(potsInvolvedIn).ToList();

                    BroadcastPlayerHand(currPlayer, playerBestHand);
                }

                currPlayer = GetNextActivePlayer(currPlayer);
            } while (currPlayer != firstToAct);
        }
예제 #3
0
        public void PlayGame(string sConfigFile, string sOutputBase)
        {
            LoadConfig(sConfigFile, sOutputBase);

            var bDone   = false;
            var handNum = 0;
            var rnd     = new Random();

            _totalMoneyInGame = _players.Sum(p => p.StackSize);

            _dealerPlayerNum = 0;

            if (_bRandomDealer)
            {
                int dealerIncr = rnd.Next(GetNumActivePlayers());

                while (dealerIncr > 0)
                {
                    _dealerPlayerNum = GetNextActivePlayer(_dealerPlayerNum);
                    dealerIncr--;
                }
            }

            _smallBlindPlayerId = GetNextActivePlayer(_dealerPlayerNum);
            _bigBlindPlayerNum  = GetNextActivePlayer(_smallBlindPlayerId);

            BroadcastInitialisation();

            while (!bDone)
            {
                var communityCards = new Card[5];
                int lastToAct;

                // init round for each player
                handNum++;
                InitialiseHand(handNum);

                BroadcastBeginHand();

                // deal out hole cards to all active players
                DealHoleCards();

                BroadcastBeginStage(Stage.StagePreflop, communityCards);
                // First betting round - get player actions and broadcast to all players until betting round done
                DoBettingRound(Stage.StagePreflop, out lastToAct);
                BroadcastEndStage();

                if (GetNumActivePlayers() > 1)
                {
                    // deal flop
                    communityCards[0] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardFlop1, communityCards[0]);

                    communityCards[1] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardFlop2, communityCards[1]);

                    communityCards[2] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardFlop3, communityCards[2]);

                    BroadcastBeginStage(Stage.StageFlop, communityCards);
                    // Second betting round - get player actions and broadcast to all players until betting round done
                    if (IsBettingRoundRequired())
                    {
                        DoBettingRound(Stage.StageFlop, out lastToAct);
                    }
                    BroadcastEndStage();
                }

                if (GetNumActivePlayers() > 1)
                {
                    // deal turn
                    communityCards[3] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardTurn, communityCards[3]);

                    BroadcastBeginStage(Stage.StageTurn, communityCards);
                    // Third betting round - get player actions and broadcast to all players until betting round done
                    if (IsBettingRoundRequired())
                    {
                        DoBettingRound(Stage.StageTurn, out lastToAct);
                    }
                    BroadcastEndStage();
                }

                if (GetNumActivePlayers() > 1)
                {
                    // deal river
                    communityCards[4] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardRiver, communityCards[4]);

                    BroadcastBeginStage(Stage.StageRiver, communityCards);
                    // Fourth betting round - get player actions and broadcast to all players until betting round done
                    if (IsBettingRoundRequired())
                    {
                        DoBettingRound(Stage.StageRiver, out lastToAct);
                    }
                    BroadcastEndStage();
                }

                // ViewCash();

                var handRanker = new HandRanker();

                if (GetNumActivePlayers() > 1)
                {
                    Showdown(communityCards, ref handRanker, lastToAct);
                }

                if (GetNumActivePlayers() > 1)
                {
                    // More than one player has shown cards at showdown. Work out how to allocate the pot(s)
                    DistributeWinnings(handRanker);
                }
                else
                {
                    // all players except 1 have folded. Just give entire pot to last man standing
                    var winningPlayer = _players.First(p => p.IsActive).PlayerNum;

                    _players[winningPlayer].StackSize += _potMan.Size();
                    BroadcastAction(Stage.StageShowdown, winningPlayer, ActionType.Win, _potMan.Size());
                    _potMan.EmptyPot();
                }

                // check that money hasn't disappeared or magically appeared
                ReconcileCash();

                // Kill off broke players & check if only one player left
                KillBrokePlayers();

                BroadcastEndHand();

                if (GetNumLivePlayers() == 1)
                {
                    bDone = true;
                }
                else if (_maxHands > 0 && handNum >= _maxHands)
                {
                    bDone = true;
                }
                else
                {
                    // Move to next dealer
                    MoveDealerAndBlinds();
                }

                if (_bPauseAfterEachHand)
                {
                    Console.WriteLine("--- Press any key to continue (ESC to exit) ---");
                    bDone = Console.ReadKey().Key == ConsoleKey.Escape;
                }
            }

            EndOfGame();

            // Write entry to summary log - !!! do this in EndofGame / new Display class?
            TextWriter logTextWriter = new StreamWriter("logs\\Summary.txt", true);

            var playerInfos = GetListOfPlayerInfos();

            foreach (var p in playerInfos)
            {
                if (p.IsAlive)
                {
                    logTextWriter.WriteLine(sConfigFile + "\t" + sOutputBase + "\t" + p.Name + "\t" + handNum);
                }
            }

            logTextWriter.Close();
        }
예제 #4
0
        public void PlayGame()
        {
            LoadConfig();

            var bDone   = false;
            var handNum = 0;

            _totalMoneyInGame     = _players.Sum(p => p.StackSize);
            _dealerPlayerNum      = 0;
            _littleBlindPlayerNum = GetNextActivePlayer(_dealerPlayerNum);
            _bigBlindPlayerNum    = GetNextActivePlayer(_littleBlindPlayerNum);


            _display = new DisplayManager(150, 35, _players);
            _display.DrawTable();

            while (!bDone)
            {
                var board = new Card[5];
                _display.UpdateCommunityCards(board);
                int lastToAct;

                // init round for each player
                handNum++;
                InitHand(handNum);

                // deal out hole cards to all active players
                DealHoleCards();

                // First betting round - get player actions and broadcast to all players until betting round done
                DoBettingRound(EStage.StagePreflop, out lastToAct);
                _display.UpdatePots(_potMan.Pots);

                if (GetNumActivePlayers() > 1)
                {
                    // deal flop
                    board[0] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardFlop1, board[0]);
                    _display.UpdateCommunityCards(board);

                    board[1] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardFlop2, board[1]);
                    _display.UpdateCommunityCards(board);

                    board[2] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardFlop3, board[2]);
                    _display.UpdateCommunityCards(board);

                    // Second betting round - get player actions and broadcast to all players until betting round done
                    if (IsBettingRoundRequired())
                    {
                        DoBettingRound(EStage.StageFlop, out lastToAct);
                        _display.UpdatePots(_potMan.Pots);
                    }
                }

                if (GetNumActivePlayers() > 1)
                {
                    // deal turn
                    board[3] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardTurn, board[3]);
                    _display.UpdateCommunityCards(board);

                    // Third betting round - get player actions and broadcast to all players until betting round done
                    if (IsBettingRoundRequired())
                    {
                        DoBettingRound(EStage.StageTurn, out lastToAct);
                        _display.UpdatePots(_potMan.Pots);
                    }
                }

                if (GetNumActivePlayers() > 1)
                {
                    // deal river
                    board[4] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardRiver, board[4]);
                    _display.UpdateCommunityCards(board);

                    // Fourth betting round - get player actions and broadcast to all players until betting round done
                    if (IsBettingRoundRequired())
                    {
                        DoBettingRound(EStage.StageRiver, out lastToAct);
                        _display.UpdatePots(_potMan.Pots);
                    }
                }

                ViewCash();

                var handRanker = new HandRanker();

                if (GetNumActivePlayers() > 1)
                {
                    Showdown(board, ref handRanker, lastToAct);
                    handRanker.ViewHandRanks();
                }

                if (GetNumActivePlayers() > 1)
                {
                    // More than one player has shown cards at showdown. Work out how to allocate the pot(s)
                    DistributeWinnings(handRanker);
                }
                else
                {
                    // all players except 1 have folded. Just give entire pot to last man standing
                    var winningPlayer = _players.First(p => p.IsActive).PlayerNum;

                    _players[winningPlayer].StackSize += _potMan.Size();
                    BroadcastAction(EStage.StageShowdown, winningPlayer, EActionType.ActionWin, _potMan.Size());
                    _potMan.EmptyPot();
                }

                // check that money hasn't disappeared or magically appeared
                ReconcileCash();

                // Kill off broke players & check if only one player left
                KillBrokePlayers();

                if (GetNumLivePlayers() == 1)
                {
                    bDone = true;
                }
                else if (_maxHands > 0 && handNum >= _maxHands)
                {
                    bDone = true;
                }
                else
                {
                    // Move to next dealer
                    MoveDealerAndBlinds();
                }
                _display.UpdatePots(_potMan.Pots);

                /*
                 *              ConsoleKeyInfo cki;
                 *              cki= System.Console.ReadKey();
                 *              bDone = (cki.Key == ConsoleKey.Escape);
                 */
            }

            EndOfGame();
        }
예제 #5
0
        private void DistributeWinnings(HandRanker handRanker)
        {
            foreach(var pot in _potMan.Pots)
            {
                // get all players who are involved in this pot
                var playersInvolved = pot.ListPlayersInvolved();

                // loop through hand ranks from highest to lowest
                // find highest ranked handRank that includes at least one of these players
                foreach (var hri in handRanker.HandRanks)
                {
                    var playersInRank = hri.Players;

                    var winningPlayers = playersInvolved.Intersect(playersInRank).ToList();

                    if (winningPlayers.Count > 0)
                    {
                        // split pot equally between winning players - then handle remainder, remove cash from pot, add to players stack
                        var amountWon = new Dictionary<int, int>();
                        var potRemaining = pot.Size();
                        var shareOfWinnings = potRemaining / winningPlayers.Count;

                        foreach (var i in winningPlayers)
                        {
                            amountWon[i] = shareOfWinnings;
                            potRemaining -= shareOfWinnings;
                        }

                        // if remainder left in pot then allocate 1 chip at a time starting at player in worst position (closest to little blind)
                        var currPlayer = _dealerPlayerNum;

                        while (potRemaining > 0)
                        {
                            do
                            {
                                currPlayer = GetNextActivePlayer(currPlayer);
                            } while (!winningPlayers.Contains(currPlayer));

                            amountWon[currPlayer]++;
                            potRemaining--;
                        }

                        pot.EmptyPot();

                        // broadcast win
                        foreach (var pair in amountWon)
                        {
                            _players[pair.Key].StackSize += pair.Value;
                            BroadcastAction(EStage.StageShowdown, pair.Key, EActionType.ActionWin, pair.Value);
                        }

                        break;
                    }
                }
            }

            _potMan.EmptyPot();
        }
예제 #6
0
        private void Showdown(Card[] board, ref HandRanker handRanker, int lastToAct)
        {
            var firstToAct = GetNextActivePlayer(lastToAct);
            Hand playerBestHand;
            var uncontestedPots = new List<int>();

            for (var potNum = 0; potNum < _potMan.Pots.Count; potNum++)
            {
                uncontestedPots.Add(potNum);
            }

            // evaluate and show hand for first player to act - flag them as winning for now
            playerBestHand = Hand.FindPlayersBestHand(_players[firstToAct].HoleCards(), board);
            BroadcastPlayerHand(firstToAct, playerBestHand);

            handRanker.AddHand(firstToAct, playerBestHand);
            uncontestedPots = uncontestedPots.Except( _potMan.GetPotsInvolvedIn(firstToAct)).ToList();

            // Loop through other active players 
            var currPlayer = GetNextActivePlayer(firstToAct);

            do
            {
                var player = _players[currPlayer];
                EActionType playersAction;
                int playersAmount;

                // if not first to act then player may fold without showing cards (unless all in)
                // Also don't allow a player to fold if they are involved in a currently uncontested (side) pot
                var potsInvolvedIn = _potMan.GetPotsInvolvedIn(currPlayer);
                if (player.StackSize > 0 && (uncontestedPots.Intersect(potsInvolvedIn).Count() == 0))
                {
                    player.GetAction(EStage.StageShowdown, 0, 0, 0, 0, _potMan.Size(), out playersAction, out playersAmount);
                }
                else
                {
                    playersAction = EActionType.ActionShow;
                }

                if (playersAction == EActionType.ActionFold)
                {
                    _players[currPlayer].IsActive = false;
                    BroadcastAction(EStage.StageShowdown, currPlayer, playersAction, 0);
                }
                else
                {
                    playerBestHand = Hand.FindPlayersBestHand(player.HoleCards(), board);
                    handRanker.AddHand(currPlayer, playerBestHand);
                    uncontestedPots = uncontestedPots.Except(potsInvolvedIn).ToList();

                    BroadcastPlayerHand(currPlayer, playerBestHand);
                }

                currPlayer = GetNextActivePlayer(currPlayer);

            } while (currPlayer != firstToAct);
        }
예제 #7
0
        public void PlayGame()
        {
            LoadConfig();

            var bDone = false;
            var handNum = 0;

            _totalMoneyInGame = _players.Sum(p => p.StackSize);
            _dealerPlayerNum = 0;
            _littleBlindPlayerNum = GetNextActivePlayer(_dealerPlayerNum);
            _bigBlindPlayerNum = GetNextActivePlayer(_littleBlindPlayerNum);

            while (!bDone)
            {
                var board = new Card[5];
                int lastToAct;

                // init round for each player
                handNum++;
                InitHand(handNum);

                // deal out hole cards to all active players
                DealHoleCards();

                // First betting round - get player actions and broadcast to all players until betting round done
                DoBettingRound(EStage.StagePreflop, out lastToAct);

                if (GetNumActivePlayers() > 1)
                {
                    // deal flop
                    board[0] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardFlop1, board[0]);

                    board[1] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardFlop2, board[1]);

                    board[2] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardFlop3, board[2]);

                    // Second betting round - get player actions and broadcast to all players until betting round done
                    if (IsBettingRoundRequired())
                    {
                        DoBettingRound(EStage.StageFlop, out lastToAct);
                    }
                }

                if (GetNumActivePlayers() > 1)
                {
                    // deal turn
                    board[3] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardTurn, board[3]);

                    // Third betting round - get player actions and broadcast to all players until betting round done
                    if (IsBettingRoundRequired())
                    {
                        DoBettingRound(EStage.StageTurn, out lastToAct);
                    }
                }

                if (GetNumActivePlayers() > 1)
                {
                    // deal river
                    board[4] = _deck.DealCard();
                    BroadcastBoardCard(EBoardCardType.BoardRiver, board[4]);

                    // Fourth betting round - get player actions and broadcast to all players until betting round done
                    if (IsBettingRoundRequired())
                    {
                        DoBettingRound(EStage.StageRiver, out lastToAct);
                    }
                }

                ViewCash();

                var handRanker = new HandRanker();

                if (GetNumActivePlayers() > 1)
                {
                    Showdown(board, ref handRanker, lastToAct);
                    handRanker.ViewHandRanks();
                }

                if (GetNumActivePlayers() > 1)
                {
                    // More than one player has shown cards at showdown. Work out how to allocate the pot(s)
                    DistributeWinnings(handRanker);
                }
                else
                {
                    // all players except 1 have folded. Just give entire pot to last man standing
                    var winningPlayer = _players.First(p => p.IsActive).PlayerNum;

                    _players[winningPlayer].StackSize += _potMan.Size();
                    BroadcastAction(EStage.StageShowdown, winningPlayer, EActionType.ActionWin, _potMan.Size());
                    _potMan.EmptyPot();
                }

                // check that money hasn't disappeared or magically appeared
                ReconcileCash();

                // Kill off broke players & check if only one player left
                KillBrokePlayers();

                if (GetNumLivePlayers() == 1)
                {
                    bDone = true;
                }
                else if (_maxHands > 0 && handNum >= _maxHands)
                {
                    bDone = true;
                }
                else
                {
                    // Move to next dealer 
                    MoveDealerAndBlinds();
                }

/*
                ConsoleKeyInfo cki;
                cki= System.Console.ReadKey();
                bDone = (cki.Key == ConsoleKey.Escape);
*/
            }

            EndOfGame();
        }
예제 #8
0
        public void DisplayShowdown(HandRanker handRanker, PotManager potMan)
        {
            int i;

            // show pots
            Logger.Log("");

            string sLogMsg = "Pots     \t";

            for (i = 0; i < potMan.Pots.Count(); i++)
            {
                sLogMsg += i + "\t";
            }

            sLogMsg += "Total";
            Logger.Log(sLogMsg);

            // !!! only show live players?
            for (i = 0; i < _numPlayers; i++)
            {
                sLogMsg = "Player " + i + "\t";

                // !!! show stack size for player here?

                foreach (var p in potMan.Pots)
                {
                    int value = 0;

                    if (p.PlayerContributions.ContainsKey(i))
                    {
                        value = p.PlayerContributions[i];
                    }

                    sLogMsg += value + "\t";
                }

                sLogMsg += potMan.PlayerContributions(i);
                Logger.Log(sLogMsg);
            }

            sLogMsg = "Total   ";

            foreach (var p in potMan.Pots)
            {
                sLogMsg += "\t" + p.Size();
            }

            Logger.Log(sLogMsg);

            // Show hand ranks
            Logger.Log("");
            Logger.Log("--- Hand Ranks ---");

            foreach (var hri in handRanker.HandRanks)
            {
                var hand = hri.Hand;

                sLogMsg = hand.HandRankStr() + " ";

                for (i = 0; i < hand.NumSubRanks(); i++)
                {
                    sLogMsg += hand.SubRank(i) + " ";
                }

                sLogMsg += "Players (" + string.Join(",", hri.Players) + ")";
                Logger.Log(sLogMsg);
            }

            Logger.Log("");
        }