/// <summary>
        /// Sets the defaults.
        /// </summary>
        /// <param name="setBarDefaults">if set to <c>true</c> [set bar defaults].</param>
        protected override void SetDefaults(bool setBarDefaults)
        {
            base.SetDefaults(setBarDefaults);

            _MarksColor = Color.Empty;
            _MarksWidth = 1;

            _HourColor       = Color.Empty;
            _HourType        = HandTypes.Line;
            _HourLengthBegin = _DefaultHourLengthBegin;
            _HourLengthEnd   = _DefaultHourLengthEnd;
            _HourWidth       = _DefaultHourWidth;

            _MinuteColor       = Color.Empty;
            _MinuteType        = HandTypes.Line;
            _MinuteLengthBegin = _DefaultMinuteLengthBegin;
            _MinuteLengthEnd   = _DefaultMinuteLengthEnd;
            _MinuteWidth       = _DefaultMinuteWidth;
            _SpeedRatio        = 4;

            if (Bar != null)
            {
                _MarksColor  = Bar.ForeColor;
                _HourColor   = Bar.ForeColor;
                _MinuteColor = Bar.ForeColor;
            }
        }
Esempio n. 2
0
        public void SetHandShape(HandTypes hand, HandShapeTypes shape)
        {
            if ((hand == HandTypes.Left && _leftShape == shape) ||
                (hand == HandTypes.Right && _rightShape == shape))
            {
                return;
            }

            if (hand == HandTypes.Left)
            {
                _leftShape          = shape;
                _leftReleaseCount   = 0;
                _leftReleaseRunning = (shape == HandShapeTypes.Default);
            }
            else
            {
                _rightShape          = shape;
                _rightReleaseCount   = 0;
                _rightReleaseRunning = (shape == HandShapeTypes.Default);
            }

            int offset = hand == HandTypes.Right ? 5 : 0;

            float[] angles =
                (shape == HandShapeTypes.Default) ? _defaultBendAngles :
                (shape == HandShapeTypes.Rock) ? _rockBendAngles :
                (shape == HandShapeTypes.Scissors) ? _scissorsBendAngles :
                _paperBendAngles;

            for (int i = 0; i < 5; i++)
            {
                _controller.Hold(i + offset, angles[i]);
            }
        }
Esempio n. 3
0
 public Situation(StreetTypes street, HandTypes hand,
                  ChanceTypes chance, int opponents,
                  OpponentActionTypes action, PositionTypes position)
 {
     this.street    = street;
     this.hand      = hand;
     this.chance    = chance;
     this.opponents = opponents;
     this.action    = action;
     this.position  = position;
 }
Esempio n. 4
0
        public static List <Rule> readRules()
        {
            Log.Info("Reading spreadsheet '" + RULES_XLS + "'");
            Workbook    workbook  = Workbook.Load(RULES_XLS);
            Worksheet   worksheet = workbook.Worksheets[0];
            List <Rule> rules     = new List <Rule>();
            int         row       = 1;

            while (true)
            {
                // check
                if (isEmptyRow(worksheet, row))
                {
                    break;
                }
                Log.DebugIf(row % 100 == 0, "Reading row '" + (row + 1) + "'");

                // columns
                string hand     = worksheet.Cells[row, 2].StringValue;
                string street   = worksheet.Cells[row, 3].StringValue;
                string pot      = worksheet.Cells[row, 4].StringValue;
                string board    = worksheet.Cells[row, 5].StringValue;
                string opps     = worksheet.Cells[row, 6].StringValue;
                string action   = worksheet.Cells[row, 7].StringValue;
                string position = worksheet.Cells[row, 8].StringValue;
                string maxbet   = worksheet.Cells[row, 9].StringValue;
                string potsize  = worksheet.Cells[row, 10].StringValue;
                string decision = worksheet.Cells[row, 11].StringValue;

                // map
                StreetTypes         streetType   = mapStreetType(street);
                HandTypes           handType     = mapHandType(hand);
                ChanceTypes         chanceType   = mapChanceType(board);
                int                 minOpponents = mapMinOpponents(opps);
                int                 maxOpponents = mapMaxOpponents(opps);
                OpponentActionTypes actionType   = mapActionType(action);
                PositionTypes       positionType = mapPositionType(position);
                double              minMaxBet    = mapMinInterval(maxbet);
                double              maxMaxBet    = mapMaxInterval(maxbet);
                double              minPotSize   = mapMinInterval(potsize);
                double              maxPotSize   = mapMaxInterval(potsize);

                // rule
                Rule rule = new Rule(streetType, handType, chanceType, minOpponents,
                                     maxOpponents, actionType, positionType, minMaxBet, maxMaxBet,
                                     minPotSize, maxPotSize, decision);
                rules.Add(rule);

                // next
                row++;
            }
            Log.Info("Done reading spreadsheet");
            return(rules);
        }
Esempio n. 5
0
        public MadeHand(HandTypes type, Card[] played, Dictionary <Card, List <Card> > alternates = null)
        {
            Guards.ArgumentSuccess(type.IsValid(), nameof(type));
            Guards.ArgumentSuccess(played != null && played.Length == 5, nameof(played));

            Type       = type;
            Played     = played;
            Alternates = alternates;

            ScoreHand();
        }
Esempio n. 6
0
 public Rule(StreetTypes street, HandTypes hand,
             ChanceTypes chance, int minOpps, int maxOpps,
             OpponentActionTypes action)
 {
     this.street   = street;
     this.hand     = hand;
     this.chance   = chance;
     this.minOpps  = minOpps;
     this.maxOpps  = maxOpps;
     this.action   = action;
     this.decision = NO_RULE;
 }
 public static string GetHandName(HandTypes handTypes)
 {
     string text = handTypes.ToString();
     if (string.IsNullOrWhiteSpace(text))
         return "";
     StringBuilder newText = new StringBuilder(text.Length * 2);
     newText.Append(text[0]);
     for (int i = 1; i < text.Length; i++) {
         if (char.IsUpper(text[i]) && text[i - 1] != ' ')
             newText.Append(' ');
         newText.Append(text[i]);
     }
     return newText.ToString().ToLower();
 }
Esempio n. 8
0
 public static int PointTopHand(HandTypes handType)
 {
     return(handType switch
     {
         HandTypes.HighCard => 0,
         HandTypes.Pair => 0,
         HandTypes.TwoPair => 1,
         HandTypes.Trips => 2,
         HandTypes.Straight => 3,
         HandTypes.Flush => 3,
         HandTypes.FullHouse => 4,
         HandTypes.FourOfAKind => 6,
         HandTypes.StraightFlush => 12,
         _ => 0
     });
Esempio n. 9
0
		public static HandAnalysis evalHandSmart(List<Card> hand, List<Card> board)
		{
            // preflop
            if(board.Count == 0)
            {
                Log.Fine("evaluating preflop cards -> {" + map(hand) + "}");
    			HandTypes smart = SmartEvaluator.evalHand(map(hand));
    			return new HandAnalysis(smart);
            }
			// postflop
            else
            {
                Log.Fine("evaluating postflop cards -> {" + map(hand) + "}  {" + map(board) + "}");
    			Hand.HandTypes basic = evalHand(hand, board).HandTypeValue;
    			HandTypes smart = SmartEvaluator.evalHand(basic, map(hand), map(board));
                ChanceTypes chance = SmartEvaluator.evalChance(hand, smart, map(board));
    			return new HandAnalysis(basic, smart, chance);
            }
		}
        /// <summary>
        /// Copies the this.
        /// </summary>
        /// <param name="o">The o.</param>
        private void CopyThis(ZeroitBusyBarPainterClock o)
        {
            _Preset = o._Preset;

            _MarksColor = o._MarksColor;
            _MarksWidth = o._MarksWidth;

            _HourColor       = o._HourColor;
            _HourType        = o._HourType;
            _HourLengthBegin = o._HourLengthBegin;
            _HourLengthEnd   = o._HourLengthEnd;
            _HourWidth       = o._HourWidth;

            _MinuteColor       = o._MinuteColor;
            _MinuteType        = o._MinuteType;
            _MinuteLengthBegin = o._MinuteLengthBegin;
            _MinuteLengthEnd   = o._MinuteLengthEnd;
            _MinuteWidth       = o._MinuteWidth;
            _SpeedRatio        = o._SpeedRatio;
        }
Esempio n. 11
0
 public Rule(StreetTypes street, HandTypes hand,
             ChanceTypes chance, int minOpps, int maxOpps,
             OpponentActionTypes action,
             PositionTypes position,
             double minMaxBet, double maxMaxBet,
             double minPotSize, double maxPotSize,
             string decision)
 {
     this.street     = street;
     this.hand       = hand;
     this.chance     = chance;
     this.minOpps    = minOpps;
     this.maxOpps    = maxOpps;
     this.action     = action;
     this.position   = position;
     this.minMaxBet  = minMaxBet;
     this.maxMaxBet  = maxMaxBet;
     this.minPotSize = minPotSize;
     this.maxPotSize = maxPotSize;
     this.decision   = decision;
 }
Esempio n. 12
0
        public Rule findRule(StreetTypes street, HandTypes hand,
                             ChanceTypes chance, int opponents,
                             OpponentActionTypes action,
                             PositionTypes position,
                             double maxBet, double potSize)
        {
            // hash
            int hash = getHashCode(street, hand, chance, opponents, action, position);

            if (!rules.ContainsKey(hash))
            {
                Log.Debug("cannot find rule for this constellation -> "
                          + describe(street, hand, chance, opponents, action));
                return(new Rule(street, hand, chance, opponents, opponents, action));
            }

            // intervals
            MaxBetDictionary  maxBetDict  = rules[hash];
            PotSizeDictionary potSizeDict = maxBetDict.getByInterval(maxBet);
            Rule rule = potSizeDict.getByInterval(potSize);

            return(rule);
        }
Esempio n. 13
0
    public void SwitchHand(HandTypes newType)
    {
        switch (newType)
        {
        case HandTypes.Default:
            handDefault.SetActive(true);
            handGrab.SetActive(false);
            handPoint.SetActive(false);
            break;

        case HandTypes.Grab:
            handDefault.SetActive(false);
            handGrab.SetActive(true);
            handPoint.SetActive(false);
            break;

        case HandTypes.Point:
            handDefault.SetActive(false);
            handGrab.SetActive(false);
            handPoint.SetActive(true);
            break;
        }
    }
Esempio n. 14
0
        private int getHashCode(StreetTypes street, HandTypes hand,
                                ChanceTypes chance, int opponents,
                                OpponentActionTypes action,
                                PositionTypes position)
        {
            // ints
            int streetNum = (int)street;
            int handNum   = (int)hand;
            int chanceNum = (int)chance;
            int actionNum = (int)action;
            int posNum    = (int)position;

            // bits
            int bits = (streetNum & mask(4));

            bits |= (handNum & mask(6)) << 4;
            bits |= (chanceNum & mask(4)) << 10;
            bits |= (opponents & mask(4)) << 14;
            bits |= (actionNum & mask(4)) << 18;
            bits |= (posNum & mask(2)) << 22;

            // hash
            return(bits);
        }
Esempio n. 15
0
 /// <exclude/>
 private static uint HANDTYPE_VALUE(HandTypes ht)
 {
     return (((uint)ht) << HANDTYPE_SHIFT);
 }
Esempio n. 16
0
        public static ChanceTypes evalChance(List <Card> hand, HandTypes smart, string board)
        {
            // parse board hand
            string[] BoardSuits = getBoardSuits(board);
            int[]    BoardRanks = getBoardRanks(board);
            Array.Sort(BoardRanks);

            // pairs
            Pairs pairs = boardPairs(BoardRanks);

            // straight dangers
            int maxConnected  = 1;
            int tempConnected = 1;
            int Holes         = 0;

            for (int i = 1; i < BoardRanks.Length; i++)
            {
                if (BoardRanks[i] == BoardRanks[i - 1] + 1 && Holes < 2)
                {
                    tempConnected++;
                    if (maxConnected < tempConnected)
                    {
                        maxConnected = tempConnected;
                    }
                    ;
                }
                else if (BoardRanks[i] == BoardRanks[i - 1] + 2 && Holes < 1)
                {
                    tempConnected++;
                    Holes++;
                    if (maxConnected < tempConnected)
                    {
                        maxConnected = tempConnected;
                    }
                    ;
                }
                else
                {
                    if (maxConnected < tempConnected)
                    {
                        maxConnected = tempConnected;
                    }
                    ;
                    Holes         = 0;
                    tempConnected = 1;
                }
            }


            // ############################ BOARD TYPE ######################################
            int[] SuitCount = { 0, 0, 0, 0 };
            foreach (string s in BoardSuits)
            {
                if (s == "h")
                {
                    SuitCount[0]++;
                }
                else if (s == "d")
                {
                    SuitCount[1]++;
                }
                else if (s == "c")
                {
                    SuitCount[2]++;
                }
                else if (s == "s")
                {
                    SuitCount[3]++;
                }
            }
            Array.Sort(SuitCount);

            if (SuitCount[3] > 3 || pairs.BoardTwoPaired || (maxConnected > 3 && Holes == 0) || maxConnected > 4)
            {
                return(ChanceTypes.Extreme);
            }
            else if (SuitCount[3] == 3 || maxConnected > 3)
            {
                // opponent could have hit flush
                return(ChanceTypes.GotHit);
            }
            else if (pairs.BoardPaired)
            {
                // opponent could have trips/full house
                if (smart == HandTypes.Trips || smart == HandTypes.Straight)
                {
                    // we got trips/full house
                    return(ChanceTypes.Safe);
                }
                else if (smart == HandTypes.AA_KK)
                {
                    // if low boardpair, still safe for AA/KK
                    if (pairs.FirstPair < JACK)
                    {
                        return(ChanceTypes.Safe);
                    }
                    ;
                    return(ChanceTypes.GotHit);
                }
                else
                {
                    return(ChanceTypes.GotHit);
                }
            }
            else if (BoardRanks.Length == 5)
            {
                return(ChanceTypes.Safe);
            }
            else if (SuitCount[3] == 2)
            {
                return(ChanceTypes.Draws);
            }
            else
            {
                return(ChanceTypes.Safe);
            }
        }
Esempio n. 17
0
        // TODO: Add IHandTypes dependancy injection

        public AILogicProvider()
        {
            this.handType = new HandTypes();
        }
Esempio n. 18
0
 public HandEvaluation(ulong cards, HandTypes type, uint value)
 {
   Cards = cards;
   Type = type;
   Value = value;
 }
Esempio n. 19
0
 public static bool IsValid(this HandTypes type)
 {
     return(Enum.IsDefined(typeof(HandTypes), type));
 }
        /// <summary>
        /// Sets from preset.
        /// </summary>
        /// <param name="setBarDefaults">if set to <c>true</c> [set bar defaults].</param>
        private void SetFromPreset(bool setBarDefaults)
        {
            switch (_Preset)
            {
            case Presets.None:

                SetDefaults(setBarDefaults);

                break;

            case Presets.Watch:

                SetDefaults(setBarDefaults);

                if (Bar != null)
                {
                    Bar.CornerRadius = 70;
                    Bar.Maximum      = 400;
                }

                _MarksColor = Color.Orange;
                _MarksWidth = 10;

                _HourType        = HandTypes.Pie;
                _HourLengthBegin = -20;
                _HourLengthEnd   = 50;
                _HourColor       = Color.Gold;
                _HourWidth       = 20;

                _MinuteType        = HandTypes.Pie;
                _MinuteLengthBegin = -10;
                _MinuteLengthEnd   = 90;
                _MinuteColor       = Color.Orange;
                _MinuteWidth       = 10;

                _SpeedRatio = 12;

                break;

            case Presets.Circle:

                SetDefaults(setBarDefaults);

                if (Bar != null)
                {
                    Bar.CornerRadius = 100;
                    Bar.Maximum      = 400;
                    Bar.Reverse      = true;
                }

                _MarksColor = Color.Blue;
                _MarksWidth = 3;

                _HourType        = HandTypes.Pie;
                _HourLengthBegin = -20;
                _HourLengthEnd   = 40;
                _HourColor       = Color.DarkBlue;
                _HourWidth       = 20;

                _MinuteType        = HandTypes.Pie;
                _MinuteLengthBegin = 30;
                _MinuteLengthEnd   = 90;
                _MinuteColor       = Color.Red;
                _MinuteWidth       = 10;

                _SpeedRatio = 12;

                break;

            default:
                Debug.Assert(false);
                break;
            }
        }
Esempio n. 21
0
 public HandAnalysis(Hand.HandTypes basic, HandTypes smart, ChanceTypes chance)
 {
     this.basic  = basic;
     this.smart  = smart;
     this.chance = chance;
 }
Esempio n. 22
0
 public static void SayAsnc(Settings settings, HandTypes hand)
 {
     SayAsnc(settings, HandTypesText.Texts[(int)hand]);
 }
Esempio n. 23
0
        public void handranker_testhands_ranking(string communityCards, string playerCards, HandTypes ranking)
        {
            Hand     hand       = new Hand(communityCards, playerCards);
            HandRank handRanker = new HandRank();

            handRanker.Run(hand);

            Assert.That(handRanker.Ranking, Is.EqualTo(ranking));
        }
Esempio n. 24
0
 public HandAnalysis(HandTypes smart)
 {
     this.smart = smart;
 }
Esempio n. 25
0
        /// <summary>
        /// Returns a factor which determines how much of a bet a player should get 
        /// back, according to the outcome of the round.
        /// </summary>
        /// <param name="dealerPlayer">The player representing the dealer.</param>
        /// <param name="player">The player for whom we calculate the factor.</param>
        /// <param name="currentHand">The hand to calculate the factor for.</param>
        /// <returns></returns>
        private float CalculateFactorForHand(BlackjackPlayer dealerPlayer,
            BlackjackPlayer player, HandTypes currentHand)
        {
            float factor;

            bool blackjack, bust, considerAce;
            int playerValue;
            player.CalculateValues();

            // Get some player status information according to the desired hand
            switch (currentHand)
            {
                case HandTypes.First:
                    blackjack = player.BlackJack;
                    bust = player.Bust;
                    playerValue = player.FirstValue;
                    considerAce = player.FirstValueConsiderAce;
                    break;
                case HandTypes.Second:
                    blackjack = player.SecondBlackJack;
                    bust = player.SecondBust;
                    playerValue = player.SecondValue;
                    considerAce = player.SecondValueConsiderAce;
                    break;
                default:
                    throw new Exception(
                        "Player has an unsupported hand type.");
            }

            if (considerAce)
            {
                playerValue += 10;
            }


            if (bust)
            {
                factor = -1; // Bust
            }
            else if (dealerPlayer.Bust)
            {
                if (blackjack)
                {
                    factor = 1.5f; // Win BlackJack
                }
                else
                {
                    factor = 1; // Win
                }
            }
            else if (dealerPlayer.BlackJack)
            {
                if (blackjack)
                {
                    factor = 0; // Push BlackJack
                }
                else
                {
                    factor = -1; // Lose BlackJack
                }
            }
            else if (blackjack)
            {
                factor = 1.5f;
            }
            else
            {
                int dealerValue = dealerPlayer.FirstValue;

                if (dealerPlayer.FirstValueConsiderAce)
                {
                    dealerValue += 10;
                }

                if (playerValue > dealerValue)
                {
                    factor = 1; // Win
                }
                else if (playerValue < dealerValue)
                {
                    factor = -1; // Lose
                }
                else
                {
                    factor = 0; // Push
                }
            }
            return factor;
        }
Esempio n. 26
0
        /// <summary>
        /// The method returns the number of draws that are possible for the
        /// specified HandType.
        /// </summary>
        /// <param name="player">Two card mask making up the players pocket cards</param>
        /// <param name="board">The community cards</param>
        /// <param name="dead">Dead cards</param>
        /// <param name="type">They type of mask to count draws for.</param>
        /// <returns>The number of draws for this mask type.</returns>
        public static int DrawCount(string player, string board, string dead, HandTypes type)
        {
#if DEBUG
            if (!ValidateHand(player)) throw new ArgumentException("player fails to Validate");
            if (!ValidateHand(board)) throw new ArgumentException("board fails to Validate");
#endif
            return DrawCount(ParseHand(player), ParseHand(board), ParseHand(dead), type);
        }
Esempio n. 27
0
        /// <summary>
        /// The method returns the number of draws that are possible for the
        /// specified HandType. Note that DrawCount(pocket, board, dead, type) is not
        /// necessarily the same as DrawCount(pocket | board, dead, type). 
        /// 
        /// This method returns all possible draws that are the same as the requested type.
        /// </summary>
        /// <param name="mask">Hand</param>
        /// <param name="dead">Dead cards</param>
        /// <param name="type">They type of mask to count draws for.</param>
        /// <returns>The number of draws for this mask type.</returns>
        public static int DrawCount(ulong mask, ulong dead, HandTypes type)
        {
            var retval = 0;
#if DEBUG
            if (BitCount(mask) >= 7) throw new ArgumentException("mask must contain less than 7 cards");
            if ((mask & dead) != 0UL) throw new ArgumentException("mask must not contain dead cards");
#endif
            // Get original mask type
            var playerOrigHandType = EvaluateType(mask);

            if (playerOrigHandType >= type) return 0;

            // Look ahead one card
            foreach (var card in Hands(0UL, mask | dead, 1))
            {
                // Get new mask value
                var playerNewHandType = EvaluateType(mask | card);

                // If the mask improved and it matches the specified type, count it.
                if (playerNewHandType > playerOrigHandType && playerNewHandType == type)
                {
                    retval++;
                }
            }

            return retval;
        }
Esempio n. 28
0
 private string describe(StreetTypes street, HandTypes hand,
                         ChanceTypes chance, int opponents,
                         OpponentActionTypes action)
 {
     return(hand + " " + street + " " + chance + " " + opponents + " " + action);
 }
Esempio n. 29
0
        /// <summary>
        /// Returns a factor which determines how much of a bet a player should get
        /// back, according to the outcome of the round.
        /// </summary>
        /// <param name="dealerPlayer">The player representing the dealer.</param>
        /// <param name="player">The player for whom we calculate the factor.</param>
        /// <param name="currentHand">The hand to calculate the factor for.</param>
        /// <returns></returns>
        private float CalculateFactorForHand(BlackjackPlayer dealerPlayer,
                                             BlackjackPlayer player, HandTypes currentHand)
        {
            float factor;

            bool blackjack, bust, considerAce;
            int  playerValue;

            player.CalculateValues();

            // Get some player status information according to the desired hand
            switch (currentHand)
            {
            case HandTypes.First:
                blackjack   = player.BlackJack;
                bust        = player.Bust;
                playerValue = player.FirstValue;
                considerAce = player.FirstValueConsiderAce;
                break;

            case HandTypes.Second:
                blackjack   = player.SecondBlackJack;
                bust        = player.SecondBust;
                playerValue = player.SecondValue;
                considerAce = player.SecondValueConsiderAce;
                break;

            default:
                throw new Exception(
                          "Player has an unsupported hand type.");
            }

            if (considerAce)
            {
                playerValue += 10;
            }


            if (bust)
            {
                factor = -1; // Bust
            }
            else if (dealerPlayer.Bust)
            {
                if (blackjack)
                {
                    factor = 1.5f; // Win BlackJack
                }
                else
                {
                    factor = 1; // Win
                }
            }
            else if (dealerPlayer.BlackJack)
            {
                if (blackjack)
                {
                    factor = 0; // Push BlackJack
                }
                else
                {
                    factor = -1; // Lose BlackJack
                }
            }
            else if (blackjack)
            {
                factor = 1.5f;
            }
            else
            {
                int dealerValue = dealerPlayer.FirstValue;

                if (dealerPlayer.FirstValueConsiderAce)
                {
                    dealerValue += 10;
                }

                if (playerValue > dealerValue)
                {
                    factor = 1; // Win
                }
                else if (playerValue < dealerValue)
                {
                    factor = -1; // Lose
                }
                else
                {
                    factor = 0; // Push
                }
            }
            return(factor);
        }
Esempio n. 30
0
        // TODO: Add IHandTypes dependancy injection

        public AILogicProvider()
        {
            this.handType = new HandTypes();
        }
Esempio n. 31
0
        /// <summary>
        /// The method returns the number of draws that are possible for the
        /// specified HandType. This method only returns the counts that improve the 
        /// player's mask rather than just the board. Because of this subtle distinction,
        /// DrawCount(player, board, dead, type) doesn't necessarily return the same value as
        /// DrawCount(player | board, dead, type).
        /// </summary>
        /// <param name="player">Two card mask making up the players pocket cards</param>
        /// <param name="board">The community cards</param>
        /// <param name="dead">Dead cards</param>
        /// <param name="type">They type of mask to count draws for.</param>
        /// <returns>The number of draws for this mask type.</returns>
        public static int DrawCount(ulong player, ulong board, ulong dead, HandTypes type)
        {
            var retval = 0;
#if DEBUG
            if (BitCount(player) != 2) throw new ArgumentException("player must have exactly 2 cards");
            if (BitCount(board) != 3 && BitCount(board) != 4) throw new ArgumentException("board must contain 3 or 4 cards");
            if (((board | player) & dead) != 0UL) throw new ArgumentException("player and board must not contain dead cards");
#endif
            // Get original mask value
            var playerOrigHandVal = Evaluate(player | board);

            if (HandType(playerOrigHandVal) > (uint)type)
                return 0;

            // Look ahead one card
            foreach (var card in Hands(0UL, board | player | dead, 1))
            {
                // Get new mask value
                var playerNewHandVal = Evaluate(player | board | card);

                // Get new board value
                var boardHandVal = Evaluate(board | card);

                // Is the new mask better than the old one? We don't 
                // want to know about supersizing the kickers so this
                // ensures that mask moved up in mask type.
                var handImproved = HandType(playerNewHandVal) > HandType(playerOrigHandVal);

                // This compare ensures we aren't just making the board stronger
                var handStrongerThanBoard = playerNewHandVal > boardHandVal;

                // If the mask improved and it matches the specified type, return true
                if (handImproved && handStrongerThanBoard && HandType(playerNewHandVal) == (int)type)
                {
                    retval++;
                }
            }

            return retval;
        }