public static ulong OutsMask(ulong player, ulong board, params ulong[] opponents)
{
ulong retval = 0UL;
#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");
#endif
// Get original mask value
uint playerOrigHandVal = Hand.Evaluate(player | board);
// Look ahead one card
foreach (ulong card in Hand.Hands(0UL, board | player, 1))
{
// Get new mask value
uint playerNewHandVal = Hand.Evaluate(player | board | card);
// Get new board value
uint boardHandVal = Hand.Evaluate(board | card);
// Is the new mask better than the old one?
bool handImproved = playerNewHandVal > playerOrigHandVal;
// This compare ensures we move up in mask type.
bool handStrongerThanBoard = Hand.HandType(playerNewHandVal) > Hand.HandType(boardHandVal) ||
(Hand.HandType(playerNewHandVal) == Hand.HandType(boardHandVal) &&
Hand.TopCard(playerNewHandVal) > Hand.TopCard(boardHandVal));
// Check against opponents cards
bool handBeatAllOpponents = true;
if (handImproved && handStrongerThanBoard && opponents != null && opponents.Length > 0)
{
foreach (ulong opponent in opponents)
{
uint opponentHandVal = Hand.Evaluate(opponent | board | card);
if (opponentHandVal > playerNewHandVal)
{
handBeatAllOpponents = false;
break;
}
}
}
// If the mask improved then we have an out
if (handImproved && handStrongerThanBoard && handBeatAllOpponents)
{
// Add card to outs mask
retval |= card;
}
}
// return outs as a mask mask
return retval;
}