public void Initialize(CardSet deadCards)
        {
            CardSet full = StdDeck.Descriptor.FullDeck;

            Debug.Assert(full.CountCards() == 52);
            full.Remove(deadCards);
            _cards = StdDeck.Descriptor.GetIndexesAscending(full).ToArray();
        }
Example #2
0
        public static float Calculate(CardSet board)
        {
            CalulateParam param     = new CalulateParam();
            int           boardSize = board.CountCards();
            int           toDeal    = 7 - boardSize;

            CardEnum.Combin(StdDeck.Descriptor, toDeal, board, CardSet.Empty, OnDeal, param);
            return((float)(param.Sum / EnumAlgos.CountCombin(52 - boardSize, toDeal)));
        }
Example #3
0
        public static float CalculateFast(CardSet pocket, CardSet board)
        {
            int boardSize = board.CountCards();

            if (boardSize == 5)
            {
                int[]      hand    = new int[7];
                List <int> pocketL = StdDeck.Descriptor.GetIndexesAscending(pocket);
                List <int> boardL  = StdDeck.Descriptor.GetIndexesAscending(board);
                pocketL.CopyTo(hand, 0);
                boardL.CopyTo(hand, 2);
                return(Calculate(hand, 7));
            }
            return(CalculateFast(pocket, board, boardSize + 2));
        }
Example #4
0
        public void Test_CombinArray_CardSet()
        {
            CardSet[] arr = CardEnum.Combin(StdDeck.Descriptor, 2, CardSet.Empty, CardSet.Empty);
            Assert.AreEqual(1326, arr.Length);
            CardSet prev = arr[0];

            Assert.AreEqual(2, prev.CountCards());
            for (int i = 1; i < arr.Length; ++i)
            {
                CardSet cur = arr[i];
                Assert.Less(prev.bits, cur.bits);
                Assert.AreEqual(2, cur.CountCards());
                prev = cur;
            }
        }
Example #5
0
        void CombinRecursive(
            // Deck parameters
            CardSet[] deck, int suitCount, int deckSize,
            // Initial call parameters
            int n,
            // Algorithm parameters
            int depth, CardSet result1, int r1, int s1, int maxSuit,
            // Debug and test parameters
            ref int counter
            )
        {
            if (depth == n)
            {
                Debug.Assert(result1.CountCards() == n);
                counter++;
                _list.Add(result1);
                if (Verbose)
                {
                    Console.WriteLine("{0,6}: {1}", counter, result1);
                }
                return;
            }
            int r2 = r1;
            int s2 = s1 + 1;

            if (s2 >= suitCount)
            {
                s2 = 0;
                r2++;
            }

            for (; (r2 + s2) < deckSize + 1 - (n - depth);)
            {
                int maxSuit2 = r2 == r1 ? maxSuit : Math.Max(maxSuit, s2);
                //int maxSuit2 = Math.Max(maxSuit, s2);
                CardSet result2 = deck[r2 + s2];
                Debug.Assert(!result2.IsIntersectingWith(result1));
                result2.UnionWith(result1);
                CombinRecursive(deck, suitCount, deckSize, n, depth + 1, result2, r2, s2, maxSuit2, ref counter);
                s2++;
                if (s2 > Math.Min(maxSuit + 1, suitCount - 1))
                {
                    s2  = 0;
                    r2 += suitCount;
                }
            }
        }
Example #6
0
        public static float CalculateFast(CardSet board)
        {
            NormSuit ns          = new NormSuit();
            Entry    searchEntry = new Entry();

            searchEntry.CardSet = ns.Convert(board).bits;
            int round = HeHelper.HandSizeToRound[board.CountCards() + 2];

            Entry [] lut = _luts[round - 1];
            int      idx = Array.BinarySearch(lut, searchEntry);

            if (idx < 0)
            {
                throw new ApplicationException(string.Format("Cannot find LUT entry for board: '{0}'", StdDeck.Descriptor.GetCardNames(board)));
            }
            return(lut[idx].Ahvo);
        }
Example #7
0
        private void VerifyCombination(ref CardSet cs)
        {
            _combinationsCount++;
            Assert.IsFalse(cs.IsIntersectingWith(_dead));
            Assert.IsTrue(cs.Contains(_shared));
            CardSet uniqueMask = new CardSet {
                bits = cs.bits & (~_shared.bits)
            };

            Assert.AreEqual(_enumCount, uniqueMask.CountCards());
            // Use the fact that CardEnum generate masks in ascending order to check uniqueness
            if (_enumCount > 0)
            {
                Assert.Greater(uniqueMask.bits, _lastCs);
            }
            _lastCs = uniqueMask.bits;
        }
        /// <summary>
        /// Returns a cardset containing only cards of suites that are either a flush-draw
        /// or a flush. A flush draw is a set of cards of one suit that still can produce a flush,
        /// e.g. any single card for 5-hands, or 7c 8c Ad Kd for 7-hands.
        /// If the flush (5+ cards of one suit) is present, this function preserves
        /// only 5 highest flush cards, to prevent 6-hands like
        /// Ac Qc Jc Tc 9c 2c and Ac Qc Jc Tc 9c 3c from being different.
        /// This function is public to make some unit-tests.
        /// </summary>
        public static CardSet ExtractFlush(CardSet hand, int maxHandSize)
        {
            int  handSize = hand.CountCards();
            uint half     = (uint)hand.bits;

            _suits[0] = (half & 0xFFFF);
            _suits[1] = (half >> 16);
            half      = (uint)(hand.bits >> 32);
            _suits[2] = (half & 0xFFFF);
            _suits[3] = (half >> 16);

            for (int i = 0; i < 4; ++i)
            {
                int suitCount = CountBits.Count(_suits[i]);
                if (suitCount + (maxHandSize - handSize) >= 5)
                {
                    // Flush is possible
                    // Preserve the 5 highest cards.
                    uint bit = 0x00000001;
                    while (suitCount > 5)
                    {
                        if ((_suits[i] & bit) != 0)
                        {
                            suitCount--;
                            _suits[i] &= ~(bit);
                        }
                        bit <<= 1;
                    }
                }
                else
                {
                    // Flush is impossible, delete the cards.
                    _suits[i] = 0;
                }
            }
            CardSet result = CardSet.Empty;

            for (int i = 0; i < 4; ++i)
            {
                result.bits |= (((UInt64)_suits[i]) << (i * 16));
            }
            return(result);
        }
 private void FillFinalHands(State state, CardSet cards)
 {
     for (int c = 0; c < 52; ++c)
     {
         if (state.Table[c] != 0)
         {
             // Already done.
             continue;
         }
         CardSet nextCard = StdDeck.Descriptor.CardSets[c];
         if (nextCard.IsIntersectingWith(cards))
         {
             continue;
         }
         CardSet finalHand = cards | nextCard;
         Debug.Assert(finalHand.CountCards() == _maxHandSize);
         UInt32 handRank = CardSetEvaluator.Evaluate(ref finalHand);
         state.Table[c] = (Int32)handRank;
     }
 }
Example #10
0
        private void VerifyCombinationParam(int [] cards, int param)
        {
            CardSet cs = StdDeck.Descriptor.GetCardSet(cards);

            Assert.AreEqual(_combinationsCount, param);
            _combinationsCount1++;
            Assert.IsFalse(cs.IsIntersectingWith(_dead));
            Assert.IsTrue(cs.Contains(_shared));
            CardSet uniqueCs = new CardSet {
                bits = cs.bits & (~_shared.bits)
            };

            Assert.AreEqual(_enumCount, uniqueCs.CountCards());
            // Use the fact that CardEnum generate masks in ascending order to check uniqueness
            if (_enumCount > 0)
            {
                Assert.Greater(uniqueCs.bits, _lastCs1);
            }
            _lastCs1 = uniqueCs.bits;
        }
Example #11
0
        public static Result CalculateNoVerify(CardSet[] csRange1, CardSet[] csRange2)
        {
            UInt64   totalValue = 0;
            uint     count      = 0;
            NormSuit ns         = new NormSuit();
            Dictionary <CardSet, UInt32> knonwValues = new Dictionary <CardSet, UInt32>();

            foreach (CardSet cs1 in csRange1)
            {
                foreach (CardSet cs2 in csRange2)
                {
                    if (cs1.IsIntersectingWith(cs2))
                    {
                        continue;
                    }
                    CardSet union = ns.Convert(cs1);
                    union.UnionWith(ns.Convert(cs2));
                    ns.Reset();
                    Debug.Assert(union.CountCards() == 4);
                    UInt32 knownValue;
                    if (!knonwValues.TryGetValue(union, out knownValue))
                    {
                        int[] h1 = StdDeck.Descriptor.GetIndexesAscending(cs1).ToArray();
                        int[] h2 = StdDeck.Descriptor.GetIndexesAscending(cs2).ToArray();
                        knownValue = CalculateMatchupValue(h1, h2);
                        knonwValues.Add(union, knownValue);
                    }
                    totalValue += knownValue;
                    count++;
                }
            }
            Result r = new Result();

            r.Equity = (float)totalValue / count / _boardsCount / 2;
            r.Count  = count;
            return(r);
        }
        public static void DoMonteCarlo(
            ActionTree tree,
            int ourPos,
            CardSet pocket,
            int round,
            string sharedCardsAsString,
            List <ActionTreeNode> strategyPath,
            int repetitionsCount)
        {
            string[]       sharedCards     = sharedCardsAsString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            ActionTreeNode curStrategyNode = strategyPath[strategyPath.Count - 1];

            // Here we sometimes use the knowledge about the game definition.
            _clearValues.Walk(tree, curStrategyNode);

            MonteCarloData[] mc = new MonteCarloData[tree.GameDef.RoundsCount];
            for (int r = 0; r < mc.Length; ++r)
            {
                mc[r] = new MonteCarloData();
            }

            // Fill known public data.
            for (int r = 1; r <= round; ++r)
            {
                int sharedCount = tree.GameDef.SharedCardsCount[r];
                mc[r].boardSize = mc[r - 1].boardSize + sharedCount;
                mc[r].shared    = StdDeck.Descriptor.GetCardSet(sharedCards, mc[r - 1].boardSize, sharedCount);
                mc[r].board     = mc[r - 1].board | mc[r].shared;

                Debug.Assert(mc[r].shared.CountCards() == sharedCount);
                Debug.Assert(mc[r].board.CountCards() == mc[r].boardSize);
            }
            Debug.Assert(mc[round].boardSize == sharedCards.Length);

            MonteCarloDealer    mcDealer = new MonteCarloDealer();
            ApplyMonteCarloData applyMc  = new ApplyMonteCarloData();

            mcDealer.Initialize(pocket | mc[round].board);
            Debug.Assert(mcDealer.Cards.Length + pocket.CountCards() + mc[round].boardSize == 52);

            for (int repetition = 0; repetition < repetitionsCount * 10; ++repetition)
            {
                mcDealer.Shuffle(7); // 2 for opponent, up to 5 for the board

                CardSet mcPocket = StdDeck.Descriptor.GetCardSet(mcDealer.Cards, 0, 2);

                Debug.Assert(mc[0].board.IsEmpty());
                int sharedDealt = 0;
                for (int r = 0; r < tree.GameDef.RoundsCount; ++r)
                {
                    if (r > round)
                    {
                        mc[r].boardSize = mc[r - 1].boardSize + tree.GameDef.SharedCardsCount[r];
                        mc[r].shared    = StdDeck.Descriptor.GetCardSet(mcDealer.Cards, 2 + sharedDealt, tree.GameDef.SharedCardsCount[r]);
                        sharedDealt    += tree.GameDef.SharedCardsCount[r];
                        Debug.Assert(!mc[r - 1].board.Contains(mc[r].shared));
                        Debug.Assert(!mcPocket.Contains(mc[r].shared));
                        mc[r].board = mc[r - 1].board | mc[r].shared;
                    }
                    mc[r].bucket = tree.Bucketizer.GetBucket(mcPocket, mc[r].board, r);
                }
                double strategyFactor = 1;
                // Go through the strategy path, skip the b-node
                Debug.Assert(strategyPath[0].ActionKind == Ak.b);
                // Start from pos. 2 to skip deals (where OppBuckets always contains 0s if ourPos == 0).
                for (int pathIndex = 2; pathIndex < strategyPath.Count; pathIndex++)
                {
                    ActionTreeNode pathNode = strategyPath[pathIndex];
                    Debug.Assert(pathNode.ActionKind != Ak.b);
                    // Take nodes where opponent acts.
                    if (pathNode.State.CurrentActor == 1 - ourPos)
                    {
                        // nextNode always exists because this function is called when we act
                        ActionTreeNode nextNode = strategyPath[pathIndex + 1];
                        Debug.Assert(pathNode.State.Round == nextNode.State.Round);
                        int    freq     = pathNode.OppBuckets.Counts[mc[pathNode.State.Round].bucket];
                        int    nextFreq = nextNode.OppBuckets.Counts[mc[pathNode.State.Round].bucket];
                        double coef     = freq == 0 ? 0 : (double)nextFreq / freq;
                        strategyFactor *= coef;
                    }
                }
                if (strategyFactor > 0)
                {
                    int showdownValue = Showdown(pocket, mcPocket,
                                                 mc[tree.GameDef.RoundsCount - 1].board,
                                                 mc[tree.GameDef.RoundsCount - 1].boardSize + 2);
                    applyMc.ApplyData(curStrategyNode, mc, ourPos, showdownValue, strategyFactor);
                    repetition += 9;
                }
            }
            FinalizeMonteCarloData finalizer = new FinalizeMonteCarloData();

            finalizer.Finalize(tree, curStrategyNode, ourPos);
        }
Example #13
0
        bool FinalizeDeal(ref string currentDeal)
        {
            if (currentDeal == "")
            {
                return true;
            }
            if (_gameState.IsPlayerActing(_position))
            {
                ShowMessage("Is's agents turn");
                return false;
            }
            List<Ak> allowedActions = _gameState.GetAllowedActions(GameDef);
            if (!allowedActions.Contains(Ak.d))
            {
                ShowMessage(string.Format("Wrong action: 'd', expected: '{0}'", ActionKindListToString(allowedActions)));
                return false;
            }
            CardSet cs = StdDeck.Descriptor.GetCardSet(currentDeal);

            int dealRound = _gameState.Round +1;
            int expectedCardsCount = dealRound == 0 ? GameDef.PrivateCardsCount[dealRound] : GameDef.SharedCardsCount[dealRound];
            if (cs.CountCards() != expectedCardsCount)
            {
                ShowMessage(string.Format("Wrong cards count: {0}, expected: {1}", cs.CountCards(), expectedCardsCount));
                return false;
            }

            if(cs.IsIntersectingWith(_dealtCards))
            {
                ShowMessage(string.Format("Some of cards {0} are already dealt", currentDeal));
                return false;
            }
            _dealtCards |= cs;

            PokerAction pa = new PokerAction {Kind = Ak.d, Cards = currentDeal};
            currentDeal = "";
            if (_gameState.Round == -1)
            {
                PokerAction oppPrivateDeal = new PokerAction { Kind = Ak.d, Cards = "" };
                if (_position == 0)
                {
                    pa.Position = 0;
                    oppPrivateDeal.Position = 1;
                    _gameRecord.Actions.Add(pa);
                    _gameRecord.Actions.Add(oppPrivateDeal);
                }
                else
                {
                    pa.Position = 1;
                    oppPrivateDeal.Position = 0;
                    _gameRecord.Actions.Add(oppPrivateDeal);
                    _gameState.UpdateByAction(oppPrivateDeal, GameDef);
                    _gameRecord.Actions.Add(pa);
                }
                _gameState.UpdateByAction(_gameRecord.Actions[_gameRecord.Actions.Count - 2], GameDef);
                _gameState.UpdateByAction(_gameRecord.Actions[_gameRecord.Actions.Count - 1], GameDef);

            }
            else
            {
                pa.Position = -1;
                _gameRecord.Actions.Add(pa);
                _gameState.UpdateByAction(pa, GameDef);
            }
            return true;
        }
Example #14
0
        /// <summary>
        /// Returns an array containing enumerated combinations.
        /// </summary>
        public static CardSet[] Combin(DeckDescriptor deckDescr, int count, CardSet sharedCards, CardSet deadCards)
        {
            CardSet           unused    = deadCards | sharedCards;
            int               combCount = (int)EnumAlgos.CountCombin(deckDescr.Size - unused.CountCards(), count);
            CombinArrayParams p         = new CombinArrayParams();

            p.arr = new CardSet[combCount];
            Combin(deckDescr, count, sharedCards, deadCards, OnCombinArray, p);
            return(p.arr);
        }