public void Test_IsDealerAction() { PokerAction action = new PokerAction(); action.Kind = Ak.b; Assert.IsFalse(action.IsDealerAction()); action.Kind = Ak.f; Assert.IsFalse(action.IsDealerAction()); action.Kind = Ak.c; Assert.IsFalse(action.IsDealerAction()); action.Kind = Ak.r; Assert.IsFalse(action.IsDealerAction()); action.Kind = Ak.d; Assert.IsTrue(action.IsDealerAction()); }
public void Test_IsDealerAction_Static() { Assert.IsFalse(PokerAction.IsDealerAction(Ak.b)); Assert.IsFalse(PokerAction.IsDealerAction(Ak.f)); Assert.IsFalse(PokerAction.IsDealerAction(Ak.c)); Assert.IsFalse(PokerAction.IsDealerAction(Ak.r)); Assert.IsTrue(PokerAction.IsDealerAction(Ak.d)); }
public DealRecord(GameRecord cfg, DeckDescriptor deckDescr, SequenceRng randomDealer) { _cfg = cfg; _deckDescr = deckDescr; _randomDealer = randomDealer; // Loop through actions and // - find the fixed cards // - count random cards // - count enumerated cards for (int a = 0; a < _cfg.Actions.Count; ++a) { PokerAction action = _cfg.Actions[a]; if (!action.IsDealerAction()) { continue; } string[] cards = action.Cards.Split(_separator, StringSplitOptions.RemoveEmptyEntries); foreach (string card in cards) { if (card == "?") { _randomCount++; } else if (card.Length > 0 && card.Substring(0, 1) == "#") { int idx = int.Parse(card.Substring(1)); while (_enumCounts.Count <= idx) { _enumCounts.Add(0); _enumCombosCounts.Add(0); _enumCombos.Add(new List <CardSet>()); } _enumCounts[idx]++; } else { _fixedCards.UnionWith(_deckDescr.GetCardSet(card)); } } } // Count enumerated combinations. int deadCards = _fixedCards.CountCards(); for (int i = 0; i < _enumCounts.Count; ++i) { _enumCombosCounts[i] = EnumAlgos.CountCombin(_deckDescr.Size - deadCards, _enumCounts[i]); deadCards += _enumCounts[i]; } }
/// <summary> /// Parses Open CFG format to PokerAction list. Converts cards to indexes for both abstracted /// and non-abstracted games. /// </summary> List <PokerAction> ParseActionString(string key, out int round) { List <PokerAction> actions = new List <PokerAction>(); actions.Add(new PokerAction()); string[] parts = key.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 2) { throw new ApplicationException("Wrong format"); } string pocket = parts[0].Substring(0, 1); string board = parts[0].Length == 1 ? null : parts[0].Substring(1, 1); // Add two deals, as this is required to update game state. // One deal will be ignored later in the conversion to a strategic string. actions.Add(PokerAction.d(0, GameDef.DeckDescr.GetIndex(pocket).ToString())); actions.Add(PokerAction.d(1, GameDef.DeckDescr.GetIndex(pocket).ToString())); round = 0; int pos = 0; foreach (char actChar in parts[1].Substring(1)) { switch (actChar) { case 'r': actions.Add(PokerAction.r(pos, GetRaiseAmount(round))); pos = 1 - pos; break; case 'c': actions.Add(PokerAction.c(pos)); pos = 1 - pos; break; case '/': actions.Add(PokerAction.d(GameDef.DeckDescr.GetIndex(board).ToString())); round++; pos = 0; break; default: throw new ApplicationException("Wrong format"); } } if (ChanceAbstraction != null) { int[] hand = new int[2]; round = -1; for (int i = 0; i < actions.Count; ++i) { PokerAction a = actions[i]; if (a.Kind == Ak.d && a.Position <= 0) { ++round; hand[round] = int.Parse(a.Cards); } if (a.IsDealerAction() && a.Cards != "") { int bucket = ChanceAbstraction.GetAbstractCard(hand, round + 1); a.Cards = bucket.ToString(); } } } return(actions); }
public GameRecord Generate(int repetition) { string[][] enumNames = new string[_enumCounts.Count][]; int[] enumIndexes = new int[_enumCounts.Count]; CardSet deadCards = _fixedCards; if (_enumCounts.Count != 0) { int r = repetition; for (int d = _enumCounts.Count - 1; d >= 0; --d) { enumIndexes[d] = r % (int)_enumCombosCounts[d]; r /= (int)_enumCombosCounts[d]; } int redealFrom = _enumCombos.Count; for (int d = _enumCounts.Count - 1; d >= 0; --d) { if (enumIndexes[d] != 0) { break; } redealFrom = d; } for (int d = 0; d < redealFrom; ++d) { deadCards.UnionWith(_enumCombos[d][enumIndexes[d]]); } for (int d = redealFrom; d < _enumCombos.Count; ++d) { _enumCombos[d].Clear(); CardEnum.Combin(_deckDescr, _enumCounts[d], CardSet.Empty, deadCards, OnCombin, d); Debug.Assert(_enumCombosCounts[d] == _enumCombos[d].Count); deadCards.UnionWith(_enumCombos[d][enumIndexes[d]]); } for (int d = 0; d < _enumCombos.Count; ++d) { string enumCards = _deckDescr.GetCardNames(_enumCombos[d][enumIndexes[d]]); enumNames[d] = enumCards.Split(_separator, StringSplitOptions.RemoveEmptyEntries); } } GameRecord result = new GameRecord(_cfg.ToString()); result.Actions.Clear(); // Shuffle the rest of the deck. CardSet deckRest = _deckDescr.FullDeck; deckRest.Remove(deadCards); _randomDealer.SetSequence(_deckDescr.GetIndexesAscending(deckRest).ToArray()); _randomDealer.Shuffle(_randomCount); int randomDealt = 0; int[] enumDealt = new int[_enumCounts.Count]; // Deal the cards. for (int a = 0; a < _cfg.Actions.Count; ++a) { PokerAction action = _cfg.Actions[a]; if (!action.IsDealerAction()) { continue; } string[] cards = action.Cards.Split(_separator, StringSplitOptions.RemoveEmptyEntries); CardSet resultCards = new CardSet(); foreach (string card in cards) { CardSet nextCard = new CardSet(); if (card == "?") { nextCard = _deckDescr.GetCardSet(_randomDealer.Sequence, randomDealt++, 1); } else if (card.Length > 0 && card.Substring(0, 1) == "#") { int d = int.Parse(card.Substring(1)); string enumName = enumNames[d][enumDealt[d]++]; nextCard = _deckDescr.GetCardSet(enumName); } else { nextCard = _deckDescr.GetCardSet(card); } Debug.Assert(!resultCards.IsIntersectingWith(nextCard)); resultCards.UnionWith(nextCard); } PokerAction resultAction = new PokerAction(action.Kind, action.Position, action.Amount, _deckDescr.GetCardNames(resultCards)); result.Actions.Add(resultAction); } Debug.Assert(_randomCount == randomDealt); return(result); }
/// <summary> /// Processes each poker action received from the server. /// Updates the game state and moves to the next node in our strategy. /// </summary> /// <param name="pa"></param> void ProcessAction(PokerAction pa) { int chBegin, chCount; _strIndexes[_pos].GetChildrenBeginIdxAndCount(_curStrNodeIdx, out chBegin, out chCount); int nextStrNodeIdx = -1; if (pa.IsDealerAction()) { _gameState.UpdateByAction(pa, null); if (pa.Position >= 0 && pa.Position != _pos) { // This is a deal to an opponent // We can skip it for games without public cards (and it is very unlikely we will have some // in the future). return; } int[] hand = _deckDescr.GetIndexes(_gameState.Players[_pos].Hand); int abstrCard = _chanceAbsrtractions[_pos].GetAbstractCard(hand, hand.Length); for (int c = 0; c < chCount; ++c) { int stNodeIdx = _strIndexes[_pos].GetChildIdx(chBegin + c); StrategyTreeNode stNode = new StrategyTreeNode(); _strategies[_pos].GetNode(stNodeIdx, &stNode); if (!stNode.IsDealerAction) { throw new ApplicationException( String.Format("{0} : expected strategy child: dealer action but was: '{1}'", GetBotStateDiagText(), stNode.ToStrategicString(null))); } if (stNode.Card == abstrCard) { nextStrNodeIdx = stNodeIdx; goto searchFinished; } } } else // Player action { double inPotBefore = _gameState.Players[pa.Position].InPot; _gameState.UpdateByAction(pa, null); double inPotAfter = _gameState.Players[pa.Position].InPot; double actualAmount = inPotAfter - inPotBefore; double bestAmount = double.MinValue; for (int c = 0; c < chCount; ++c) { int stNodeIdx = _strIndexes[_pos].GetChildIdx(chBegin + c); StrategyTreeNode stNode = new StrategyTreeNode(); _strategies[_pos].GetNode(stNodeIdx, &stNode); if (!stNode.IsPlayerAction(pa.Position)) { throw new ApplicationException( String.Format("{0} : expected strategy child: player action pos {1} but was: '{2}'", GetBotStateDiagText(), pa.Position, stNode.ToStrategicString(null))); } double amount = stNode.Amount; switch (_amountSearchMethod) { case AmountSearchMethod.Equal: if (FloatingPoint.AreEqual(amount, actualAmount, AMOUNT_EPSILON)) { nextStrNodeIdx = stNodeIdx; goto searchFinished; } break; case AmountSearchMethod.Closest: if (Math.Abs(amount - actualAmount) < Math.Abs(bestAmount - actualAmount)) { bestAmount = amount; nextStrNodeIdx = stNodeIdx; } break; } } } searchFinished: if (nextStrNodeIdx == -1) { throw new ApplicationException( String.Format("{0} : cannot find strategy action for poker action '{1}'", GetBotStateDiagText(), pa.ToGameString())); } _curStrNodeIdx = nextStrNodeIdx; }