Example #1
0
    public bool Play(Card card)
    {
        if (_hand.Contains(card))
        {
            _hand.Remove(card);
            _grave.Add(card);
            EventManager.Instance.QueueEvent(new Evt_PlayedCard()
            {
                Owner = Owner, Card = card
            });
            return(true);
        }

        return(false);
    }
Example #2
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;
        }
Example #3
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 #4
0
            public void Resolve(IReactionScope scope)
            {
                var revealedTreasures = new CardSet();

                2.Times(() =>
                {
                    var revealedCard = scope.RevealCardFromDeck();
                    if (revealedCard.IsTreasure && !revealedTreasures.Contains(revealedCard))
                    {
                        revealedTreasures.Add(revealedCard, scope);
                    }
                });
                if (revealedTreasures.Count() == 1)
                {
                    scope.Publish(new TrashTreasureCardFromThief(TurnScope, scope, revealedTreasures.Single()));
                }
                else if (revealedTreasures.Count() == 2)
                {
                    TurnScope.Publish(new ChooseTreasureCardToTrashFromThief(TurnScope, scope, revealedTreasures));
                }
            }
        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 #6
0
    public int Best()
    {
        Sort(Order.ASC);

        CardSet oneSetCards  = new CardSet();
        CardSet twoSetsCards = new CardSet();

        ClassifyCards(ref oneSetCards, ref twoSetsCards);

        int bestScore = 1000;

        // There is at least one card which is in two sets.
        if (twoSetsCards.Length() > 0)
        {
            int tmpScore = 0;
            for (int i = 0; i < twoSetsCards.Length(); i++)
            {
//				Debug.Log ("Rank set:" + ToCardString ());
                // First check same rank set.
                CardSet rankSet = FindRankSetCombination((PhomCard)twoSetsCards.At(i));

                List <int> overlappedIndice = new List <int> ();
                if (rankSet.Length() == 4)
                {
                    for (int j = 0; j < twoSetsCards.Length(); j++)
                    {
                        if (i != j && rankSet.Contains(twoSetsCards.At(j)))
                        {
                            overlappedIndice.Add(j);
                            break;
                        }
                    }
                }

                // Two cards in the same rank set. Quad set.
                if (overlappedIndice.Count > 0)
                {
                    for (int m = 0; m < overlappedIndice.Count; m++)
                    {
                        // Keep all in the rank set.
                        if (BestSubHand(rankSet, -1, ref bestScore))
                        {
                            return(0);
                        }

                        // Remove the overlapped out of rank set.
                        if (BestSubHand(rankSet, overlappedIndice [m], ref bestScore))
                        {
                            return(0);
                        }
                    }
                }
                else
                {
                    if (BestSubHand(rankSet, -1, ref bestScore))
                    {
                        return(0);
                    }
                }


                // Check straight set.
//				Debug.Log ("Straight set:" + ToCardString ());
                CardSet straightSet = FindStraightCombination((PhomCard)twoSetsCards.At(i));
//				Debug.Log ("Straight set2:" + straightSet.ToCardString ());
                int mainIndex = straightSet.cards.IndexOf(twoSetsCards.At(i));
                overlappedIndice.Clear();

                for (int j = 0; j < twoSetsCards.Length(); j++)
                {
                    if (i != j && straightSet.Contains(twoSetsCards.At(j)))
                    {
                        overlappedIndice.Add(j);
                        break;
                    }
                }

                // Two cards in the same straight.
                if (overlappedIndice.Count > 0)
                {
                    for (int m = 0; m < overlappedIndice.Count; m++)
                    {
                        // Keep the overlapped card in the straight hand <=> remove it from the remaining.
                        if (BestSubHand(straightSet, -1, ref bestScore))
                        {
                            return(0);
                        }

                        // Remove the overlapped card in the set <=> not remove it from the remaining.
                        if ((int)Mathf.Abs(mainIndex - overlappedIndice [m]) > 2)
                        {
                            PhomHand straightHand = new PhomHand(SubSetList(0, numCards));
                            if (mainIndex < overlappedIndice [m])
                            {
                                for (int k = overlappedIndice [m]; k < straightSet.Length(); k++)
                                {
                                    straightHand.RemoveCard(straightSet.At(k));
                                }
                            }
                            else
                            {
                                for (int k = 0; k <= overlappedIndice [m]; k++)
                                {
                                    straightHand.RemoveCard(straightSet.At(k));
                                }
                            }

                            if (CheckBestScore(straightHand, ref bestScore, true))
                            {
                                return(0);
                            }
                        }
                    }
                }
                //
                else
                {
                    if (BestSubHand(straightSet, -1, ref bestScore))
                    {
                        return(0);
                    }
                }
            }
        }
        // No card in two sets.
        else if (oneSetCards.Length() > 0)
        {
            int tmpScore = 0;
//			Debug.Log ("++++++++:" + oneSetCards.ToCardString () + " " + oneSetCards.Length ());
            for (int i = 0; i < oneSetCards.Length(); i++)
            {
                // First check same rank set.
                CardSet rankSet = FindRankSetCombination((PhomCard)oneSetCards.At(i));
//				Debug.Log ("++++++++2:" + rankSet.ToCardString ());
                if (rankSet.Length() > 0 && BestSubHandWithNoCardInTwoSet(rankSet, ref bestScore))
                {
                    return(0);
                }

                // Check straight set.
                CardSet straightSet = FindStraightCombination((PhomCard)oneSetCards.At(i));
//				Debug.Log ("Set one: straight set:" + straightSet.ToCardString ());
                if (straightSet.Length() > 0 && BestSubHandWithNoCardInTwoSet(straightSet, ref bestScore))
                {
                    return(0);
                }
            }
        }
        else
        {
//			Debug.Log ("no set found:" + ToCardString ());
            singleCards.cards.AddRange(cards);
            if (CheckBestScore(this, ref bestScore, false))
            {
                return(0);
            }
        }

//		Debug.Log ("bestScore:" + bestScore);
        return(bestScore);
    }