public HoldemBoard(CardList cardList) : base("Board") { Trace.Assert(cardList.Count >= 3 && cardList.Count <= 5, "Cannot create a holdem board with " + cardList.Count + " cards"); foreach (Card c in cardList) { cards.Add(c); } }
// This window actually never generates a hand protected override Hand CreateHandFromCardList(CardList cardList) { return null; }
private bool IsOpenEndedStraightDraw(CardList cardList) { if (cardList.Count < 4) return false; // Except if the ace is the last card, because there's no cards higher than the ace if (cardList.AreConsecutive(true, false, 4)){ // (list is sorted from lowest to highest) cardList.Sort(SortUsing.AceHigh); // Special case if (cardList[cardList.Count - 1].Face == CardFace.Ace && cardList[cardList.Count - 2].Face == CardFace.King && cardList[cardList.Count - 3].Face == CardFace.Queen && cardList[cardList.Count - 4].Face == CardFace.Jack) return false; else return true; } // Except if the ace is not the first card, there's no cards lower than the ace if (cardList.AreConsecutive(false, false, 4)) { cardList.Sort(SortUsing.AceLow); // Special case if (cardList[0].Face == CardFace.Ace && cardList[1].Face == CardFace.Two && cardList[2].Face == CardFace.Three && cardList[3].Face == CardFace.Four) return false; else return true; } return false; }
private bool IsInsideStraightDraw(CardList cardList, bool countAceAsHigh) { if (cardList.Count < 4) return false; cardList.Sort(countAceAsHigh); // Case 1 and 2 are special cases // Case 1: first card is an ace and we are not counting ace as low, followed by 2, 3, 4 if (!countAceAsHigh && cardList[0].Face == CardFace.Ace && cardList[1].Face == CardFace.Two && cardList[2].Face == CardFace.Three && cardList[3].Face == CardFace.Four) return true; // Case 2: first card is a J and we are counting ace as high, followed by Q, K, A if (countAceAsHigh && cardList[0].Face == CardFace.Jack && cardList[1].Face == CardFace.Queen && cardList[2].Face == CardFace.King && cardList[3].Face == CardFace.Ace) return true; // Case 2: 1 card, missing, 3 straight for (int i = 0; i < (cardList.Count - 3); i++) { int faceValue = cardList[i].GetFaceValue(countAceAsHigh); if (cardList[i + 1].GetFaceValue(countAceAsHigh) == faceValue + 2 && cardList[i + 2].GetFaceValue(countAceAsHigh) == faceValue + 3 && cardList[i + 3].GetFaceValue(countAceAsHigh) == faceValue + 4) { return true; } } // Case 3: 2 straight, missing, 2 straight for (int i = 1; i < (cardList.Count - 2); i++) { int faceValue = cardList[i].GetFaceValue(countAceAsHigh); if (cardList[i - 1].GetFaceValue(countAceAsHigh) == faceValue - 1 && cardList[i + 1].GetFaceValue(countAceAsHigh) == faceValue + 2 && cardList[i + 2].GetFaceValue(countAceAsHigh) == faceValue + 3) { return true; } } // Case 4: 3 straight, missing, 1 card for (int i = 2; i < (cardList.Count - 1); i++) { int faceValue = cardList[i].GetFaceValue(countAceAsHigh); if (cardList[i - 2].GetFaceValue(countAceAsHigh) == faceValue - 2 && cardList[i - 1].GetFaceValue(countAceAsHigh) == faceValue - 1 && cardList[i + 1].GetFaceValue(countAceAsHigh) == faceValue + 2) { return true; } } return false; }
private bool IsFlushDraw(CardList cardList) { // Flush draw for (int i = 0; i < cardList.Count; i++) { int numCardsSameSuit = 1; for (int j = i + 1; j < cardList.Count; j++) { if (cardList[i].Suit == cardList[j].Suit) { numCardsSameSuit++; } } if (numCardsSameSuit == 4) { return true; } } return false; }
private PairType GetPairType(CardList communityCards, Card matching, Card firstCard, Card secondCard) { communityCards.Sort(SortUsing.AceHigh); // Pocket pair if (firstCard.Face == secondCard.Face) { if (firstCard.GetFaceValue() >= communityCards.Last.GetFaceValue()) return PairType.Top; else if (firstCard.GetFaceValue() <= communityCards[0].GetFaceValue()) return PairType.Bottom; else return PairType.Middle; } else { // Matched the board if (matching.Face == communityCards.Last.Face) return PairType.Top; else if (matching.Face == communityCards[0].Face) return PairType.Bottom; else return PairType.Middle; } }
/* Visual Recognition Manager handlers */ public void PlayerHandRecognized(CardList playerCards) { Globals.Director.RunFromGUIThread((Action)delegate () { if (DisplayWindow != null) DisplayWindow.DisplayPlayerHand(playerCards); }, true); }
public void DisplayPlayerHand(CardList playerCards) { // First create the hand Hand playerHand = CreateHandFromCardList(playerCards); if (playerHand != null){ UpdateHandTab(playerHand); // Save reference to the current hand lastPlayerHand = playerHand; } }
public ClassificationPostflop(HoldemHand hand, HoldemGamePhase phase, HoldemBoard board) { CardList communityCards = board.GetBoardAt(phase); // Default this.hand = HandType.Unknown; this.kicker = KickerType.Unknown; this.pair = PairType.Irrelevant; this.draw = DrawType.Irrelevant; this.straightDraw = StraightDrawType.None; Trace.Assert(communityCards.Count > 0, "Cannot classificate an empty list of community cards."); // Create a new list including the board cards and the cards from the hand CardList cards = new CardList(communityCards.Count + 2); foreach (Card c in communityCards) cards.AddCard(c); cards.AddCard(hand.GetFirstCard()); cards.AddCard(hand.GetSecondCard()); // --- Royal flush if (IsRoyalFlush(cards)) { this.hand = HandType.RoyalFlush; this.kicker = KickerType.Irrelevant; return; } // -- Four of a kind if (cards.HaveIdenticalFaces(4)) { this.hand = HandType.FourOfAKind; this.kicker = KickerType.Irrelevant; return; } // -- Full House // If we have three of a kind and two pair at the same time, we have a full house bool isThreeOfAKind = cards.HaveIdenticalFaces(3); bool isTwoPair = IsTwoPair(cards); if (isThreeOfAKind && isTwoPair) { this.hand = HandType.FullHouse; this.kicker = KickerType.Irrelevant; return; } // -- Flush for (int i = 0; i < cards.Count; i++) { int numCardsSameSuit = 0; for (int j = i + 1; j < cards.Count; j++) { if (cards[i].Suit == cards[j].Suit) { numCardsSameSuit++; } } if (numCardsSameSuit >= 4) { this.hand = HandType.Flush; this.kicker = KickerType.Irrelevant; return; } } // -- Straight if (IsStraight(cards)) { this.hand = HandType.Straight; this.kicker = KickerType.Irrelevant; return; } // Calculate draws (if we got until here, there might be some) // Also, no draws are possible at the river if (phase == HoldemGamePhase.River) { draw = DrawType.None; straightDraw = StraightDrawType.None; } else { draw = GetDrawType(cards); if (IsInsideStraightDraw(cards)) { straightDraw = StraightDrawType.InsideStraightDraw; } if (IsOpenEndedStraightDraw(cards)) { straightDraw = StraightDrawType.OpenEndedStraightDraw; } } // -- Trips if (isThreeOfAKind) { this.hand = HandType.ThreeOfAKind; this.kicker = KickerType.Irrelevant; return; } // -- Two pair if (isTwoPair) { this.hand = HandType.TwoPair; this.kicker = KickerType.Irrelevant; return; } // -- Pair Card matching; if (cards.HaveIdenticalFaces(2, out matching)) { // Sort list by face value (ace high first) cards.Sort(SortUsing.AceHigh); // Find kicker (check from end of the list where face values are higher) Card kicker = cards[0]; for (int i = cards.Count - 1; i >= 0; i--) { if (cards[i].Face != matching.Face) { kicker = cards[i]; break; } } this.hand = HandType.Pair; this.kicker = GetKickerTypeFromCard(kicker); this.pair = GetPairType(communityCards, matching, hand.GetFirstCard(), hand.GetSecondCard()); return; } // -- High card cards.Sort(SortUsing.AceHigh); Card highCard = cards.Last; this.hand = HandType.HighCard; this.kicker = GetKickerTypeFromCard(highCard); }
private bool IsTwoPair(CardList cards) { // Keep track of which pair face we have already found int firstPairFace = -1; bool foundFirstPair = false; bool foundSecondPair = false; for (int i = 0; i < cards.Count; i++) { for (int j = i + 1; j < cards.Count; j++) { // firstPairFace is always != face the first set of iterations if (cards[i].Face == cards[j].Face && ((int)cards[i].Face != firstPairFace)) { if (foundFirstPair) { foundSecondPair = true; } else { foundFirstPair = true; firstPairFace = (int)cards[i].Face; } break; } } } return foundSecondPair; }
private bool IsStraightDraw(CardList cardList) { if (cardList.Count < 4) return false; // Case 1: 4 cards to a straight (open ended straight draw) if (IsOpenEndedStraightDraw(cardList)) { return true; } // Case 2: inside straight draw if (IsInsideStraightDraw(cardList)) { return true; } return false; }
private bool IsStraight(CardList cards) { if (cards.AreConsecutive(true, false, 5)) { return true; } if (cards.AreConsecutive(false, false, 5)) { return true; } return false; }
private bool IsRoyalFlush(CardList cards) { if (cards.AreConsecutive(true, true, 5)) { return true; } if (cards.AreConsecutive(false, true, 5)) { return true; } return false; }
void handHistoryParser_FoundTableMaxSeatingCapacity(int maxSeatingCapacity) { this.maxSeatingCapacity = maxSeatingCapacity; // Usually the max seating capacity is the last piece of information we need in order to create a visual recognition manager // Attempt to create the visual recognition manager if (IsVisualRecognitionPossible()) { if (visualRecognitionManager == null) { visualRecognitionManager = new VisualRecognitionManager(this, this); } // TODO REMOVE CardList cards = new CardList(); //cards.AddCard(new Card(CardFace.Six, CardSuit.Spades)); //cards.AddCard(new Card(CardFace.Eight, CardSuit.Spades)); cards.AddCard(new Card(CardFace.Ace, CardSuit.Clubs)); cards.AddCard(new Card(CardFace.Seven, CardSuit.Hearts)); PlayerHandRecognized(cards); CardList board = new CardList(); cards.AddCard(new Card(CardFace.Ace, CardSuit.Hearts)); cards.AddCard(new Card(CardFace.Seven, CardSuit.Spades)); cards.AddCard(new Card(CardFace.Six, CardSuit.Hearts)); BoardRecognized(board); Globals.Director.RunFromGUIThread((Action)delegate () { if (displayWindow != null) displayWindow.SetVisualRecognitionSupported(true); }, false); } else { Trace.WriteLine("Visual recognition is not supported for " + this.ToString()); Globals.Director.RunFromGUIThread((Action)delegate () { if (displayWindow != null) displayWindow.SetVisualRecognitionSupported(false); }, false); } }
public bool IsInsideStraightDraw(CardList cardList) { if (cardList.Count < 4) return false; return IsInsideStraightDraw(cardList, true) || IsInsideStraightDraw(cardList, false); }
/* Tries to match a set of bitmaps into a card list. * @param allowPartialMatch If any card fails to match, the operation is aborted and the results obtained so far are returned * (but they might be incomplete). If this parameter is set to false, null is returned on failure. */ public CardList MatchCards(List<Bitmap> images, bool allowPartialMatch) { if (images.Count == 0) return null; CardList result = new CardList(); foreach (Bitmap image in images) { Card card = MatchCard(image); if (card != null) { result.AddCard(card); } else if (allowPartialMatch) { return result; } else { return null; } } return result; }
private DrawType GetDrawType(CardList cardList) { bool foundStraightDraw = false, foundFlushDraw = false; foundFlushDraw = IsFlushDraw(cardList); foundStraightDraw = IsStraightDraw(cardList); if (foundFlushDraw && !foundStraightDraw) return DrawType.Flush; else if (!foundFlushDraw && foundStraightDraw) return DrawType.Straight; else if (foundFlushDraw && foundStraightDraw) return DrawType.FlushAndStraight; else return DrawType.None; }
/* Hands are different objects depending on the game type * this methods returns null if the the hand cannot be created (maybe because of invalid number of cards) */ protected abstract Hand CreateHandFromCardList(CardList cardList);
public void BoardRecognized(CardList board) { Globals.Director.RunFromGUIThread((Action)delegate () { if (Game == PokerGame.Holdem && DisplayWindow != null) { ((HoldemTableDisplayWindow)DisplayWindow).DisplayBoard(board); } }, true); }