public BoardSituation(BoardSituation prevSituation, ulong cards, string playerName, int decision) { PreviousSituation = prevSituation; Cards = cards; Street = Hand.Cards(Cards).Count(); PlayerName = playerName; Decision = decision; if (prevSituation != null) { Deep = prevSituation.Deep + 1; if (Cards == prevSituation.Cards) { MaxBet = prevSituation.MaxBet; RaiseCount = prevSituation.RaiseCount; } int bet = GetPlayerCurrentBet(playerName); if (bet > prevSituation.MaxBet) { MaxBet = bet; if (Deep > 2) { RaiseCount++; } } } }
private static TableLog HandRound(StackPlayers sPlayers, TableInfo tInfo, bool showLog) { ulong dead = 0UL; ulong board = 0UL; TableLog log = new TableLog(showLog); GameState state = GameState.STARTINFO; log.Add(state, "Hand ID - " + tInfo.HandId + ", small blind - " + tInfo.SmallBlind + ", players count - " + sPlayers.Count + ", button seats on - " + (tInfo.Button + 1)); for (int p = 0; p < sPlayers.Count; p++) { log.Add(state, "Seat " + (p + 1) + ": " + sPlayers[p].Agent.GetName() + " has stack - " + sPlayers[p].Stack); } #region Streets List <Action> streets = new List <Action> { () => { // Раздаем карты for (int p = 0; p < sPlayers.Count; p++) { sPlayers[p].Hand = Hand.RandomHand(dead, 2); dead |= sPlayers[p].Hand; if (sPlayers[p].Agent.GetType() == typeof(Player)) { log.Add(state, sPlayers[p].Agent.GetName() + " pocket cards are " + Hand.MaskToString(sPlayers[p].Hand)); } } state = GameState.PREFLOP; log.Add(state, "*** " + state.ToString() + " ***"); }, () => { ulong flop = Hand.RandomHand(dead, 3); board = flop; dead |= flop; state = GameState.FLOP; log.Add(state, "*** FLOP *** [" + Hand.MaskToString(flop) + "]"); }, () => { ulong turn = Hand.RandomHand(dead, 1); state = GameState.TURN; log.Add(state, "*** TURN *** [" + Hand.MaskToString(board) + "] [" + Hand.MaskToString(turn) + "]"); board |= turn; dead |= turn; }, () => { ulong river = Hand.RandomHand(dead, 1); state = GameState.RIVER; log.Add(state, "*** RIVER *** [" + Hand.MaskToString(board) + "] [" + Hand.MaskToString(river) + "]"); board |= river; } }; #endregion // Создаем начальную ситуацию с пустым столом BoardSituation currentSituation = null; foreach (var street in streets) { street(); currentSituation = new BoardSituation(currentSituation, board, "", -1); EmulatorPlayer player; while (player = sPlayers.GetNextPlayer(currentSituation, tInfo)) { int decision = -1; // Если нужно ставить блайды - ставим, иначе запрашиваем ставку у агента if (currentSituation.Deep == 0) { decision = tInfo.SmallBlind; } else if (currentSituation.Deep == 1) { decision = tInfo.SmallBlind * 2; } else { decision = player.Agent.GetDecision(currentSituation, tInfo); } //Проверяем верность ставки int currentBet = currentSituation.GetPlayerCurrentBet(player.Agent.GetName()); if (decision >= 0) { if (decision + currentBet < currentSituation.MaxBet || sPlayers.GetNotFoldedAndNotAllInInGamePlayers() == 1 || currentSituation.RaiseCount == 3) { decision = currentSituation.MaxBet - currentBet; } } if (decision > player.Stack) { decision = player.Stack; } else if (decision < -1) { decision = -1; } // Добавляем ситуацию в дерево currentSituation = new BoardSituation(currentSituation, board, player.Agent.GetName(), decision); log.Add(state, player.Agent.GetName() + ": " + currentSituation.GetActionString(tInfo)); } if (sPlayers.IsGameOver(currentSituation, tInfo, ref log)) { break; } } log.Add(GameState.ENDINFO, "Game Over"); return(log); }
public EmulatorPlayer GetNextPlayer(BoardSituation currentSituation, TableInfo tInfo) { // Меняем стэк сходившего игрока if (currentSituation.Decision > 0) { players[GetIndexPlayerByName(currentSituation.PlayerName)].Stack -= currentSituation.Decision; } else if (currentSituation.Decision == -1 && currentSituation.PlayerName != "") { players[GetIndexPlayerByName(currentSituation.PlayerName)].Folded = true; } int sbPlayer = 0; if (players.Count > 2) { sbPlayer = GetNextIndexInGame(tInfo.Button); } else { sbPlayer = tInfo.Button; } if (currentSituation.Deep == 0) { return(players[sbPlayer]); } else if (currentSituation.Deep == 1) { return(players[GetNextIndexInGame(sbPlayer)]); } // Если игроков в игре и не сбросивших меньше 2х, круг закончен if (players.Count(p => p.Folded == false) < 2) { return(null); } int curIndex = GetNextIndexInGame(currentSituation.PlayerName); int?prevIndex = null; if (currentSituation.PlayerName == "") { curIndex = GetNextIndexInGame(tInfo.Button); } else { prevIndex = GetIndexPlayerByName(currentSituation.PlayerName); } // Если текущий игрок выставился, берем следующего while (prevIndex != curIndex && (players[curIndex].Stack == 0 || players[curIndex].Folded)) { if (prevIndex == null) { prevIndex = curIndex; } curIndex = GetNextIndexInGame(curIndex); } if (curIndex == prevIndex) { return(null); } int curBet = currentSituation.GetPlayerCurrentBet(players[curIndex].Agent.GetName()); // Если ставки заколированы и игрок уже ходил, круг закончен if (curBet == currentSituation.MaxBet && (currentSituation.GetActionsCount(players[curIndex].Agent.GetName()) > 0 || players.Count(p => p.Stack > 0 && p.Folded == false) <= 1)) { return(null); } return(players[curIndex]); }
public bool IsGameOver(BoardSituation currentSituation, TableInfo tInfo, ref TableLog log) { if (players.Count(p => !p.Folded) < 2 || Hand.Cards(currentSituation.Cards).Count() == 5) { int pot = currentSituation.GetPot(); var lastPlayers = players.Where(p => !p.Folded).ToList(); if (lastPlayers.Count == 1) { lastPlayers[0].Stack += pot; log.Add(GameState.ENDINFO, lastPlayers[0].Agent.GetName() + " won " + pot + " chips."); } else { var bets = new List <Bets>(); for (int i = 0; i < lastPlayers.Count; i++) { var b = new Bets(); b.HandValue = Hand.Evaluate(currentSituation.Cards | lastPlayers[i].Hand); b.Bet = currentSituation.GetPlayerPot(lastPlayers[i].Agent.GetName()); b.Name = lastPlayers[i].Agent.GetName(); bets.Add(b); } var foldedPlayers = players.Where(p => p.Folded).ToList(); var foldedBets = new List <int>(); for (int i = 0; i < foldedPlayers.Count; i++) { foldedBets.Add(currentSituation.GetPlayerPot(foldedPlayers[i].Agent.GetName())); } while (pot > 0) { var max = bets.Max(b => b.HandValue); var maxValues = bets.Where(b => b.HandValue == max).OrderBy(b => b.Bet).ToList(); int win = maxValues[0].Bet; int foldedPot = 0; for (int i = 0; i < foldedBets.Count; i++) { if (foldedBets[i] < win) { foldedPot += foldedBets[i]; foldedBets[i] = 0; } else { foldedPot += win; foldedBets[i] -= win; } } int sidePot = 0; for (int i = 0; i < bets.Count; i++) { if (bets[i].Name != maxValues[0].Name) { if (bets[i].Bet < win) { sidePot += bets[i].Bet; bets[i].Bet = 0; } else { sidePot += win; bets[i].Bet -= win; } } } win += foldedPot + sidePot; for (int i = 0; i < maxValues.Count; i++) { var p = lastPlayers.First(mp => mp.Agent.GetName() == maxValues[i].Name); p.Stack += win / maxValues.Count; log.Add(GameState.ENDINFO, p.Agent.GetName() + " won " + (win / maxValues.Count) + " chips with " + Hand.DescriptionFromHandValueInternal(maxValues[i].HandValue) + "."); } pot -= win; if (win % maxValues.Count != 0) { int mod = win % maxValues.Count; int button = tInfo.Button; EmulatorPlayer p = null; var winnigPlayers = maxValues.Select(v => v.Name).ToList(); while (!winnigPlayers.Contains((p = players[GetNextIndexInGame(button)]).Agent.GetName())) { button = GetNextIndexInGame(button); } p.Stack += mod; } bets.Remove(maxValues[0]); } } for (int i = 0; i < allPlayers.Count; i++) { if (allPlayers[i].Stack == 0) { allPlayers[i].InGame = false; } else { allPlayers[i].Folded = false; } } if (allPlayers.Sum(p => p.Stack) != 1500) { } return(true); } return(false); }