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