internal static string Format(CardMask cardMask, string format, CardFormatInfo cardFormatInfo) { if (string.IsNullOrEmpty(format)) { format = DefaultCardMaskFormat; } return FormatCustomized(cardMask, format, cardFormatInfo); }
private static void FormatAllCards(CardMask cardMask, CardFormatInfo cardFormatInfo, bool isOnePatternAlreadyProcessed, StringBuilder sb, IDeck deck, char patternChar, int num1) { var cardIndexes = cardFormatInfo.Deck.ToCardIndexes(cardMask); var i = 0; foreach (var cardIndex in cardIndexes) { if (i == 0 && isOnePatternAlreadyProcessed) { sb.Append(cardFormatInfo.PatternSeparator); } var rankIndex = deck.ToRankIndex(cardIndex); var suitIndex = deck.ToSuitIndex(cardIndex); switch (patternChar) { case 'i': if (i != 0) { sb.Append(cardFormatInfo.CardIndexesSeparator); } sb.Append(cardIndex.ToString(CultureInfo.CurrentCulture)); break; case 'a': FormatAbbreviatedName(cardFormatInfo, i, sb, rankIndex, suitIndex); break; case 'c': FormatName(cardFormatInfo, i, sb, rankIndex, suitIndex); break; case 'r': case 's': FormatAbbreviatedName2(cardFormatInfo, i, sb, patternChar, rankIndex, suitIndex, num1); break; case 'R': case 'S': FormatName2(cardFormatInfo, i, sb, patternChar, rankIndex, suitIndex, num1); break; default: throw new ArgumentException(patternChar.ToString()); } ++i; } }
private static string FormatCustomized(CardMask cardMask, string format, CardFormatInfo cardFormatInfo) { var deck = cardFormatInfo.Deck; var sb = new StringBuilder(128); var index1 = 0; var isOnePatternAlreadyProcessed = false; while (index1 < format.Length) { var num1 = 1; var patternChar = format[index1]; if (patternChar == 'n') { if (isOnePatternAlreadyProcessed) { sb.Append(cardFormatInfo.PatternSeparator); } sb.Append(((long) cardMask).ToString(CultureInfo.CurrentCulture)); isOnePatternAlreadyProcessed = true; } if (patternChar == 'i' || patternChar == 'a' || patternChar == 'c' || patternChar == 'r' || patternChar == 'R' || patternChar == 's' || patternChar == 'S') { var patternChar2 = ParseNextChar(format, index1); if (((patternChar == 'r' && patternChar2 == 's') || (patternChar == 's' && patternChar2 == 'r')) || ((patternChar == 'R' && patternChar2 == 'S') || (patternChar == 'S' && patternChar2 == 'R'))) { num1 = 2; } FormatAllCards(cardMask, cardFormatInfo, isOnePatternAlreadyProcessed, sb, deck, patternChar, num1); isOnePatternAlreadyProcessed = true; } index1 += num1; } return sb.ToString(); }
internal static CardMask[] GenerateStandardDeckCardMaskTable() { var deck = new StandardDeck(); var cardMaskTable = new CardMask[deck.NoOfCards]; for (var cardIndex = 0; cardIndex != deck.NoOfCards; ++cardIndex) { var cardSuit = deck.ToSuit(deck.ToSuitIndex(cardIndex)); var cardRankIndex = deck.ToRankIndex(cardIndex); CardMask cardMask; switch (cardSuit) { case CardSuit.Hearts: cardMask = (CardMask)((0x1L << cardRankIndex) << 48); break; case CardSuit.Diamonds: cardMask = (CardMask)((0x1L << cardRankIndex) << 32); break; case CardSuit.Clubs: cardMask = (CardMask)((0x1L << cardRankIndex) << 16); break; case CardSuit.Spades: cardMask = (CardMask)(0x1L << cardRankIndex); break; case CardSuit.Undefined: cardMask = CardMask.Empty; break; default: cardMask = CardMask.Empty; break; } cardMaskTable[cardIndex] = cardMask; } return cardMaskTable; }
public override IEnumerable<int> ToCardIndexes(CardMask cardMask) { var cardIndexes = new int[cardMask.NoOfCardsSet()]; var index = 0; var patternMask = (CardMask) 1L; for (var i = 0; i != 64; ++i, patternMask <<= 1) { var tempMask = cardMask & patternMask; if (tempMask == CardMask.Empty) { continue; } for (var cardIndex = 0; cardIndex != CardMaskTable.Length; ++cardIndex) { if (tempMask != CardMaskTable[cardIndex]) { continue; } cardIndexes[index] = cardIndex; ++index; break; } } return cardIndexes; }
public int Evaluate(CardMask cardMask, int noOfCardsToEvaluate) { var handValue = HandValue.NothingHigh; var ss = cardMask.Spades(); var sc = cardMask.Clubs(); var sd = cardMask.Diamonds(); var sh = cardMask.Hearts(); var ranks = sc | sd | sh | ss; var rankCount = BitsTable[ranks]; var duplicateCount = noOfCardsToEvaluate - rankCount; // Check for straight, flush, or straight flush, and return if we can determine // immediately that this is the best possible hand. if (rankCount >= 5) { if (BitsTable[ss] >= 5) { if (StraightTable[ss] != 0) { handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.StraightFlush)) + HandValue.FromTopCardRank(StraightTable[ss]); return handValue; } handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.Flush)) + TopFiveCardsTable[ss]; } else if (BitsTable[sc] >= 5) { if (StraightTable[sc] != 0) { handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.StraightFlush)) + HandValue.FromTopCardRank(StraightTable[sc]); return handValue; } handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.Flush)) + TopFiveCardsTable[sc]; } else if (BitsTable[sd] >= 5) { if (StraightTable[sd] != 0) { handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.StraightFlush)) + HandValue.FromTopCardRank(StraightTable[sd]); return handValue; } handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.Flush)) + TopFiveCardsTable[sd]; } else if (BitsTable[sh] >= 5) { if (StraightTable[sh] != 0) { handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.StraightFlush)) + HandValue.FromTopCardRank(StraightTable[sh]); return handValue; } handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.Flush)) + TopFiveCardsTable[sh]; } else { var straight = StraightTable[ranks]; if (straight != 0) { handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.Straight)) + HandValue.FromTopCardRank(straight); } } // Another win - if there can't be a FH/Quads (duplicateCount < 3), which is true // most of the time when there is a made hand, then if we've found a five card hand, // just return. This skips the whole process of computing two_mask/three_mask/etc. if (handValue != HandValue.NothingHigh && duplicateCount < 3) { return handValue; } } int twoMask, threeMask; // By the time we're here, either: // 1) there's no five-card hand possible (flush or straight), or // 2) there's a flush or straight, but we know that there are enough duplicates // to make a full house or quads possible. switch (duplicateCount) { // It's a no-pair hand. case 0: handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.NoPair)) + TopFiveCardsTable[ranks]; return handValue; // It's a one-pair hand. case 1: twoMask = ranks ^ (sc ^ sd ^ sh ^ ss); handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.OnePair)) + HandValue.FromTopCardRank(TopCardTable[twoMask]); // Only one bit set in two_mask. twoMask ^= ranks; // Get the top five cards in what is left, drop all but the top three cards, // and shift them by one to get the three desired kickers. var kickers = (TopFiveCardsTable[twoMask] >> HandValue.CardBitsWidth) & ~HandValue.FifthCardRankMask; handValue += kickers; return handValue; // Either two pair or trips. case 2: twoMask = ranks ^ (sc ^ sd ^ sh ^ ss); if (twoMask != HandValue.NothingHigh) { handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.TwoPair)) + (TopFiveCardsTable[twoMask] & (HandValue.TopCardRankMask | HandValue.SecondCardRankMask)); // Exactly two bits set in two_mask. twoMask ^= ranks; handValue += HandValue.FromThirdCardRank(TopCardTable[twoMask]); return handValue; } threeMask = ((sc & sd) | (sh & ss)) & ((sc & sh) | (sd & ss)); handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.Trips)) + HandValue.FromTopCardRank(TopCardTable[threeMask]); // Only one bit set in three_mask. threeMask ^= ranks; var secondRank = TopCardTable[threeMask]; handValue += HandValue.FromSecondCardRank(secondRank); threeMask ^= 1 << secondRank; handValue += HandValue.FromThirdCardRank(TopCardTable[threeMask]); return handValue; // Possible quads, fullhouse, straight or flush, or two pair. default: var fourMask = sh & sd & sc & ss; int topCardRank; if (fourMask != HandValue.NothingHigh) { topCardRank = TopCardTable[fourMask]; handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.Quads)) + HandValue.FromTopCardRank(topCardRank); fourMask = ranks ^ (1 << topCardRank); handValue += HandValue.FromSecondCardRank(TopCardTable[fourMask]); return handValue; } // Technically, three_mask as defined below is really the set of bits which // are set in three or four of the suits, but since we've already eliminated // quads, this is OK. Similarly, two_mask is really two_or_four_mask, but // since we've already eliminated quads, we can use this shortcut. twoMask = ranks ^ (sc ^ sd ^ sh ^ ss); if (BitsTable[twoMask] != duplicateCount) { // Must be some trips then, which really means there is a full house // since duplicateCount >= 3. threeMask = ((sc & sd) | (sh & ss)) & ((sc & sh) | (sd & ss)); topCardRank = TopCardTable[threeMask]; handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.FullHouse)) + HandValue.FromTopCardRank(topCardRank); threeMask = (twoMask | threeMask) ^ (1 << topCardRank); handValue += HandValue.FromSecondCardRank(TopCardTable[threeMask]); return handValue; } // flush and straight. if (handValue != HandValue.NothingHigh) { return handValue; } // Must be two pair topCardRank = TopCardTable[twoMask]; handValue = HandValue.FromHandTypeRank(StandardRules.ToHandTypeRank(HandType.TwoPair)) + HandValue.FromTopCardRank(topCardRank); twoMask ^= 1 << topCardRank; secondRank = TopCardTable[twoMask]; handValue += HandValue.FromSecondCardRank(secondRank); twoMask = ranks ^ (1 << topCardRank) ^ (1 << secondRank); handValue += HandValue.FromThirdCardRank(TopCardTable[twoMask]); return handValue; } }
public abstract IEnumerable<int> ToCardIndexes(CardMask cardMask);
public bool TryParseCards(string value, out CardMask cardMask) { var result = Parse(value, false, null, out cardMask); return result; }
static void Main(string[] args) { CardMask cm1 = new CardMask(CardMaskRank.Ace, null); CardMask cm2 = new CardMask(CardMaskRank.HighCard, null); CardMask cm3 = new CardMask(CardMaskRank.Ace, CardMaskSuit.Trump); CardMask cm4 = new CardMask(CardMaskRank.HighCard, CardMaskSuit.Trump); CardsSetMask csm1 = new CardsSetMask(new CardMask[] { cm4, cm2, cm2, cm1 }); CardsSetMask csm2 = new CardsSetMask(new CardMask[] { cm2, cm2, cm2, cm3 }); Combination[] combinations = new Combination[] { new Combination("Москва", new CardsSetMask[] { csm1, csm2 }) }; CombinationsChecker combinationsChecker = new CombinationsChecker(combinations); Suit trump = Suit.Spades; Card[] cards = new Card[] { new Card(Rank.Ten, trump), new Card(Rank.Ten, Suit.Hearts), new Card(Rank.Six, Suit.Hearts), new Card(Rank.Jack, Suit.Diamonds) }; var res = combinationsChecker.GetRealizedCombinations(cards, trump); int sjk = 489; /*bool dsf = MatrixUtils.HasFullDiagonal(new bool[][] { new bool[] { true , true, true }, * new bool[] { true, true , true }, * new bool[] { false, true , false } }); * * int count = 3; * * Card[] ac = new Card[count]; * Card[] dc = new Card[count]; * * bool[][] b = new bool[count][]; * for (int i = 0; i < count; i++) * b[i] = new bool[count]; * * Random r = new Random(); * do * { * Suit trump = (Suit)r.Next(4); * * for (int i = 0; i < count; i++) * { * Card tc; * * do * { * tc = new Card((Rank)r.Next(6, 15), (Suit)r.Next(4)); * } * while (dc.Contains(tc) || ac.Contains(tc)); * ac[i] = tc; * * do * { * tc = new Card((Rank)r.Next(6, 15), (Suit)r.Next(4)); * } * while (dc.Contains(tc) || ac.Contains(tc)); * dc[i] = tc; * } * * for (int i = 0; i < count; i++) * { * for (int j = 0; j < count; j++) * { * b[i][j] = Card.CanBeat(dc[j], ac[i], trump); * } * } * * string log = $"Trump={trump}\n"; * for (int i = -1; i < count; i++) * { * for (int j = -1; j < count; j++) * { * if (i == -1 && j == -1) log += string.Format("{0,17}|", " "); * * if (i == -1 && j != -1) * log += $"{dc[j],17}|"; * * if (j == -1 && i != -1) * log += $"{ac[i],17}|"; * * if (i != -1 && j != -1) * log += string.Format("{0,17}|", b[i][j]); * } * log += "\n"; * } * log += $"does it beat? {MatrixUtils.HasFullDiagonal(b)}\n\n\n"; * * Console.WriteLine(log); * } * while (Console.ReadKey().KeyChar != 'q');*/ }