Exemple #1
0
        private bool IsCardHigher(int card, int highestCard)
        {
            int suit        = BitwiseCardHelper.GetSuitAsBits(card);
            int highestSuit = BitwiseCardHelper.GetSuitAsBits(highestCard);

            if (suit == highestSuit)
            {
                return((uint)card > (uint)highestCard);
            }

            int trumpSuit = mContext.TrumpSuit;

            if (trumpSuit != 0)
            {
                if ((suit == trumpSuit) && (highestSuit != trumpSuit))
                {
                    return(true);
                }

                if ((suit != trumpSuit) && (highestSuit == trumpSuit))
                {
                    return(false);
                }
            }

            return(false);
        }
Exemple #2
0
        internal void DoMove(Move move)
        {
            // Register the move.
            ActiveHand.Move = move;
            // Remove the played card from the player's cards.
            ActiveHand.Cards &= ~move.Card;

            // Update the leading suit.
            if (mLeadingSuit == 0)
            {
                mLeadingSuit = BitwiseCardHelper.GetSuitAsBits(move.Card);
            }

            ActivateNextHand();

            // If the next player has already played a card, then the trick is over.
            if (ActiveHand.Move.Card != 0)
            {
                mActiveIndex = GetTrickWinner();
                ActiveHand.Tricks++;

                for (int i = 0; i < HandCount; i++)
                {
                    mDiscards     |= mHands[i].Move.Card;
                    mHands[i].Move = Move.Empty;
                }

                mLeadingSuit = 0;
            }
        }
        private double GetFailureProbabilityForSuit(int cards, int discards, CardSuit suit)
        {
            int cardSet                = BitwiseCardHelper.GetCardSet(cards, suit);
            int discardsCount          = BitwiseCardHelper.GetSuitCount(discards, suit);
            int otherSuitsDistribution = CardSuitDistribution.GetDistribution(cards, discards, suit);

            return(MisereProbabilities.GetFailureProbability(cardSet, discardsCount, otherSuitsDistribution, IsFirstHand));
        }
Exemple #4
0
        internal HandState(Hand source)
        {
            Cards = BitwiseCardHelper.CardCollectionToBits(source.Cards);

            if (source.PlayedCard.HasValue)
            {
                Move = new Move(BitwiseCardHelper.CardToBits(source.PlayedCard.Value));
            }

            Tricks = source.Tricks;
        }
Exemple #5
0
        internal PlayingContext(Game game)
        {
            Game = game;

            if (game.GameType != GameType.AllPass)
            {
                mDeclarerIndex = game.Declarer.Index;
            }

            TrumpSuit   = BitwiseCardHelper.SuitToBits(game.BiddingContext.TrumpSuit);
            InitialSuit = BitwiseCardHelper.SuitToBits(game.PlayingContext.InitialSuit);

            SetStateEvaluator();
        }
Exemple #6
0
        internal PlayingState(PlayingContext context)
        {
            mContext = context;

            Game game = context.Game;

            for (int i = 0; i < HandCount; i++)
            {
                mHands[i] = new HandState(game.GetHand(i));
            }

            mActiveIndex = game.ActiveHand.Index;
            mDiscards    = BitwiseCardHelper.CardCollectionToBits(game.PlayingContext.Discards);
            mLeadingSuit = context.InitialSuit;
        }
Exemple #7
0
        private double EvaluateDiscards(int cards)
        {
            Debug.Assert(BitwiseCardHelper.GetCardCount(cards) == 12);

            var values = new List <double>();

            var enumerator = new TwoCardsEnumerator(cards);

            while (enumerator.MoveNext())
            {
                int    cardsAfterDiscarding = cards & ~enumerator.Current;
                double value = EvaluateCards(cardsAfterDiscarding, enumerator.Current);
                values.Add(value);
            }

            return(values.Max());
        }
        internal Card PlayCard()
        {
            var context   = new PlayingContext(mGame);
            var rootState = new PlayingState(context);

            var validMoves = rootState.GetValidMoves();

            // Exit if only one move is possible.
            if (BitwiseCardHelper.GetGroupCount(validMoves) == 1)
            {
                return(GetRandomCard(validMoves));
            }

            bool isCheater = (mGame.Options.DifficultyLevel == GameDifficultyLevel.Cheater);
            var  bestNode  = TreeSearcher.Search(rootState, 100000, !isCheater);

            return(GetRandomCard(bestNode.Move.Group));
        }
        protected override double EvaluateCards(int cards, int discards)
        {
            Debug.Assert(BitwiseCardHelper.GetCardCount(cards) == 10);

            int trumpCount = BitwiseCardHelper.GetSuitCount(cards, mTrumpSuit);

            // Don't consider trump game if the number of trumps is less than 4.
            // TODO Consider 3-3-3-1.
            if (trumpCount < 4)
            {
                return(double.MinValue);
            }

            IEnumerable <TrickProbability> totalProbabilities = Enumerable.Empty <TrickProbability>();

            // Calculate sum of tricks with corresponding probabilities in all suits.
            for (var suit = CardSuit.Spades; suit <= CardSuit.Hearts; suit++)
            {
                int cardSet = BitwiseCardHelper.GetCardSet(cards, suit);
                IEnumerable <TrickProbability> probabilities = TrickPlayProbabilities.GetTrickProbabilities(cardSet);

                // Combine probabilities..
                totalProbabilities = totalProbabilities.Combine(probabilities);
            }

            bool isEasyLevel = (Game.Options.DifficultyLevel == GameDifficultyLevel.Beginner) ||
                               (Game.Options.DifficultyLevel == GameDifficultyLevel.Amateur);

            // The following stuff is too complex for weak players.
            if (!isEasyLevel)
            {
                totalProbabilities = ConsiderTrumpAdvancing(totalProbabilities);
                totalProbabilities = ConsiderTrickTaking(totalProbabilities);
            }

            return(totalProbabilities.Expectation(
                       tricks => Game.Rules.GetGameCost(
                           GameType.TrickPlay,
                           Game.Options.NumberOfPlayers,
                           DeclaredTricks,
                           tricks)));
        }
Exemple #10
0
        /// <summary>
        /// Calculates a mathematical expectation of the active hand for a certain game type.
        /// Uses the expecti-max algorithm to compute the value among all possible widow cards and further discards.
        /// Updates the <see cref="Expectation"/> property.
        /// </summary>
        /// <returns></returns>
        internal void Evaluate()
        {
            int ownCards     = BitwiseCardHelper.CardCollectionToBits(mGame.ActiveHand.Cards);
            int unknownCards = ~ownCards;

            Debug.Assert(BitwiseCardHelper.GetCardCount(unknownCards) == 22);

            var values = new List <double>();

            var enumerator = new TwoCardsEnumerator(unknownCards);

            while (enumerator.MoveNext())
            {
                int    ownCardsWithWidow = ownCards | enumerator.Current;
                double value             = EvaluateDiscards(ownCardsWithWidow);
                values.Add(value);
            }

            Expectation = values.Average();
        }
Exemple #11
0
        private void CalculateCardSets()
        {
            mHandsToRandomize = mState.GetHandsToRandomize();
            int handCount = mHandsToRandomize.Count;

            mCardCounts = new int[handCount];
            mCardSets   = new CardSet[handCount];

            // We know own cards.
            int knownCards = mState.ActiveHand.Cards;

            // We know just played cards.
            for (int i = 0; i < 3; i++)
            {
                if (mState.Hands[i] != mState.ActiveHand)
                {
                    knownCards |= mState.Hands[i].Move.Card;
                }
            }

            // We know discarded cards.
            knownCards |= mState.Discards;

            for (int i = 0; i < handCount; i++)
            {
                int  handIndex = mHandsToRandomize[i];
                Hand hand      = mState.Game.GetHand(handIndex);

                mCardCounts[i] = hand.Cards.Count;

                int cardSet = ~knownCards;
                // Remove suits that the hand is known to miss.
                foreach (var suit in hand.VoidSuits)
                {
                    cardSet &= ~BitwiseCardHelper.SuitToBits(suit);
                }

                mCardSets[i] = new CardSet(cardSet);
            }
        }
Exemple #12
0
 internal void RemoveCards(int cards)
 {
     mCards &= ~cards;
     mCount  = BitwiseCardHelper.GetCardCount(mCards);
 }
Exemple #13
0
 internal CardSet(int cards)
 {
     mCards = cards;
     mCount = BitwiseCardHelper.GetCardCount(cards);
 }
        private static Card GetRandomCard(int cards)
        {
            var cardCollection = BitwiseCardHelper.BitsToCardCollection(cards);

            return(RandomHelper.Select(cardCollection));
        }