Exemple #1
0
        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());
        }
Exemple #2
0
 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));
 }
Exemple #3
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        /// <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;
        }