//determine the hole cards of the player and the community cards to be dealt //determines who will win the showdown at the end public void CalculateHandValueHard(Hand otherHand,Deck deck) { Hand knownCommunityCards = new Hand(); Hand remainingCommunityCards = new Hand(); //add known community cards for (int i = 2; i < myHand.Count(); i++) { knownCommunityCards.Add(myHand[i]); } //generate remaining community cards if (knownCommunityCards.Count() < 5) { remainingCommunityCards.Add(deck.Deal()); if (knownCommunityCards.Count() < 4) { remainingCommunityCards.Add(deck.Deal()); if (knownCommunityCards.Count() < 3) { remainingCommunityCards.Add(deck.Deal()); remainingCommunityCards.Add(deck.Deal()); remainingCommunityCards.Add(deck.Deal()); } } } //add the remaining cards this.AddToHand(remainingCommunityCards); otherHand += remainingCommunityCards; otherHand += knownCommunityCards; //compare hands if (HandCombination.getBestHandEfficiently(new Hand(myHand)) > HandCombination.getBestHandEfficiently(new Hand(otherHand))) handValue = 1; else if (HandCombination.getBestHandEfficiently(new Hand(myHand)) < HandCombination.getBestHandEfficiently(new Hand(otherHand))) handValue = 0; else handValue = 0.5; for (int i = 0; i < remainingCommunityCards.Count(); i++) { myHand.Remove(remainingCommunityCards[i]); } }
//use recursion to get rid of pairs, then evaluate straight flush public static bool isStraightFlush(Hand hand) { hand.sortByRank(); Hand simplifiedhand1, simplifiedhand2; //to be set the same as hand - cards are removed from this hand to evaluate straights separately without the interference of pairs or three-of-a-kind for (int i = 0; i <= hand.Count() - 2; i++) { if (hand.getCard(i) == hand.getCard(i + 1)) { simplifiedhand1 = new Hand(hand); simplifiedhand1.Remove(i); simplifiedhand2 = new Hand(hand); simplifiedhand2.Remove(i + 1); if (HandCombination.isStraightFlush(simplifiedhand1)) { return(true); } if (HandCombination.isStraightFlush(simplifiedhand2)) { return(true); } } } for (int i = 0; i <= hand.Count() - 5; i++) { int currentrank = hand.getCard(i).getRank(), currentsuit = hand.getCard(i).getSuit(); if (currentrank == hand.getCard(i + 1).getRank() + 1 && currentrank == hand.getCard(i + 2).getRank() + 2 && currentrank == hand.getCard(i + 3).getRank() + 3 && currentrank == hand.getCard(i + 4).getRank() + 4 && currentsuit == hand.getCard(i + 1).getSuit() && currentsuit == hand.getCard(i + 2).getSuit() && currentsuit == hand.getCard(i + 3).getSuit() && currentsuit == hand.getCard(i + 4).getSuit()) { return(true); } } for (int i = 0; i <= hand.Count() - 4; i++) { int currentrank = hand.getCard(i).getRank(), currentsuit = hand.getCard(i).getSuit(); if (currentrank == 5 && hand.getCard(i + 1).getRank() == 4 && hand.getCard(i + 2).getRank() == 3 && hand.getCard(i + 3).getRank() == 2 && hand.getCard(0).getRank() == 14 && currentsuit == hand.getCard(i + 1).getSuit() && currentsuit == hand.getCard(i + 2).getSuit() && currentsuit == hand.getCard(i + 3).getSuit() && currentsuit == hand.getCard(0).getSuit()) { return(true); } } return(false); }
//get all remaining cards, if necessary, to form 5 cards private static Hand getKickers(Hand hand, Hand specialCards) { if (specialCards.Count() == 0) { return(specialCards); } for (int i = 0; i < specialCards.Count(); i++) { hand.Remove(specialCards.getCard(i)); } for (int i = 0; i < hand.Count(); i++) { if (specialCards.Count() >= 5) { break; } specialCards.Add(hand.getCard(i)); specialCards.setValue(hand.getCard(i).getRank()); } return(specialCards); }
public static bool isOnePair(Hand hand) { hand.sortByRank(); for (int i = 0; i <= hand.Count() - 2; i++) { if (hand.getCard(i) == hand.getCard(i + 1)) { return(true); } } return(false); }
public static bool isThreeOfAKind(Hand hand) { hand.sortByRank(); for (int i = 0; i <= hand.Count() - 3; i++) { if (hand.getCard(i) == hand.getCard(i + 1) && hand.getCard(i) == hand.getCard(i + 2)) { return(true); } } return(false); }
public static Hand getBestHand(Hand hand) { if (hand.Count() < 5) { hand.Clear(); return(hand); } if (isRoyalFlush(hand)) { return(getRoyalFlush(hand)); } if (isStraightFlush(hand)) { return(getStraightFlush(hand)); } if (isFourOfAKind(hand)) { return(getFourOfAKind(hand)); } if (isFullHouse(hand)) { return(getFullHouse(hand)); } if (isFlush(hand)) { return(getFlush(hand)); } if (isStraight(hand)) { return(getStraight(hand)); } if (isThreeOfAKind(hand)) { return(getThreeOfAKind(hand)); } if (isTwoPair(hand)) { return(getTwoPair(hand)); } if (isOnePair(hand)) { return(getOnePair(hand)); } return(getHighCard(hand)); }
public static Hand getOnePair(Hand hand) { hand.sortByRank(); Hand onepair = new Hand(); onepair.setValue(2); for (int i = 0; i <= hand.Count() - 2; i++) { if (hand.getCard(i) == hand.getCard(i + 1)) { onepair.setValue(hand.getCard(i).getRank()); onepair.Add(hand.getCard(i)); onepair.Add(hand.getCard(i + 1)); break; } } return(getKickers(hand, onepair)); }
public static Hand getThreeOfAKind(Hand hand) { hand.sortByRank(); Hand threeofakind = new Hand(); threeofakind.setValue(4); for (int i = 0; i <= hand.Count() - 3; i++) { if (hand.getCard(i) == hand.getCard(i + 1) && hand.getCard(i) == hand.getCard(i + 2)) { threeofakind.setValue(hand.getCard(i).getRank()); threeofakind.Add(hand.getCard(i)); threeofakind.Add(hand.getCard(i + 1)); threeofakind.Add(hand.getCard(i + 2)); break; } } return(getKickers(hand, threeofakind)); }
//use a counter, if a counter reaches five, a flush is detected public static bool isFlush(Hand hand) { hand.sortByRank(); int diamondCount = 0, clubCount = 0, heartCount = 0, spadeCount = 0; for (int i = 0; i < hand.Count(); i++) { if ((SUIT)hand.getCard(i).getSuit() == SUIT.DIAMONDS) { diamondCount++; } else if ((SUIT)hand.getCard(i).getSuit() == SUIT.CLUBS) { clubCount++; } else if ((SUIT)hand.getCard(i).getSuit() == SUIT.HEARTS) { heartCount++; } else if ((SUIT)hand.getCard(i).getSuit() == SUIT.SPADES) { spadeCount++; } } if (diamondCount >= 5) { return(true); } else if (clubCount >= 5) { return(true); } else if (heartCount >= 5) { return(true); } else if (spadeCount >= 5) { return(true); } return(false); }
//same as above except return the cards themselves public static Hand getFourOfAKind(Hand hand) { Hand fourofakind = new Hand(); fourofakind.setValue(8); hand.sortByRank(); for (int i = 0; i <= hand.Count() - 4; i++) { if (hand.getCard(i) == hand.getCard(i + 1) && hand.getCard(i) == hand.getCard(i + 2) && hand.getCard(i) == hand.getCard(i + 3)) { fourofakind.Add(hand.getCard(i)); fourofakind.Add(hand.getCard(i + 1)); fourofakind.Add(hand.getCard(i + 2)); fourofakind.Add(hand.getCard(i + 3)); fourofakind.setValue(hand.getCard(i).getRank()); break; } } return(getKickers(hand, fourofakind)); }
public static bool isTwoPair(Hand hand) { hand.sortByRank(); int pairCount = 0; for (int i = 0; i <= hand.Count() - 2; i++) { if (hand.getCard(i) == hand.getCard(i + 1)) { pairCount++; i++; //the pair has already been checked, i must be incremented an additional time to avoid using a card in this pair again. This prevents the program from identifying 3 of a kind as 2 pairs. } } if (pairCount >= 2) { return(true); } else { return(false); } }
//using the monte carlo method, calculate a hand value for the AI's current hand //this can be very hard on the computer's memory and processor and can result in lag time public void CalculateHandValue(int count) { double score = 0; PlayerList playerList = new PlayerList(); for (int i = 0; i < count - 1; i++) { playerList.Add(new Player()); } Hand bestHand = new Hand(); int bestHandCount = 1; Deck deck = new Deck(); Hand knownCommunityCards = new Hand(); Hand remainingCommunityCards = new Hand(); Hand myHoleCards = new Hand(); //remove known cards from deck for (int i = 0; i < myHand.Count(); i++) { deck.Remove(myHand[i]); } //add known community cards for (int i = 2; i < myHand.Count(); i++) { knownCommunityCards.Add(myHand[i]); } myHoleCards.Add(this.getHand()[0]); myHoleCards.Add(this.getHand()[1]); //loop 100 times for (int i = 0; i < 100; i++) { //reset players and shuffle deck for (int j = 0; j < playerList.Count; j++) { playerList[j].isbusted = false; playerList[j].getHand().Clear(); } myHand.Clear(); remainingCommunityCards.Clear(); deck.Shuffle(); //generate remaining community cards if (knownCommunityCards.Count() < 5) { remainingCommunityCards.Add(deck.Deal()); if (knownCommunityCards.Count() < 4) { remainingCommunityCards.Add(deck.Deal()); if (knownCommunityCards.Count() < 3) { remainingCommunityCards.Add(deck.Deal()); remainingCommunityCards.Add(deck.Deal()); remainingCommunityCards.Add(deck.Deal()); } } } //add hole/community cards to the AI this.AddToHand(knownCommunityCards); this.AddToHand(remainingCommunityCards); this.AddToHand(myHoleCards); //add hole/community cards to other players for (int j = 0; j < playerList.Count; j++) { playerList[j].AddToHand(knownCommunityCards); if (remainingCommunityCards.Count() != 0) playerList[j].AddToHand(remainingCommunityCards); playerList[j].AddToHand(deck.Deal()); playerList[j].AddToHand(deck.Deal()); //if player is dealt hole cards of less than 5-5, and no pocket pairs the player drops out if (playerList[j].getHand()[playerList[j].getHand().Count() - 1].getRank() + playerList[j].getHand()[playerList[j].getHand().Count() - 2].getRank() <= 10 && playerList[j].getHand()[playerList[j].getHand().Count() - 1].getRank() != playerList[j].getHand()[playerList[j].getHand().Count() - 2].getRank()) { playerList[j].isbusted = true; } } //add cards back to deck for (int j = 0; j < remainingCommunityCards.Count(); j++) { deck.Add(remainingCommunityCards[j]); } for (int j = 0; j < playerList.Count; j++) { deck.Add(playerList[j].getHand()[playerList[j].getHand().Count() - 1]); deck.Add(playerList[j].getHand()[playerList[j].getHand().Count() - 2]); } //compare hands bestHandCount = 1; playerList.Add(this); bestHand = playerList[0].getHand(); for (int j = 0; j <playerList.Count-1; j++) { if (playerList[j].isbusted) continue; if (HandCombination.getBestHandEfficiently(new Hand(playerList[j+1].getHand())) > HandCombination.getBestHandEfficiently(new Hand(playerList[j].getHand()))) { bestHandCount = 1; bestHand = playerList[j+1].getHand(); } else if (HandCombination.getBestHandEfficiently(new Hand(playerList[j+1].getHand())) == HandCombination.getBestHandEfficiently(new Hand(playerList[j].getHand()))) bestHandCount++; } playerList.Remove(this); //if my hand is the best, increment score if (myHand.isEqual(bestHand)) score = score + (1 / bestHandCount); } //reconstruct original hand myHand.Clear(); this.AddToHand(myHoleCards); this.AddToHand(knownCommunityCards); //calculate hand value as a percentage of wins handValue = score / 100; }
//use a counter to determine with suit forms a flush //then get all cards from the suit public static Hand getFlush(Hand hand) { hand.sortByRank(); Hand flush = new Hand(); flush.setValue(6); int diamondCount = 0, clubCount = 0, heartCount = 0, spadeCount = 0; for (int i = 0; i < hand.Count(); i++) { if ((SUIT)hand.getCard(i).getSuit() == SUIT.DIAMONDS) { diamondCount++; } else if ((SUIT)hand.getCard(i).getSuit() == SUIT.CLUBS) { clubCount++; } else if ((SUIT)hand.getCard(i).getSuit() == SUIT.HEARTS) { heartCount++; } else if ((SUIT)hand.getCard(i).getSuit() == SUIT.SPADES) { spadeCount++; } } if (diamondCount >= 5) { for (int i = 0; i < hand.Count(); i++) { if (hand.getCard(i).getSuit() == 1) { flush.Add(hand.getCard(i)); flush.setValue(hand.getCard(i).getRank()); } if (flush.Count() == 5) { break; } } //return flush; } else if (clubCount >= 5) { for (int i = 0; i <= hand.Count(); i++) { if (hand.getCard(i).getSuit() == 2) { flush.Add(hand.getCard(i)); flush.setValue(hand.getCard(i).getRank()); } if (flush.Count() == 5) { break; } } //return flush; } else if (heartCount >= 5) { for (int i = 0; i <= hand.Count(); i++) { if (hand.getCard(i).getSuit() == 3) { flush.Add(hand.getCard(i)); flush.setValue(hand.getCard(i).getRank()); } if (flush.Count() == 5) { break; } } //return flush; } else if (spadeCount >= 5) { for (int i = 0; i <= hand.Count(); i++) { if (hand.getCard(i).getSuit() == 4) { flush.Add(hand.getCard(i)); flush.setValue(hand.getCard(i).getRank()); } if (flush.Count() == 5) { break; } } //return flush; } return(flush); }
//get straight flush using two pointer variable and taking care of all cases public static Hand getStraightFlush(Hand hand) { hand.sortByRank(); Hand straightflush = new Hand(); straightflush.setValue(9); if (hand.getCard(0).getRank() == 14) { hand.Add(new Card((int)RANK.ACE, hand.getCard(0).getSuit())); } //int straightflushCount = 1; straightflush.Add(hand.getCard(0)); int ptr1 = 0, ptr2 = 1; while (ptr1 < hand.Count() - 2 || ptr2 < hand.Count()) { if (straightflush.Count() >= 5) { break; } int rank1 = hand.getCard(ptr1).getRank(), rank2 = hand.getCard(ptr2).getRank(); int suit1 = hand.getCard(ptr1).getSuit(), suit2 = hand.getCard(ptr2).getSuit(); if (rank1 - rank2 == 1 && suit1 == suit2) { straightflush.Add(hand.getCard(ptr2)); ptr1 = ptr2; ptr2++; } else if (rank1 == 2 && rank2 == 14 && suit1 == suit2) { straightflush.Add(hand.getCard(ptr2)); ptr1 = ptr2; ptr2++; } else { if (rank1 - rank2 <= 1) { ptr2++; } else { straightflush.Clear(); straightflush.setValue(9); ptr1++; ptr2 = ptr1 + 1; straightflush.Add(hand.getCard(ptr1)); } } } if (hand.getCard(0).getRank() == 14) { hand.Remove(hand.Count() - 1); } straightflush.setValue(straightflush.getCard(0).getRank()); if (straightflush.Count() < 5) { straightflush.Clear(); } return(straightflush); }