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); }
public override bool Equals(object obj) { // Null is false if (obj == null) { return(false); } CardList otherList = (CardList)obj; // Different size is false if (cards.Count != otherList.cards.Count) { return(false); } bool equal = true; for (int i = 0; i < cards.Count; i++) { if (!cards[i].Equals(otherList.cards[i])) { equal = false; break; } } return(equal); }
public void VillainHandRecognized(CardList villainCards, int seat) { //TODO: Actions needed: // 1. Find player by seat // 2. Convert CardList into hands // 3. call code below Player player = FindPlayer(seat); if (null == player) { Globals.Director.WriteDebug(WRITE_DEBUG, " -- player at seat (" + seat + ") can not be found"); return; } Hand muckedCards = new Hand(); muckedCards.AddCard(villainCards[0]); muckedCards.AddCard(villainCards[1]); player.IsPlaying = true; player.IsDealtHoleCards(); player.MuckHandAvailable(muckedCards); UpdateUI(); }
/* 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); }
public void DisplayBoard(CardList boardCards) { HoldemBoard board = CreateBoardFromCardList(boardCards); if (board != null) { UpdateBoardOdds(board); lastBoard = board; } }
public bool IsInsideStraightDraw(CardList cardList) { if (cardList.Count < 4) { return(false); } return(IsInsideStraightDraw(cardList, true) || IsInsideStraightDraw(cardList, false)); }
public void BoardRecognized(CardList board) { Globals.Director.RunFromGUIThread((Action) delegate() { if (Game == PokerGame.Holdem && DisplayWindow != null) { ((HoldemTableDisplayWindow)DisplayWindow).DisplayBoard(board); } }, true); }
protected override Hand CreateHandFromCardList(CardList cardList) { // We need exactly two cards in hold'em to have a hand if (cardList.Count == 2) { HoldemHand hand = new HoldemHand(cardList[0], cardList[1]); return hand; } else return null; }
private HoldemBoard CreateBoardFromCardList(CardList cardList) { if (cardList.Count >= 3 && cardList.Count <= 5) { HoldemBoard result = new HoldemBoard(cardList); return(result); } return(null); }
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); } }
/* Visual Recognition Manager handlers */ public void PlayerHandRecognized(CardList playerCards) { Globals.Director.RunFromGUIThread((Action) delegate() { if (DisplayWindow != null) { DisplayWindow.DisplayPlayerHand(playerCards); } }, true); }
private void ProcessPlayerCardActions(Bitmap screenshot, int seat, bool isHero) { /* Try to match player cards */ List <Bitmap> playerCardImages = new List <Bitmap>(); ArrayList playerCardsActions = colorMap.GetPlayerCardsActions(seat); foreach (String action in playerCardsActions) { Globals.Director.WriteDebug(" --- PlayerCardsActions: " + action); Rectangle actionRect = recognitionMap.GetRectangleFor(action); if (!actionRect.Equals(Rectangle.Empty)) { //Globals.Director.WriteDebug(" --- Found Rectangle for:: " + action); playerCardImages.Add(ScreenshotTaker.Slice(screenshot, actionRect)); } else { Globals.Director.WriteDebug("Warning: could not find a rectangle for action " + action); } } //Globals.Director.WriteDebug("Matching player cards! "); //playerCardsActions CardList playerCards = matcher.MatchCards(playerCardImages, false, playerCardsActions, table.MatchHistogramThreshold(), table.MatchTemplateThreshold(), table.AllowableMatchTemplateThreshold()); if (playerCards != null && isHero) { Globals.Director.WriteDebug("Matched player cards! " + playerCards.ToString()); handler.PlayerHandRecognized(playerCards); } else if (playerCards != null && !isHero) { Globals.Director.WriteDebug(" -- NOT hero cards. Seat " + seat + " Cards: " + playerCards.ToString()); handler.VillainHandRecognized(playerCards, seat); } else { Globals.Director.WriteDebug(" --- SEAT: " + seat + " Did not find any matching player cards "); } // Dispose foreach (Bitmap image in playerCardImages) { if (image != null) { image.Dispose(); } } }
/* Perform a deep copy */ public object Clone() { CardList cardList = (CardList)this.MemberwiseClone(); cardList.cards = new List <Card>(5); foreach (Card c in cards) { cardList.AddCard((Card)c.Clone()); } return(cardList); }
/* Visual Recognition Manager handlers */ public void PlayerHandRecognized(CardList playerCards) { Globals.Director.RunFromGUIThread((Action) delegate() { Globals.Director.WriteDebug(WRITE_DEBUG, "\n\t ~~~ PlayerHandRecognized " + playerCards.ToString()); if (DisplayWindow != null) { DisplayWindow.DisplayPlayerHand(playerCards); } }, true); //TODO - update the state of the Table }
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 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; } }
protected override Hand CreateHandFromCardList(CardList cardList) { // We need exactly two cards in hold'em to have a hand if (cardList.Count == 2) { HoldemHand hand = new HoldemHand(cardList[0], cardList[1]); return(hand); } else { return(null); } }
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); }
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 void ProcessCommunityCardActions(Bitmap screenshot) { /* If community cards are supported, try to match them */ if (colorMap.SupportsCommunityCards) { List <Bitmap> communityCardImages = new List <Bitmap>(); ArrayList communityCardsActions = colorMap.GetCommunityCardsActions(); foreach (String action in communityCardsActions) { Rectangle actionRect = recognitionMap.GetRectangleFor(action); if (!actionRect.Equals(Rectangle.Empty)) { communityCardImages.Add(ScreenshotTaker.Slice(screenshot, actionRect)); } else { Globals.Director.WriteDebug("Warning: could not find a rectangle for action " + action); } } // We try to identify as many cards as possible CardList communityCards = matcher.MatchCards(communityCardImages, true, communityCardsActions, table.MatchHistogramThreshold(), table.MatchTemplateThreshold(), table.AllowableMatchTemplateThreshold() ); if (communityCards != null && communityCards.Count > 0) { //Globals.Director.WriteDebug("~~~ Matched board cards! " + communityCards.ToString()); handler.BoardRecognized(communityCards); } else { Globals.Director.WriteDebug("~~~ Warning: could not find a commnity cards "); } // Dispose foreach (Bitmap image in communityCardImages) { if (image != null) { image.Dispose(); } } } }
public void BoardRecognized(CardList board) { Globals.Director.RunFromGUIThread((Action) delegate() { Globals.Director.WriteDebug(WRITE_DEBUG, "\n\t ~~~ BoardRecognized " + board.ToString()); if (Game == PokerGame.Holdem && DisplayWindow != null) { ((HoldemTableDisplayWindow)DisplayWindow).DisplayBoard(board); } }, true); Globals.Director.WriteDebug(WRITE_DEBUG, "\n\t ~~~ Board Count " + board.ToString() + " " + board.Count); //TODO - update the state of the Table if (board.Count == 5) { Board finalBoard = new HoldemBoard(board); handHistoryParser_FinalBoardAvailable(finalBoard); } }
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 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); }
/* 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, ArrayList actionMap, double perfectMatchHistogramThreshold = 0, double possibleMatchTemplateThreshold = 0, double allowableSimilarityThreshold = 0) { if (images.Count == 0) { return(null); } CardList result = new CardList(); int i = 0; foreach (Bitmap image in images) { Globals.Director.WriteDebug(WRITE_DEBUG, " --- action: " + actionMap[i].ToString()); Card card = MatchCard(image, actionMap[i].ToString(), perfectMatchHistogramThreshold, possibleMatchTemplateThreshold, allowableSimilarityThreshold); ++i; if (card != null) { result.AddCard(card); } else if (allowPartialMatch) { return(result); } else { return(null); } } return(result); }
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); } } }
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); } }
public bool IsInsideStraightDraw(CardList cardList) { if (cardList.Count < 4) return false; return IsInsideStraightDraw(cardList, true) || IsInsideStraightDraw(cardList, false); }
// This window actually never generates a hand protected override Hand CreateHandFromCardList(CardList cardList) { return(null); }
// This window actually never generates a hand protected override Hand CreateHandFromCardList(CardList cardList) { return null; }
public void BoardRecognized(CardList board) { Globals.Director.RunFromGUIThread((Action)delegate() { if (Game == PokerGame.Holdem && DisplayWindow != null){ ((HoldemTableDisplayWindow)DisplayWindow).DisplayBoard(board); } }, true); }
/* 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 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; }
void timedScreenshotTaker_ScreenshotTaken(Bitmap screenshot) { UpdateCardMatchDialogSpawnLocation(); /* This code would resize the map and recompute the data in it, * but we don't use this approach anymore. */ //recognitionMap.AdjustToSize(screenshot.Size); /* Instead if the screenshot we took differs in size from the map at our disposal * we resize the window and retake the screenshot */ if (!screenshot.Size.Equals(recognitionMap.OriginalMapSize)) { Trace.WriteLine(String.Format("Screenshot size ({0}x{1}) differs from our map image ({2}x{3}), resizing window...", screenshot.Size.Width, screenshot.Size.Height, recognitionMap.OriginalMapSize.Width, recognitionMap.OriginalMapSize.Height)); Size winSize = tableWindow.Size; Size difference = new Size(screenshot.Size.Width - recognitionMap.OriginalMapSize.Width, screenshot.Size.Height - recognitionMap.OriginalMapSize.Height); Size newSize = winSize - difference; tableWindow.Resize(newSize, true); return; // At next iteration this code should not be executed because sizes will be the same, unless the player resizes the window } // If we don't know where the player is seated, we don't need to process any further if (table.CurrentHeroSeat == 0) { return; } /* Try to match player cards */ List <Bitmap> playerCardImages = new List <Bitmap>(); ArrayList playerCardsActions = colorMap.GetPlayerCardsActions(table.CurrentHeroSeat); foreach (String action in playerCardsActions) { Rectangle actionRect = recognitionMap.GetRectangleFor(action); if (!actionRect.Equals(Rectangle.Empty)) { playerCardImages.Add(ScreenshotTaker.Slice(screenshot, actionRect)); } else { Trace.WriteLine("Warning: could not find a rectangle for action " + action); } } CardList playerCards = matcher.MatchCards(playerCardImages, false); if (playerCards != null) { Trace.WriteLine("Matched player cards! " + playerCards.ToString()); handler.PlayerHandRecognized(playerCards); } // Dispose foreach (Bitmap image in playerCardImages) { if (image != null) { image.Dispose(); } } /* If community cards are supported, try to match them */ if (colorMap.SupportsCommunityCards) { List <Bitmap> communityCardImages = new List <Bitmap>(); ArrayList communityCardsActions = colorMap.GetCommunityCardsActions(); foreach (String action in communityCardsActions) { Rectangle actionRect = recognitionMap.GetRectangleFor(action); if (!actionRect.Equals(Rectangle.Empty)) { communityCardImages.Add(ScreenshotTaker.Slice(screenshot, actionRect)); } else { Trace.WriteLine("Warning: could not find a rectangle for action " + action); } } // We try to identify as many cards as possible CardList communityCards = matcher.MatchCards(communityCardImages, true); if (communityCards != null && communityCards.Count > 0) { Trace.WriteLine("Matched board cards! " + communityCards.ToString()); handler.BoardRecognized(communityCards); } // Dispose foreach (Bitmap image in communityCardImages) { if (image != null) { image.Dispose(); } } } // Dispose screenshot if (screenshot != null) { screenshot.Dispose(); } }
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 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); } }
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 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; } }
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); }
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); }
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; } }
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 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; }
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 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 HoldemBoard CreateBoardFromCardList(CardList cardList) { if (cardList.Count >= 3 && cardList.Count <= 5) { HoldemBoard result = new HoldemBoard(cardList); return result; } return null; }
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; }
/* 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);
/* Visual Recognition Manager handlers */ public void PlayerHandRecognized(CardList playerCards) { Globals.Director.RunFromGUIThread((Action)delegate() { if (DisplayWindow != null) DisplayWindow.DisplayPlayerHand(playerCards); }, true); }