public override PlayerAction BettingRound2(List <PlayerAction> actions, Card[] hand) { //reset? localMoney = Money; //throw new NotImplementedException(); //action to be done PlayerAction act = new PlayerAction(Name, "Bet2", "fold", 0); //Fold; //EVAL HAND Card highCard = null; handStrength = Evaluate.RateAHand(hand, out highCard); //(1 weak - 10 strong af) //review actions of other player EvaluateActions(actions); //Respond to their action if (actions[actions.Count - 1].ActionPhase == "fold") { //round is over reset all values Reset(); } else //they did something we should respond to that { act = ResponseAction(actions[actions.Count - 1], highCard, "Bet2"); } if (cheat) { ChangeMoney(500); } return(act); }
public override PlayerAction BettingRound1(List <PlayerAction> actions, Card[] hand) { //Reset if it's the start of a new round if (actions.Count < 2) { Reset(); } localMoney = Money; //Update how much money we actually have //Evaluate hand strength and get the high card Card highCard = null; handStrength = Evaluate.RateAHand(hand, out highCard); EvaluateActions(actions); //Check the actions of the other player if (actions.Count > 0 && actions[actions.Count - 1].ActionPhase == "fold") //If the last action was fold { Reset(); //Reset all values } else if (actions.Count == 0) //If this is round 1 { return(ResponseAction(null, highCard, "Bet1")); //Passing in null is handled and avoids ArgumentOutOfRange exceptions } else //Respond to actions other than fold { return(ResponseAction(actions[actions.Count - 1], highCard, "Bet1")); } return(new PlayerAction(Name, "Bet1", "fold", 0)); //Fold }
/// <summary> /// This method simulates 1000 scenarios with the current hand AI has to calculate winning percentage. /// </summary> /// <param name="hand">Current hand</param> /// <returns> /// Strength of cards player has. /// </returns> private double CalculateHandStrength(Card[] hand) { Card [] sample_hand = new Card[5]; float win_count = 0f; Random r = new Random(); int pos; Card high, new_high; int rating = Evaluate.RateAHand(hand, out high); int new_rating; for (int run = 0; run < 1000; run++) { List <Card> demodeck = CreateDummyDeck(hand); for (int i = 0; i < 5; i++) { pos = r.Next(demodeck.Count); sample_hand[i] = demodeck[pos]; demodeck.RemoveAt(pos); } new_rating = Evaluate.RateAHand(sample_hand, out new_high); if (rating > new_rating) { win_count++; } else if (rating == new_rating && high.Value >= new_high.Value) { win_count++; } } double hand_strength = win_count / 1000f; hand_strength = Math.Round(hand_strength, 2); return(hand_strength); }
// Score is Evaluate.RateAHand * 100 + highCard.value. private static double ScoreHand(Card[] hand) { // for now, we just pass this to evaluate Card highCard; return((double)(Evaluate.RateAHand(hand, out highCard) * 100 + highCard.Value)); }
// Determines whether drawing *change* amount of cards has potential private bool HasPotential(int change, Card[] cardHand, int[] intHand, int start) { // Used for hand rating Card c; // The maximum numbers of iterations int max = (int)Math.Floor(Math.Pow(52, change)); // The minimum potential necessary (based on iterations) to decide to draw that many cards float tolerance = 0.25f; int handPotential = Evaluate.RateAHand(cardHand, out c); int minPotential = (int)(tolerance * max * handPotential); // Initialize variables for finding potential int potential = 0; // Determines which cards we are currently effecting int first = start; int second = Next(first, 4); int third = Next(second, 4); // Temporary hands that we can modify Card[] tempC = new Card[cardHand.Length]; cardHand.CopyTo(tempC, 0); int[] tempI = new int[intHand.Length]; intHand.CopyTo(tempI, 0); // Acts as multiple for loops by changing index intelligently for (int i = 0; i < max; i++) { // Iterate the first card every iteration Iterate(tempI, first); // Every 52 iterations, iterate the second card if (i % 52 == 0) { Iterate(tempI, second); } // Every 2704 iterations, iterate the third card if (i % 2704 == 0) { Iterate(tempI, third); } // Add any new potential from drawing tempC[0] = IntToCard(tempI[0]); tempC[1] = IntToCard(tempI[1]); tempC[2] = IntToCard(tempI[2]); tempC[3] = IntToCard(tempI[3]); tempC[4] = IntToCard(tempI[4]); potential += Clamp(0, 10, Evaluate.RateAHand(tempC, out c) - handPotential); } // This draw amount only has potential if it is greater than the minimum return(potential > minPotential); }
public override PlayerAction Draw(Card[] hand) { Card highCard; int rating = Evaluate.RateAHand(Hand, out highCard); int discard = new DiscardNode().Discard(ref hand, rating); return(new PlayerAction(Name, "Draw", "draw", discard)); }
public override PlayerAction BettingRound1(List <PlayerAction> actions, Card[] hand) { //estimate values and update the rounds details Card highestCard; int rating = Evaluate.RateAHand(hand, out highestCard); details.Update(rating, "Bet1"); //return the playeraction return(chooseMove.calc(actions, details)); }
public override PlayerAction BettingRound2(List <PlayerAction> actions, Card[] hand) { Random rand = new Random(); Card highCard = null; int rank = Evaluate.RateAHand(hand, out highCard); //bets the ammount based on hand rank int amount = 10 * rank + rand.Next(0, 10); PlayerAction pa = new PlayerAction(Name, "Bet2", "check", amount); return(pa); }
// helper method - list the hand // temporarily copied into here so we can see what the AI has // TODO: delete when AI is working properly private void ListTheHand(Card[] hand) { // evaluate the hand Card highCard = null; int rank = Evaluate.RateAHand(hand, out highCard); // list your hand Console.WriteLine("\nName: " + Name + " Your hand: Rank: " + rank); for (int i = 0; i < hand.Length; i++) { Console.Write(hand[i].ToString() + " "); } Console.WriteLine(); }
public override PlayerAction BettingRound1(List <PlayerAction> actions, Card[] hand) { Random rand = new Random(); PlayerAction pa = null; // evaluate the hand Card highCard = null; int rank = Evaluate.RateAHand(hand, out highCard); //bets the ammount based on hand rank int amount = 10 * rank + rand.Next(0, 10); //if isn't the dealer, and is going first if (this.Dealer == false) { if (rank == 1) //if rank is 1, no point in playing { pa = new PlayerAction(Name, "Bet1", "fold", amount); } else if (rank >= 4) { pa = new PlayerAction(Name, "Bet1", "bet", amount); } else // check cause the hand you ahve isn't that great { pa = new PlayerAction(Name, "Bet1", "check", amount); } } else { if (rank == 1) //if rank is 1, no point in playing { pa = new PlayerAction(Name, "Bet1", "fold", amount); } else if (rank < 5) //match the bet if hand rank is 6 or less { pa = new PlayerAction(Name, "Bet1", "call", amount); } else // else raise the bet cause your hand is probably the best { pa = new PlayerAction(Name, "Bet1", "raise", amount); } } return(pa); }
public override PlayerAction BettingRound2(List <PlayerAction> actions, Card[] hand) { //order hand first Evaluate.SortHand(hand); // get rank of current hand and highest card Card highCard = null; int finalRank = Evaluate.RateAHand(hand, out highCard); // final hand rank // Determine bet/bluff action -- KPAR, NPRO Boolean bluffing = determineBluff(); // return appropriate PlayerAction object int amountPlaced = 0; string actionTaken = determinePlayerAction(finalRank, actions, bluffing, out amountPlaced);//the player action that will be taken for this turn return(new PlayerAction(Name, "Bet2", actionTaken, amountPlaced)); }
// list a hand of cards public static string ListHand(Card[] hand) { // string to hold output string text = ""; // evaluate the hand Card highCard = null; int rank = Evaluate.RateAHand(hand, out highCard); // list your hand text += "Hand Rank: " + rank + " \n"; for (int i = 0; i < hand.Length; i++) { text += hand[i].ToString() + " "; } text += "\n"; return(text); }
//Implemented by Mark Scott public override PlayerAction BettingRound2(List <PlayerAction> actions, Card[] hand) { //estimate values and update the rounds details Card highestCard; int rating = Evaluate.RateAHand(hand, out highestCard); details.Update(rating, "Bet2"); //return the playeraction return(chooseMove.calc(actions, details)); /* old Nelson Stuff * //Rate the hand * Card highestCard; * int handRating = Evaluate.RateAHand(hand, out highestCard); * * //Selector * PlayerAction pa = new PlayerAction(Name, "Bet2", "fold", 0); * if (AllInSequence(handRating)) * { * pa = new PlayerAction(Name, "Bet2", "raise", Money); * } * else if (RaiseSequence(handRating)) * { * pa = new PlayerAction(Name, "Bet2", "raise", (int)(Money / 4)); * } * else if (actions.Count > 0 && CallSequence(actions[actions.Count - 1], handRating)) * { * pa = new PlayerAction(Name, "Bet2", "call", actions[actions.Count - 1].Amount); * } * else if (CheckSequence(handRating)) * { * pa = new PlayerAction(Name, "Bet2", "check", 0); * } * * return pa; */ }
public override PlayerAction BettingRound2(List <PlayerAction> actions, Card[] hand) { //todo gather information about the other player beforehand based on what they are drawing //ie if they draw 3 cards and we have a two pair then we have a 2/3 chance of beating them //since we know they have one pair GetSuitsValues(hand); Card highCard; PlayerAction lastAction = actions[actions.Count - 1]; int handValue = Evaluate.RateAHand(hand, out highCard); //how aggressively we will raise/call //compared against aggressionR2, if opponent is not aggressive then we will assume that our hand is stronger above a certain aggressionR2 threshold initialTurn = actions.Count; //int moneyToBet = 0; bool firstPlay = false; if (lastAction.ActionName == "stand pat" || lastAction.ActionName == "draw") { firstPlay = true; } int pairHigh = -1; Card currentCard; for (int outer = 0; outer < 5; outer++) { currentCard = hand[outer]; for (int inner = 0; inner < 5; inner++) { if (outer != inner) { if ((hand[inner].Value == hand[outer].Value) && hand[inner].Value > pairHigh) { pairHigh = hand[inner].Value; } } } } if (handValue >= 8) { r2MaxRaise = Money; } else if (handValue < 2 || (handValue == 2 && pairHigh < 14)) { r2MaxRaise = 0; } else { r2MaxRaise = 20 + 20 * (handValue - 1); } //Player is playing first in round 2 if (actions[actions.Count - 1].ActionPhase == "Draw") { // if (handValue < 2 || (handValue == 2 && pairHigh < 14)) { aggressionR2 = 0; return(new PlayerAction(name, "Bet2", "check", 0)); } //pair of kings or better play conservatively else if (handValue == 2 && pairHigh >= 14) { aggressionR2 = .3f; moneyBetR2 += 10; return(new PlayerAction(name, "Bet2", "bet", 10)); } else if (handValue == 3) { if (pairHigh >= 12) //two pair high of 10s { aggressionR2 = .7f; moneyBetR2 += 20; return(new PlayerAction(name, "Bet2", "bet", 20)); } else //two pair high of less than 10s { aggressionR2 = 0.5f; moneyBetR2 += 15; return(new PlayerAction(name, "Bet2", "bet", 15)); } } else if (handValue == 4) { //3 of a kind 10s or higher if (pairHigh <= 12) { aggressionR2 = .9f; moneyBetR2 += 30; return(new PlayerAction(name, "Bet2", "bet", 30)); } else // 3 of a kind 9s or lower { aggressionR2 = .8f; moneyBetR2 += 25; return(new PlayerAction(name, "Bet2", "bet", 25)); } } else if (handValue >= 5) { aggressionR2 = 1.0f; moneyBetR2 += 30; return(new PlayerAction(name, "Bet2", "bet", 30)); } } //player is playing second in round 2 else if (actions[actions.Count - 2].ActionPhase == "Draw" && actions[actions.Count - 1].ActionPhase == "Bet2") { if (lastAction.ActionName == "check") { //neutral opponentAggression = .5f; if (aggressionR2 > .5f) { moneyBetR2 += 20; return(new PlayerAction(name, "Bet2", "bet", 20)); } else { moneyBetR2 += 10; return(new PlayerAction(name, "Bet2", "bet", 10)); } } //I'd love to scale aggression based on how much they bet but I'm really not sure how much money is a lot in this game //so I opt to scale it based on how the opponent chooses actions instead of the specific values else if (lastAction.ActionName == "bet") { opponentAggression = .5f; if (aggressionR2 > .5f) { //raise int moneyThisTurn = (int)(((float)r2MaxRaise / 2.0f * (float)aggressionR2)); moneyBetR2 += moneyThisTurn; return(new PlayerAction(name, "Bet2", "raise", moneyThisTurn)); } else if (aggressionR2 > .3f) { //call int moneyThisTurn = lastAction.Amount; moneyBetR2 += moneyThisTurn; return(new PlayerAction(name, "Bet2", "call", moneyThisTurn)); } else { //fold return(new PlayerAction(name, "Bet2", "fold", 0)); } } } //not player's first turn in the round else { } return(new PlayerAction(name, "Bet2", "fold", 0)); }
public override PlayerAction BettingRound2(List <PlayerAction> actions, Card[] hand) { PokerTournament.Card highCard; int handEval = Evaluate.RateAHand(this.Hand, out highCard); int pot = CurrentPot(actions, "Bet2"); int betAmount = GetCurrentBet(actions, "Bet2"); float odds = CalculatePotOdds(betAmount, pot); float returnRate = CalculateRateOfReturn(handEval, odds); float chance = rand.Next(0, 100); ListTheHand(hand); Console.WriteLine("Return rate: " + returnRate); //Console.WriteLine("Chance: " + chance); //Console.WriteLine("Pairs: " + CheckPair().Count); //Console.ReadLine(); if (returnRate < 4) { if (chance > 94) { return(new PlayerAction(Name, "Bet2", "raise", betAmount)); } else { return(new PlayerAction(Name, "Bet2", "fold", 0)); } } else if (returnRate < 20) { if (chance > 94) { return(new PlayerAction(Name, "Bet2", "call", 0)); } else if (chance > 79) { return(new PlayerAction(Name, "Bet2", "raise", betAmount)); } else { return(new PlayerAction(Name, "Bet2", "fold", 0)); } } else { if (returnRate == float.PositiveInfinity) { int res; res = 5 * handEval; if (res > Money) { res = Money; } return(new PlayerAction(Name, "Bet2", "bet", res)); } if (chance > 70) { return(new PlayerAction(Name, "Bet2", "call", 0)); } else { float fres = betAmount * (returnRate); int res; res = (int)fres; if (res > Money) { res = Money; } return(new PlayerAction(Name, "Bet2", "raise", res)); } } //return new PlayerAction(Name, "Bet2", "bet", 0); }
public override PlayerAction Draw(Card[] hand) { // BRANCHING BEHAVIOR TREE (?) // // Get hand Eval Card highCard = null; handStrength = Evaluate.RateAHand(hand, out highCard); // number of tossed cards (and number to be drawn) // pass into PlayerAction return at the end int removed = 0; // Do stuff according to handStrength switch (handStrength) { case 1: // weakest hand: HIGH CARD if (highCard.Value >= 10) // Check the highCard's value, if highCard is a 10-J-Q-K-A { for (int i = 0; i < hand.Length; i++) // remove everything but the high card { if (hand[i] == highCard) { continue; // ignore if the current card is the high card } hand[i] = null; // remove removed++; } //thisAction = new PlayerAction(Name, "Draw", "draw", removed); ////////////////DO THIS AT THE END OF SWITCH????? Console.WriteLine("Player 10 threw away and will draw" + removed + " cards."); } else // if high card is not 10-J-Q-K-A then all these cards mean literally nothing, toss all { for (int i = 0; i < hand.Length; i++) { hand[i] = null; } //thisAction = new PlayerAction(Name, "Draw", "draw", 5);/////////////////////////// removed = 5; Console.WriteLine("Player 10 throws away its entire hand."); } break; case 2: // 1-PAIR int pairValue = 0; // have to get the value of the 1pair, must be initialized to something for (int i = 2; i < 15; i++) // check all values { if (Evaluate.ValueCount(i, hand) == 2) // count occurences of value (once 2 are found, break from for loop) { pairValue = i; break; } } // optimize chances of getting a higher hand // if the high card is not one of the pair AND it is 10-J-Q-K-A if (highCard.Value != pairValue && highCard.Value >= 10) { for (int i = 0; i < hand.Length; i++) { if (hand[i].Value == pairValue || hand[i].Value == highCard.Value) { continue; // do not toss if the current card is one of the pair OR if it is the HIGH CARD (that is different from the pair in this case) } hand[i] = null; } removed = 2; } else // otherwise toss everything that isn't the pair { for (int i = 0; i < hand.Length; i++) { if (hand[i].Value == pairValue) { continue; } hand[i] = null; } removed = 3; } break; case 3: // 2-PAIR // Get 2 pairs value int pair1Value = 0; int pair2Value = 0; // Count occurances of values and put as pair1's value for (int i = 2; i < 15; i++) { if (Evaluate.ValueCount(i, hand) == 2) { pair1Value = i; break; } } // Count occurences of values and put as pair2's value for (int i = 2; i < 15; i++) { if (Evaluate.ValueCount(i, hand) == 2) { if (i == pair1Value) { continue; // make sure to ignore pair 1 } pair2Value = i; break; } } // Check if either pair's value is the high card if (pair1Value == highCard.Value || pair2Value == highCard.Value) { for (int i = 0; i < hand.Length; i++) // toss the 1 remaining card { if (hand[i].Value == pair1Value || hand[i].Value == pair2Value) { continue; } hand[i] = null; } removed = 1; } else { // Any other factors to decide what to do???? // Otherwise return a stand pat action return(new PlayerAction(Name, "Draw", "stand pat", 0)); } break; case 4: // 3-OF-A-KIND // Get the triple's value int tripleValue = 0; for (int i = 2; i < 15; i++) { if (Evaluate.ValueCount(i, hand) == 3) { tripleValue = i; break; } } // optimize chances of getting a higher hand // if the high card is not one of the triple AND it is 10-J-Q-K-A if (highCard.Value != tripleValue && highCard.Value >= 10) { for (int i = 0; i < hand.Length; i++) { if (hand[i].Value == tripleValue || hand[i].Value == highCard.Value) { continue; } hand[i] = null; } removed = 1; } else { // otherwise, toss the cards that aren't the triple and not 10-J-Q-K-A for (int i = 0; i < hand.Length; i++) { if (hand[i].Value == tripleValue) { continue; } hand[i] = null; } removed = 2; } break; // case 5: // STRAIGHT // probably not worth it to toss anything draw again, weigh this? // case 6: // FLUSH // same as STRIAGHT //case 7: // FULL HOUSE // which pair has the high card? (the triple or double?) // if the high card is of the triple // CASE 8: If 4 of a kind // if the diffent card is the high AND (10+) // weight whether or not to risk discarding the quadruple? // otherwise stand pat //case 8: // 4 of a kind // // Get Quadruple value // int quadValue = 0; // for (int i = 2; i < 15; i++) // { // if (Evaluate.ValueCount(i, hand) == 4) // when there are 4 occurances of one of the values (i) // { // pairValue = i; // break; // } // } // // // if (quadValue == highCard.Value || highCard.Value <= 10) // { // // Get rid of the other card because we can do better // for (int i = 0; i < hand.Length; i++) // { // if (hand[i].Value == quadValue) // continue; // hand[i] = null; // } // removed = 1; // } // break; case 5: case 6: case 7: case 8: case 9: // STRAIGHT FLUSH case 10: // ROYAL FLUSH // just stand pat like a winner return(new PlayerAction(Name, "Draw", "stand pat", 0)); } // otherwise, do approriate action return(new PlayerAction(Name, "Draw", "draw", removed)); }
//Handles discarding and drawing new cards public override PlayerAction Draw(Card[] hand) { PokerTournament.Card highCard; int handEval = Evaluate.RateAHand(this.Hand, out highCard); List <int> cardsToDelete = new List <int>(); List <int> pair = new List <int>(); pair = CheckPair(); PlayerAction pa = null; int discardAmount = 0; if (handEval > 4) { //Counts for the dominant suit and dominant value of the hand int[] suites = { 0, 0, 0, 0 }; int[] values = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; for (int i = 0; i < this.Hand.Length; i++) { //Add this card's suit to the count switch (this.Hand[i].Suit) { case "Club": suites[0]++; break; case "Diamond": suites[1]++; break; case "Heart": suites[2]++; break; default: suites[3]++; break; } values[this.Hand[i].Value]++; } //If we have a dominant suit (4 cards), discard any cards that aren't part of it List <int> discards = new List <int>(); for (int i = 0; i < suites.Length; i++) { //Add this card's suit to the count switch (suites[i]) { case 1: //Get the card's index if it should be discarded for (int k = 0; k < this.Hand.Length; i++) { if (this.Hand[k].Suit == "Club" && i == 0) { discards.Add(k); } else if (this.Hand[k].Suit == "Diamond" && i == 1) { discards.Add(k); } else if (this.Hand[k].Suit == "Club" && i == 2) { discards.Add(k); } else if (this.Hand[k].Suit == "Spade" && i == 3) { discards.Add(k); } } break; default: break; } } if (discards.Count > 0) { Console.WriteLine("Discarding " + discards[0].ToString()); pa = new PlayerAction(Name, "Draw", "draw", discards.Count); return(pa); } pa = new PlayerAction(Name, "Draw", "stand pat", 0); return(pa); } if (pair.Count == 0) { if (highCard.Value == 14) //If Ace { for (int i = 0; i < Hand.Length; i++) { if (Hand[i].Value != 14) { Console.WriteLine("Discarding " + Hand[i].ToString()); hand[i] = null; discardAmount++; } } } else //Otherwise keep highest two cards { PokerTournament.Card highCardOld; int handEvalNew = Evaluate.RateAHand(this.Hand, out highCardOld); Card[] handTemp = this.Hand; for (int i = 0; i < Hand.Length; i++) { if (Hand[i] == highCardOld) { handTemp[i] = new PokerTournament.Card("Spades", 2);; } } PokerTournament.Card highCardNew; handEvalNew = Evaluate.RateAHand(handTemp, out highCardNew); for (int i = 0; i < Hand.Length; i++) { if (Hand[i] == highCardOld || Hand[i] == highCardNew) { Hand[i] = null; discardAmount++; } } } pa = new PlayerAction(Name, "Draw", "draw", discardAmount); //Draws equal to discard amount return(pa); //Should keep ace or two highest cards } else { Console.WriteLine("There are " + pair.Count + " pairs, attempting to discard."); for (int r = 0; r < pair.Count; r++) { for (int i = 0; i < Hand.Length; i++) { if (Hand[i] != null) { if (!pair.Contains(Hand[i].Value)) { Console.WriteLine("Discarding " + Hand[i].ToString()); hand[i] = null; discardAmount++; } } } } } pa = new PlayerAction(Name, "Draw", "draw", discardAmount); //Draws equal to discard amount return(pa); }
public override PlayerAction Draw(Card[] hand) { int handValue = Evaluate.RateAHand(hand, out highCard); // Gets the value of the hand we have Evaluate.SortHand(hand); // Sorts hand if (handValue == 10 || handValue == 9 || handValue == 7 || handValue == 6 || handValue == 5) { Speak("I swap nothing, mortal"); return(new PlayerAction(Name, "Draw", "stand pat", 0)); } if (handValue == 8) { Speak("I swap one card"); //find card that isn't part of 4 of a kind and remove it for (int i = 2; i < 15; i++) { if (Evaluate.ValueCount(i, hand) == 4) { for (int j = 0; j < 5; j++) { if (hand[j].Value != i) { hand[j] = null; } } } } return(new PlayerAction(Name, "Draw", "draw", 1)); } if (handValue == 4) { Speak("I swap two cards"); List <int> cardsToRemove = new List <int>(); //find cards that aren't part of three of a kind and remove them for (int i = 2; i < 15; i++) { if (Evaluate.ValueCount(i, hand) == 3) { for (int j = 0; j < 5; j++) { if (hand[j].Value != i) { cardsToRemove.Add(j); //hand[j] = null; } } } } //remove the ones we need to hand[cardsToRemove[0]] = null; hand[cardsToRemove[1]] = null; //request 2 cards return(new PlayerAction(Name, "Draw", "draw", 2)); } if (handValue == 3) { Speak("I swap one card"); //find card that isn't part of either pair and remove it // Get the first pair int firstPair = 0; for (int i = 2; i < 15; i++) { if (Evaluate.ValueCount(i, hand) == 2) { firstPair = i; } } // now get the second pair int secondPair = 0; for (int i = 2; i < 15; i++) { if (i == firstPair) { continue; // skip this value } if (Evaluate.ValueCount(i, hand) == 2) { secondPair = i; } } for (int i = 0; i < 5; i++) { if (hand[i].Value != firstPair && hand[i].Value != secondPair) { hand[i] = null; } } return(new PlayerAction(Name, "Draw", "draw", 1)); } if (handValue == 2) { //find the value that is the pair int pair = 0; for (int i = 2; i < 15; i++) { if (Evaluate.ValueCount(i, hand) == 2) { pair = i; } } //find the cards that are not the pair and replace them for (int i = 0; i < 5; i++) { if (hand[i].Value != pair) { hand[i] = null; } } Speak("I swap three cards"); return(new PlayerAction(Name, "Draw", "draw", 3)); } if (handValue == 1) { Speak("I swap four cards"); //Checks for 3 or more of same suit string flushSuit = ""; int suitCount = 0; for (int i = 0; i < hand.Length; i++) { for (int j = 0; j < hand.Length; j++) { if (hand[i].Suit == hand[j].Suit && i != j) { suitCount++; } } if (suitCount >= 3) { flushSuit = hand[i].Suit; break; } } if (flushSuit != "") { int count = 0; for (int i = 0; i < 5; i++) { if (hand[i].Suit != flushSuit) { hand[i] = null; count++; } } Console.WriteLine("requesting " + (5 - count) + " new cards"); return(new PlayerAction(Name, "Draw", "draw", count)); } // checks for a hand that is almost a straight // ex: 4, 5, 7, 8, Ace| 4, 5, 6, 7, 10| // so Two in a row, then 1 missing, then Two more in a row // or Three in a row, 1 missing, then 1 // or Four in a row if (hand[0].Value == hand[1].Value - 1 && hand[0].Value == hand[2].Value - 2 && hand[0].Value == hand[3].Value - 3 && hand[0].Value != hand[4].Value - 4) { hand[4] = null; return(new PlayerAction(Name, "Draw", "draw", 1)); } else if (hand[0].Value == hand[1].Value - 1 && hand[0].Value == hand[2].Value - 2 && hand[0].Value != hand[3].Value - 3 && hand[0].Value == hand[4].Value - 4) { hand[3] = null; return(new PlayerAction(Name, "Draw", "draw", 1)); } else if (hand[0].Value == hand[1].Value - 1 && hand[0].Value != hand[2].Value - 2 && hand[0].Value == hand[3].Value - 3 && hand[0].Value == hand[4].Value - 4) { hand[2] = null; return(new PlayerAction(Name, "Draw", "draw", 1)); } else if (hand[0].Value != hand[1].Value - 1 && hand[0].Value == hand[2].Value - 2 && hand[0].Value == hand[3].Value - 3 && hand[0].Value == hand[4].Value - 4) { hand[1] = null; return(new PlayerAction(Name, "Draw", "draw", 1)); } else if (hand[1].Value != hand[2].Value - 1 && hand[1].Value == hand[3].Value - 2 && hand[1].Value == hand[4].Value - 3 && hand[1].Value == hand[0].Value + 1) { hand[0] = null; return(new PlayerAction(Name, "Draw", "draw", 1)); } else { return(new PlayerAction(Name, "Draw", "draw", 4)); } } else { return(new PlayerAction(Name, "Draw", "stand pat", 0)); } }
public override PlayerAction Draw(Card[] hand) { Card curHighCard; int curHandStrength = Evaluate.RateAHand(hand, out curHighCard); bool takeASmallRisk = false; bool takeABigRisk = false; //Determine if we need to take a risk if (estimatedEnemyHand > 0.15f && estimatedEnemyHand <= 0.35f) { takeASmallRisk = true; } else if (estimatedEnemyHand > 0.35f) { takeASmallRisk = true; takeABigRisk = true; } //Decision Tree (if statements for now) PlayerAction pa = null; List <int> deleteIndices = new List <int>(); if (curHandStrength >= 5) //Do we have a strong hand? { if (curHandStrength >= 7) //Is it almost unbeatable? { if (curHandStrength == 8) //Is it a 4 of a kind? { if (curHighCard.Value > 10) //Get rid of a low high card { pa = new PlayerAction(Name, "Draw", "stand pat", 0); } else { DeleteCards(hand, UnmatchingCards(hand, 4)); pa = new PlayerAction(Name, "Draw", "draw", 1); } } else //Nothing to get rid of that wouldn't ruin the hand { pa = new PlayerAction(Name, "Draw", "stand pat", 0); } } else { if (takeABigRisk) //Do we need to take a risk? { if (curHandStrength == 5) //Is it a straight? { if (SimilarSuitedCards(hand, out deleteIndices) == 4) //Is it almost a flush? { DeleteCards(hand, deleteIndices); pa = new PlayerAction(Name, "Draw", "draw", 1); } else { pa = new PlayerAction(Name, "Draw", "stand pat", 0); } } else { if (ConsecutiveCards(hand, out deleteIndices) == 4) //Is it almost a straight flush? { DeleteCards(hand, deleteIndices); pa = new PlayerAction(Name, "Draw", "draw", 1); } else { pa = new PlayerAction(Name, "Draw", "stand pat", 0); } } } else { pa = new PlayerAction(Name, "Draw", "stand pat", 0); } } } else { if (takeASmallRisk) //Do we need to take a risk? { if (curHandStrength > 2) //Is it a medium strength hand? { if (curHandStrength == 4) //Is it a 3 of a kind? { DeleteCards(hand, UnmatchingCards(hand, 3)); pa = new PlayerAction(Name, "Draw", "stand pat", 2); } else { if (SimilarSuitedCards(hand, out deleteIndices) >= 3) //Is it almost a flush? { DeleteCards(hand, deleteIndices); pa = new PlayerAction(Name, "Draw", "draw", deleteIndices.Count); } else if (ConsecutiveCards(hand, out deleteIndices) >= 3) //Is it almost a straight? { DeleteCards(hand, deleteIndices); pa = new PlayerAction(Name, "Draw", "draw", deleteIndices.Count); } else // Ditch the 5th card { hand[OddCardOut(hand)] = null; pa = new PlayerAction(Name, "Draw", "stand pat", 1); } } } else { if (SimilarSuitedCards(hand, out deleteIndices) >= 3) //Is it almost a flush? { DeleteCards(hand, deleteIndices); pa = new PlayerAction(Name, "Draw", "draw", deleteIndices.Count); } else if (ConsecutiveCards(hand, out deleteIndices) >= 3) //Is it almost a straight? { DeleteCards(hand, deleteIndices); pa = new PlayerAction(Name, "Draw", "draw", deleteIndices.Count); } else { if (curHandStrength == 2) //Is it a pair? { DeleteCards(hand, UnmatchingCards(hand, 2)); pa = new PlayerAction(Name, "Draw", "draw", 3); } else //Ditch all but the high card { for (int i = 0; i < hand.Length; i++) { if (i != 4) { hand[i] = null; } } pa = new PlayerAction(Name, "Draw", "draw", 4); } } } } else { if (curHandStrength > 2) //Is it a medium strength hand? { if (curHandStrength == 4) //Is it a 3 of a kind? { //Find the high card of the 2 remaining, discard the lower List <int> tempCardList = UnmatchingCards(hand, 3); int deleteIndex = 0; foreach (int i in tempCardList) { if (deleteIndex == 0) { deleteIndex = i; } else { if (hand[deleteIndex].Value > hand[i].Value) { hand[i] = null; } else { hand[deleteIndex] = null; } } } pa = new PlayerAction(Name, "Draw", "draw", 1); } else //If a two pair, ditch the 5th card { hand[OddCardOut(hand)] = null; pa = new PlayerAction(Name, "Draw", "stand pat", 1); } } else { if (curHandStrength == 2) //If a pair, lose the other 3 { DeleteCards(hand, UnmatchingCards(hand, 2)); pa = new PlayerAction(Name, "Draw", "draw", 3); } else //Discard all but the high card { for (int i = 0; i < hand.Length; i++) { if (i != 4) { hand[i] = null; } } pa = new PlayerAction(Name, "Draw", "draw", 4); } } } } // return the action return(pa); }
public override PlayerAction BettingRound1(List <PlayerAction> actions, Card[] hand) { PokerTournament.Card highCard; int handEval = Evaluate.RateAHand(this.Hand, out highCard); int pot = CurrentPot(actions, "Bet1"); int betAmount = GetCurrentBet(actions, "Bet1"); float odds = CalculatePotOdds(betAmount, pot); float returnRate = CalculateRateOfReturn(handEval, odds); float chance = rand.Next(0, 100); Console.WriteLine("Return rate: " + returnRate); Console.WriteLine("Chance: " + chance); if (returnRate < 0.8) { if (chance > 94) { return(new PlayerAction(Name, "Bet1", "raise", betAmount)); } else { return(new PlayerAction(Name, "Bet1", "fold", 0)); } } else if (returnRate < 1) { if (chance > 94) { return(new PlayerAction(Name, "Bet1", "call", 0)); } else if (chance > 79) { return(new PlayerAction(Name, "Bet1", "raise", betAmount)); } else { return(new PlayerAction(Name, "Bet1", "fold", 0)); } } else if (returnRate < 1.3) { if (chance > 70) { return(new PlayerAction(Name, "Bet1", "call", 0)); } else { return(new PlayerAction(Name, "Bet1", "raise", betAmount)); } } int res; if (returnRate > 0 && returnRate != float.PositiveInfinity) { float fres = betAmount * (returnRate); res = (int)fres; } else { res = 5 * handEval; } return(new PlayerAction(Name, "Bet1", "bet", res)); //return new PlayerAction(Name, "Bet1", "bet", betAmount); //throw new NotImplementedException(); }
public override PlayerAction BettingRound1(List <PlayerAction> actions, Card[] hand) { //order hand first Evaluate.SortHand(hand); // convert hand to inner class refHand = ConvertHandToRefCards(hand); // get rank of current hand and highest card Card highCard = null; int currentRank = Evaluate.RateAHand(hand, out highCard); if (currentRank < 2) // check for at least a potential pair { currentRank = 2; } // based on current rank, loop through and evaluate all possible hand types and determine most likely PossibilityLevel bestChance = PossibilityLevel.Impossible; PossibilityLevel currentChance; for (int i = currentRank; i < 11; i++) { currentChance = CheckForHandOfRank(i, refHand); // get chance of current hand if (currentChance < bestChance) // if current chance is better than current best, reassign { rankOfTargetHands.Clear(); // clear old bests bestChance = currentChance; // overwrite best rankOfTargetHands.Add(i); // add new best hand by their rank } else if (currentChance == bestChance) // if equally as good { rankOfTargetHands.Add(i); // add both target ranks } } // loop through target hand indices determine which is most likely if (rankOfTargetHands.Count > 1) { var evaluateNumBest = -1; //best hand to have a chance of drawing foreach (int targetRank in rankOfTargetHands) // resolve conflict { // determine which rank is more likely -- NPAR // determine based on pot size/money total int evaluateNum = targetRank; // how likely this hand is to draw int numOfCard = ChanceOfCardsNeeded(evaluateNum); //number of possible cards that could be drawn to get hand for (int i = 0; i < (int)bestChance; i++) //number that will be thrown away { if (numOfCard - i <= 0) //add extra chances for drawing correct card { evaluateNum *= numOfCard; } else {//have to draw correct cards evaluateNum *= (numOfCard - i); } } // assign target rank if (evaluateNum > evaluateNumBest)//there is a better chance of getting this hand { targetHandRank = targetRank; evaluateNumBest = evaluateNum; } else if (evaluateNum == evaluateNumBest && targetRank > targetHandRank)//same chance of happening and targetRank is better than target hand { targetHandRank = targetRank; } } } else if (rankOfTargetHands.Count == 1)//only one in array, have to go for that one { targetHandRank = rankOfTargetHands[0]; } else//catch if list is empty { targetHandRank = 0; } // get total amount of discards int discardingTotal = GetTotalDiscardsForHandRank(targetHandRank); // Determine bet/bluff action -- KPAR, NPRO Boolean bluffing = determineBluff(); // return appropriate PlayerAction object int amountPlaced = 0; string actionTaken = determinePlayerAction(currentRank, actions, bluffing, out amountPlaced);//the player action that will be taken for this turn return(new PlayerAction(Name, "Bet1", actionTaken, amountPlaced)); }
public override PlayerAction Draw(Card[] hand) { /// Keeping it super rudimentary /// Fuzzy logic might be better here /// But since every rank corresponds with a different set of cards (IE: 1 = high card, 2 = Two pair, 10 is always = Royal Flush), 10 if statements are easier to manage imo /// PlayerAction pa = new PlayerAction(Name, "Draw", "stand pat", 0); // Print out the hand so we can see it //ListTheHand(hand); Console.WriteLine("\n"); // The first thing we should do is to evaluate our hand Card highCard = null; int rank = Evaluate.RateAHand(hand, out highCard); // If you have nothing switch (rank) { case 1: // You have nothing; #region Section 1 (High Card) Console.WriteLine("\n AI didn't like their hand."); // If your high is 10 or greater, then get rid of everything but the 10+ // Otherwise, dump everything and redraw if (highCard.Value >= 10) { for (int i = 0; i < hand.Length; i++) { if (hand[i] == highCard) { continue; } hand[i] = null; } pa = new PlayerAction(Name, "Draw", "draw", 4); Console.WriteLine("\n AI Discarded 4 cards, and kept their high card"); } else { // Dump! for (int i = 0; i < hand.Length; i++) { hand[i] = null; } pa = new PlayerAction(Name, "Draw", "draw", 5); Console.WriteLine("\n AI Discarded all 5 cards."); } #endregion break; case 2: // We have exactly a 1 pair #region Section 2 (Single Pair) // First identify what number of a pair we have int pairValue = 0; for (int i = 2; i < 15; i++) // Loop through every possible card number { if (Evaluate.ValueCount(i, hand) == 2) // Thankfully we have this method { pairValue = i; break; } } // We know which number it is // If our high card is 10 or higher, we'll want to dump every card, except for the high card and our double if (highCard.Value >= 10 && highCard.Value != pairValue) // Also check to make sure our high card isn't actually our pairValue. If it is then we'll just dump everything except for the pair { for (int i = 0; i < hand.Length; i++) { if (hand[i].Value == pairValue || hand[i].Value == highCard.Value) { continue; } hand[i] = null; } pa = new PlayerAction(Name, "Draw", "draw", 2); Console.WriteLine("\n AI has a 2 pair and has discarded everything but the 2 pair and their high card."); } else { // If our high card isn't 10 or higher, then dump every card except for the high cards // Dump! for (int i = 0; i < hand.Length; i++) { if (hand[i].Value == pairValue) { continue; } hand[i] = null; } pa = new PlayerAction(Name, "Draw", "draw", 3); Console.WriteLine("\n AI has a 2 pair and has discarded everything but the 2 pair."); } #endregion break; case 3: // We have two pairs! #region Section 3 (Two Pairs) // Ok first thing we need to do is to figure out which numbers are the two pair int pairValue1 = 0; int pairValue2 = 0; for (int i = 2; i < 15; i++) // Loop through every possible card number { if (Evaluate.ValueCount(i, hand) == 2) { pairValue1 = i; break; } } // Do it again and get the second one for (int i = 2; i < 15; i++) // Loop through every possible card number { if (Evaluate.ValueCount(i, hand) == 2) { if (i == pairValue2) { continue; } pairValue2 = i; break; } } if (pairValue1 == highCard.Value || pairValue2 == highCard.Value) { // Dump the other card and hope for a higher card for (int i = 0; i < hand.Length; i++) { if (hand[i].Value == pairValue1 || hand[i].Value == pairValue2) { continue; } hand[i] = null; pa = new PlayerAction(Name, "Draw", "draw", 1); } } else { // Keep it! Your hand is good! pa = new PlayerAction(Name, "Draw", "stand pat", 0); } #endregion break; case 4: // Three of a kind #region Section 4 (Three of a Kind) // Pretty simple. Exactly the same as 1 pair except that it's with 3 // First identify what number of a pair we have int triValue = 0; for (int i = 2; i < 15; i++) // Loop through every possible card number { if (Evaluate.ValueCount(i, hand) == 3) // Thankfully we have this method { pairValue = i; break; } } // We know which number it is // If our high card is 10 or higher, we'll want to dump every card, except for the high card and our tripple if (highCard.Value >= 10 && highCard.Value != triValue) // Also check to make sure our high card isn't actually our trieValue. If it is then we'll just dump everything except for the tripple { for (int i = 0; i < hand.Length; i++) { if (hand[i].Value == triValue || hand[i].Value == highCard.Value) { continue; } hand[i] = null; } pa = new PlayerAction(Name, "Draw", "draw", 1); Console.WriteLine("\n AI has a tripple and has discarded everything but the 3 of a kind and their high card."); } else { // If our high card isn't 10 or higher, then dump every card except for the high cards // Dump! for (int i = 0; i < hand.Length; i++) { if (hand[i].Value == triValue) { continue; } hand[i] = null; } pa = new PlayerAction(Name, "Draw", "draw", 2); Console.WriteLine("\n AI has a 3 of a kind and has discarded everything but the tripple."); } #endregion break; // There's no reason for a case. Case 5 is a stroke, and we stand pat if we have a stroke case 8: // 4 of a kind #region Section 8 (Four of a Kind) // Check to see if our high is high enough. If it isn't drop it and as for another. int theQuadNumber = hand[3].Value; if (theQuadNumber == highCard.Value || highCard.Value <= 10) { // Get rid of the other card because we can do better for (int i = 0; i < hand.Length; i++) { if (hand[i].Value == theQuadNumber) { continue; } hand[i] = null; } pa = new PlayerAction(Name, "Draw", "draw", 1); } #endregion break; // Any other selection is just a hold hand because we don't want to drop anything } return(pa); }
// plays 1 round of poker private string Round() { string text = ""; // result text List <PlayerAction> actions = new List <PlayerAction>(); // list of actions // reset the pot if (pot % 2 == 0) // even numbered pot { pot = anteAmt; // pot with antes only } else // odd pot { // in this case, the pot was not an even number // so there was 1 credit left over for the starting pot // In theory this should never happen. pot = anteAmt + 1; } // call players in order Player[] playerOrder = new Player[2]; // note that playerOrder[1] always contains the dealer if (p0.Dealer == true) // player 0 deals? { playerOrder[0] = p1; // p1 goes first playerOrder[1] = p0; } else { playerOrder[0] = p0; // p0 goes first playerOrder[1] = p1; } // setup deck for a new round deck.NewRound(); // dealer deals out 5 cards to each player playerOrder[0].Hand = deck.Deal(5); playerOrder[1].Hand = deck.Deal(5); // round 1 of betting - loop until both players check, // one folds, or one calls ResultWriter("Betting round 1:"); Boolean done = false; // flags when finished do { PlayerAction pa0 = playerOrder[0].BettingRound1(actions, playerOrder[0].Hand); bool valid = CheckAction("Bet1", actions, pa0); if (valid == false) { ResultWriter(playerOrder[0].Name + " played a bad action of " + pa0.ActionName + " and forfeits the hand"); pa0 = new PlayerAction(pa0.Name, pa0.ActionPhase, "fold", 0); } actions.Add(pa0); ResultWriter(pa0.ToString()); ResultWriter(" "); // handle the case of the first player calling - the // second player must also call - do this automatically // and break out of the loop if (pa0.ActionName == "call") { // add the second player's action automatically PlayerAction pa1 = new PlayerAction(playerOrder[1].Name, "Bet1", "call", 0); actions.Add(pa1); break; // done betting } if (pa0.ActionName != "fold") // first player did not fold { PlayerAction pa1 = playerOrder[1].BettingRound1(actions, playerOrder[1].Hand); valid = CheckAction("Bet1", actions, pa1); if (valid == false) { ResultWriter(playerOrder[1].Name + " played a bad action of " + pa1.ActionName + " and forfeits the hand"); pa1 = new PlayerAction(pa1.Name, pa1.ActionPhase, "fold", 0); } actions.Add(pa1); ResultWriter(pa1.ToString()); ResultWriter(" "); } done = EvaluateActions(actions, "Bet1"); } while (done == false); // update the pot based on the bets int lastBet = 0; for (int i = 0; i < actions.Count; i++) { if (actions[i].ActionPhase == "Bet1") { switch (actions[i].ActionName) { case "bet": lastBet = actions[i].Amount; pot += lastBet; // adjust the pot // deduct from player if (actions[i].Name == playerOrder[0].Name) // player0 bet? { playerOrder[0].ChangeMoney(-lastBet); } else // must be player1 { playerOrder[1].ChangeMoney(-lastBet); } break; case "raise": int total = lastBet; // amt from previous player pot += lastBet; // player raising must match last bet lastBet = actions[i].Amount; total += lastBet; // amt being raised pot += lastBet; // plus the amount raised // deduct from player if (actions[i].Name == playerOrder[0].Name) // player0 bet? { playerOrder[0].ChangeMoney(-total); } else // must be player1 { playerOrder[1].ChangeMoney(-total); } break; case "call": // skip if this is a call after another call if (i - 1 >= 0) { if (actions[i - 1].ActionName == "call") { break; } } pot += lastBet; // match the last bet // deduct from player if (actions[i].Name == playerOrder[0].Name) // player0 bet? { playerOrder[0].ChangeMoney(-lastBet); } else // must be player1 { playerOrder[1].ChangeMoney(-lastBet); } break; } } } ResultWriter("After Bet1, pot is " + pot); ResultWriter(" "); // see if someone folded if (actions[actions.Count - 1].ActionName == "fold" && actions[actions.Count - 1].Name == playerOrder[1].Name) { // if the player in playerOrder[1] folded, other // player gets the pot playerOrder[0].ChangeMoney(pot); string result = actions[actions.Count - 1].Name + " folded. Other player gets the pot of " + pot; pot = 0; // clear the pot return(result); // skip rest of loop } else if (actions[actions.Count - 1].ActionName == "fold" && actions[actions.Count - 1].Name == playerOrder[0].Name) { // if the player in playerOrder[1] folded, other // player gets the pot playerOrder[1].ChangeMoney(pot); string result = actions[actions.Count - 1].Name + " folded. Other player gets the pot of " + pot; pot = 0; // clear the pot return(result); // skip rest of loop } // draw for (int i = 0; i < playerOrder.Length; i++) { PlayerAction pa = playerOrder[i].Draw(playerOrder[i].Hand); actions.Add(pa); if (pa.Amount > 0) { Card[] newCards = deck.Deal(pa.Amount); // get cards playerOrder[i].AddCards(playerOrder[i].Hand, newCards); } ResultWriter("Name: " + playerOrder[i].Name); string handList = Evaluate.ListHand(playerOrder[i].Hand); ResultWriter(handList); ResultWriter(" "); } // round 2 of betting- loop until both players check, // one folds, or one calls ResultWriter("Betting round 2:"); done = false; // flags when finished do { PlayerAction pa0 = playerOrder[0].BettingRound2(actions, playerOrder[0].Hand); bool valid = CheckAction("Bet2", actions, pa0); if (valid == false) { ResultWriter(playerOrder[0].Name + " played a bad action of " + pa0.ActionName + " and forfeits the hand"); pa0 = new PlayerAction(pa0.Name, pa0.ActionPhase, "fold", 0); } actions.Add(pa0); ResultWriter(pa0.ToString()); ResultWriter(" "); // handle the case of the first player calling - the // second player must also call - do this automatically // and break out of the loop if (pa0.ActionName == "call") { // add the second player's action automatically PlayerAction pa1 = new PlayerAction(playerOrder[1].Name, "Bet2", "call", 0); actions.Add(pa1); break; // done betting } if (pa0.ActionName != "fold") // first player did not fold { PlayerAction pa1 = playerOrder[1].BettingRound2(actions, playerOrder[1].Hand); valid = CheckAction("Bet2", actions, pa1); if (valid == false) { ResultWriter(playerOrder[1].Name + " played a bad action of " + pa1.ActionName + " and forfeits the hand"); pa1 = new PlayerAction(pa1.Name, pa1.ActionPhase, "fold", 0); } actions.Add(pa1); ResultWriter(pa1.ToString()); ResultWriter(" "); } done = EvaluateActions(actions, "Bet2"); } while (done == false); // update the pot based on the bets lastBet = 0; for (int i = 0; i < actions.Count; i++) { if (actions[i].ActionPhase == "Bet2") { switch (actions[i].ActionName) { case "bet": lastBet = actions[i].Amount; pot += lastBet; // adjust the pot // deduct from player if (actions[i].Name == playerOrder[0].Name) // player0 bet? { playerOrder[0].ChangeMoney(-lastBet); } else // must be player1 { playerOrder[1].ChangeMoney(-lastBet); } break; case "raise": int total = lastBet; // amt from previous player pot += lastBet; // player raising must match last bet lastBet = actions[i].Amount; total += lastBet; // amt being raised pot += lastBet; // plus the amount raised // deduct from player if (actions[i].Name == playerOrder[0].Name) // player0 bet? { playerOrder[0].ChangeMoney(-total); } else // must be player1 { playerOrder[1].ChangeMoney(-total); } break; case "call": // skip if this is a call after another call if (i - 1 >= 0) { if (actions[i - 1].ActionName == "call") { break; } } pot += lastBet; // match the last bet // deduct from player if (actions[i].Name == playerOrder[0].Name) // player0 bet? { playerOrder[0].ChangeMoney(-lastBet); } else // must be player1 { playerOrder[1].ChangeMoney(-lastBet); } break; } } } ResultWriter("After Bet2, pot is " + pot); ResultWriter(" "); // see if someone folded if (actions[actions.Count - 1].ActionName == "fold" && actions[actions.Count - 1].Name == playerOrder[1].Name) { // if the player in playerOrder[1] folded, other // player gets the pot playerOrder[0].ChangeMoney(pot); string result = actions[actions.Count - 1].Name + " folded. Other player gets the pot of " + pot; pot = 0; // clear the pot return(result); // skip rest of loop } else if (actions[actions.Count - 1].ActionName == "fold" && actions[actions.Count - 1].Name == playerOrder[0].Name) { // if the player in playerOrder[1] folded, other // player gets the pot playerOrder[1].ChangeMoney(pot); string result = actions[actions.Count - 1].Name + " folded. Other player gets the pot of " + pot; pot = 0; // clear the pot return(result); // skip rest of loop } // round resolution // see if there is a clear winner based on hand strength Card highCard = null; int p0Rank = Evaluate.RateAHand(playerOrder[0].Hand, out highCard); int p1Rank = Evaluate.RateAHand(playerOrder[1].Hand, out highCard); if (p0Rank > p1Rank) { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); pot = 0; } else if (p1Rank > p0Rank) { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); pot = 0; } else // same rank - needs further examination { // sort both hands Evaluate.SortHand(playerOrder[0].Hand); Card[] hand0 = playerOrder[0].Hand; Evaluate.SortHand(playerOrder[1].Hand); Card[] hand1 = playerOrder[1].Hand; switch (p0Rank) { case 1: // high card for (int i = 4; i >= 0; i--) { if (hand0[i].Value != hand1[i].Value) { if (hand0[i].Value > hand1[i].Value) { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); pot = 0; } else if (hand1[i].Value > hand0[i].Value) { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); pot = 0; } } } // could be a tie if (pot != 0) { playerOrder[0].ChangeMoney(pot / 2); playerOrder[1].ChangeMoney(pot / 2); text = "Tie, each player gets " + pot / 2; if (pot % 2 != 0) { pot = 1; } else { pot = 0; } } break; case 2: // one pair // get the pair for playerOrder[0] int p0Pair = 0; for (int j = 14; j >= 2; j--) { int count = Evaluate.ValueCount(j, hand0); if (count == 2) // found the pair { p0Pair = j; break; } } // do the same for the other hand int p1Pair = 0; for (int k = 14; k >= 2; k--) { int count = Evaluate.ValueCount(k, hand1); if (count == 2) // found the pair { p1Pair = k; break; } } // which is higher if (p0Pair > p1Pair) // playerOrder[0] wins { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); } else if (p1Pair > p0Pair) { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); } else { // need to see what the high // card is aside from the pair // get the cards that are not part of a pair from hand0 Card[] h0NotPair = new Card[3]; int pos = 0; for (int i = 0; i < hand0.Length; i++) { if (hand0[i].Value != p0Pair) { h0NotPair[pos] = hand0[i]; pos++; } } // do the same for the next hand Card[] h1NotPair = new Card[3]; pos = 0; for (int i = 0; i < hand1.Length; i++) { if (hand1[i].Value != p1Pair) { h1NotPair[pos] = hand1[i]; pos++; } } // see if high card breakes the tie for (int i = 2; i >= 0; i--) { if (h0NotPair[i].Value != h1NotPair[i].Value) { if (h0NotPair[i].Value > h1NotPair[i].Value) { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); pot = 0; } else if (h1NotPair[i].Value > h0NotPair[i].Value) { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); pot = 0; } } } // could be a tie if (pot != 0) { playerOrder[0].ChangeMoney(pot / 2); playerOrder[1].ChangeMoney(pot / 2); text = "Tie, each player gets " + pot / 2; if (pot % 2 != 0) { pot = 1; } else { pot = 0; } } } break; case 3: // two pair // get the two pair int[] h0Pair = new int[2]; int[] h1Pair = new int[2]; // get hand0 pairs int pCount = 0; for (int i = 14; i >= 2; i--) { int count = Evaluate.ValueCount(i, hand0); if (count == 2) // found the pair { h0Pair[pCount] = i; pCount++; } } // get the hand1 pairs pCount = 0; for (int i = 14; i >= 2; i--) { int count = Evaluate.ValueCount(i, hand1); if (count == 2) // found the pair { h1Pair[pCount] = i; pCount++; } } // compare the pairs if (h0Pair[0] > h1Pair[0]) // playerOrder[0] wins { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); } else if (h1Pair[0] > h0Pair[0]) // playerOrder[1] wins { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); pot = 0; } else // tie on the highest pair { // compare the second pair if (h0Pair[1] > h1Pair[1]) // playerOrder[0] wins { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); pot = 0; } else if (h1Pair[0] > h0Pair[0]) // playerOrder[1] wins { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); pot = 0; } else // tie on the highest pair { playerOrder[0].ChangeMoney(pot / 2); playerOrder[1].ChangeMoney(pot / 2); text = "Tie, each player gets " + pot / 2; // tie overall if (pot % 2 != 0) { pot = 1; } else { pot = 0; } } } break; case 4: // three of a kind // get the pair for playerOrder[0] int p0Three = 0; for (int j = 14; j >= 2; j--) { int count = Evaluate.ValueCount(j, hand0); if (count == 3) // found the pair { p0Three = j; break; } } // do the same for the other hand int p1Three = 0; for (int k = 14; k >= 2; k--) { int count = Evaluate.ValueCount(k, hand1); if (count == 3) // found the three cards { p1Three = k; break; } } // which is higher - no possibility of a tie if (p0Three > p1Three) // playerOrder[0] wins { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); } else { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); } pot = 0; break; case 5: // straight // compare the top card - if one is higher than the other, that // player is the winner. Otherwise, there is a tie if (hand0[0].Value > hand1[0].Value) { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); pot = 0; } else if (hand1[0].Value > hand0[0].Value) { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); pot = 0; } else // tie { playerOrder[0].ChangeMoney(pot / 2); playerOrder[1].ChangeMoney(pot / 2); text = "Tie, each player gets " + pot / 2; if (pot % 2 != 0) { pot = 1; } else { pot = 0; } } break; case 6: // flush // locate the high cards and keep testing until you // either have a tie or a winner // tie flag Boolean tie = true; for (int i = 4; i >= 0; i--) { if (hand0[i].Value != hand1[i].Value) { // determine the winner if (hand0[i].Value > hand1[i].Value) { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); pot = 0; } else { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); pot = 0; } // not a tie tie = false; break; // exit loop } } // handle a tie if (tie == true) { playerOrder[0].ChangeMoney(pot / 2); playerOrder[1].ChangeMoney(pot / 2); text = "Tie, each player gets " + pot / 2; if (pot % 2 != 0) { pot = 1; } else { pot = 0; } } break; case 7: // full house // get the two pair int h0FH = 0; int h1FH = 0; // get hand0 triple for (int i = 14; i >= 2; i--) { int count = Evaluate.ValueCount(i, hand0); if (count == 3) // found the triple { h0FH = i; } } // get the hand1 triple for (int i = 14; i >= 2; i--) { int count = Evaluate.ValueCount(i, hand1); if (count == 3) // found the triple { h1FH = i; } } // compare the triples if (h0FH > h1FH) // playerOrder[0] wins { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); } else // playerOrder[1] wins { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); } pot = 0; break; case 8: // four of a kind // get the pair for playerOrder[0] int p0Four = 0; for (int j = 14; j >= 2; j--) { int count = Evaluate.ValueCount(j, hand0); if (count == 4) // found the 4 cards { p0Four = j; break; } } // do the same for the other hand int p1Four = 0; for (int k = 14; k >= 2; k--) { int count = Evaluate.ValueCount(k, hand1); if (count == 4) // found the pair { p1Four = k; break; } } // which is higher - no possible tie if (p0Four > p1Four) // playerOrder[0] wins { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); } else { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); } pot = 0; break; case 9: // straight flush // compare the top card - if one is higher than the other, that // player is the winner. Otherwise, there is a tie if (hand0[4].Value > hand1[4].Value) { text = playerOrder[0].Name + " has a better hand and wins " + pot; playerOrder[0].ChangeMoney(pot); pot = 0; } else if (hand1[4].Value > hand0[4].Value) { text = playerOrder[1].Name + " has a better hand and wins " + pot; playerOrder[1].ChangeMoney(pot); pot = 0; } else // tie { playerOrder[0].ChangeMoney(pot / 2); playerOrder[1].ChangeMoney(pot / 2); text = "Tie, each player gets " + pot / 2; if (pot % 2 == 0) { pot = 1; } else { pot = 0; } } break; case 10: // royal flush // automatic tie - split the pot playerOrder[0].ChangeMoney(pot / 2); playerOrder[1].ChangeMoney(pot / 2); text = "Tie, each player gets " + pot / 2; if (pot % 2 != 0) { pot = 1; } else { pot = 0; } break; } } // return results return(text); }
public override PlayerAction BettingRound1(List <PlayerAction> actions, Card[] hand) { //display the hand //ListTheHand(hand); //get the suits and values of the cards GetSuitsValues(hand); Card highCard; int handValue = Evaluate.RateAHand(hand, out highCard); int moneyAvailable; int moneyToBet = 0; // 1 - 10 how agressive the betting will be int aggression = 0; //if this is the first or second action, it is this players first action of the round if (actions.Count <= 1) { //reset the money bet since it is a new round moneyBet = 0; r1MaxBet = 0; //determine the maximum bet //if the high card is in the low half of cards if (highCard.Value < 8) { r1MaxBet = 5 + 10 * (handValue - 1); } //high half of the values else { r1MaxBet = 10 + 10 * (handValue - 1); } //make sure that we are not exceeding the money that we have when trying to bet if (Money < r1MaxBet) { r1MaxBet = Money; atLimit = true; } else { atLimit = false; } //set the aggression level of the Player if (handValue == 1) { aggression = 1 + (highCard.Value - 2) / 5; } else if (handValue == 2) { //find the value of the pair for (int i = 12; i >= 0; i--) { if (values[i] == 2) { highHandValue = i; } } aggression = 4 + highHandValue / 5; } else if (handValue == 3) { //find the value of the higher pair for (int i = 12; i >= 0; i--) { if (values[i] == 2) { highHandValue = i; } } aggression = 7 + highHandValue / 5; } else { aggression = 10; } } //check to see if they are going first if (actions.Count == 0) { if (aggression <= 2) { return(new PlayerAction(name, "Bet1", "check", 0)); } else { //use random to find the next //high bet if (r.Next(3, 11) <= aggression) { moneyBet += 10; return(new PlayerAction(name, "Bet1", "bet", 10)); } //low bet else if (r.Next(1, 4) <= aggression) { moneyBet += 5; return(new PlayerAction(name, "Bet1", "bet", 5)); } //check to pass else { return(new PlayerAction(name, "Bet1", "check", 0)); } } } //if the player is not making the first move, it is following a move from the opponent else { //store the last action PlayerAction lastAction = actions[actions.Count - 1]; ///----------Check------------------------------------------------------------------ //if the last action was a check if (lastAction.ActionName == "check") { //if we are at the money limit, don't raise to same money for second bet if (atLimit) { return(new PlayerAction(name, "Bet1", "check", 0)); } //if we are not at our money limit we should try and make bets else { //get the money avaiable to bet moneyAvailable = r1MaxBet - moneyBet; //high bet if (r.Next(4, 11) <= aggression && moneyAvailable > 10) { moneyAvailable -= 10; moneyToBet = 10 + r.Next(moneyAvailable / 2, moneyAvailable * 3 / 4); moneyBet += moneyToBet; return(new PlayerAction(name, "Bet1", "bet", moneyToBet)); } //low bet else if (r.Next(1, 5) <= aggression && moneyAvailable > 5) { moneyAvailable -= 5; moneyToBet = 5 + r.Next(moneyAvailable / 2); moneyBet += moneyToBet; return(new PlayerAction(name, "Bet1", "bet", moneyToBet)); } //check to end the betting else { return(new PlayerAction(name, "Bet1", "check", 0)); } } } ///----------Call------------------------------------------------------------------ //the opponent called the players raise, the only valid move is to call else if (lastAction.ActionName == "call") { return(new PlayerAction(name, "Bet1", "call", 0)); } ///----------Raise/Bet------------------------------------------------------------------ //bet and raise are handled the same way else if (lastAction.ActionName == "raise" || lastAction.ActionName == "bet") { //adjust money the player has bet since there has been a raise/bet moneyBet += lastAction.Amount; //get the amount of money the player has to bet moneyAvailable = r1MaxBet - moneyBet; //check to see if the opponents raise will goes over the max bet set, but if the value bet is insignificant to our maximum, call the bet if (lastAction.Amount > moneyAvailable && lastAction.Amount <= Math.Max(r1MaxBet * .15, 15)) { return(new PlayerAction(name, "Bet1", "call", 0)); } //if we are at our money limit and reaching our raise max, call to end betting to try and win and not lose money from the initial ante else if (moneyAvailable < r1MaxBet * 3 / 4 && atLimit) { return(new PlayerAction(name, "Bet1", "call", 0)); } //if the amount that the opponent has bet exceeds the limit that has been placed and is significant (isnt caught in the last check), fold the hand else if (lastAction.Amount > moneyAvailable) { return(new PlayerAction(name, "Bet1", "fold", 0)); } //we still have money to bet and the last amount does not exceed it (caught before reaching here) else { //high bet if (r.Next(3, 11) <= aggression && moneyAvailable > 10) { moneyAvailable -= 10; //adjust the amount to bet by the amount that the opponent placed last turn, so the bet is limited and will not "scare" the opponent //if the bet that would be placed would be too high moneyToBet = 10 + (int)(r.Next(moneyAvailable / 2, moneyAvailable) * Math.Min(((float)lastAction.Amount / (float)moneyAvailable), 1.0f)); moneyBet += moneyToBet; return(new PlayerAction(name, "Bet1", "raise", moneyToBet)); } //low bet else if (r.Next(1, 5) <= aggression && moneyAvailable > 5) { moneyAvailable -= 5; //adjust the amount to bet by the amount that the opponent placed last turn, so the bet is limited and will not "scare" the opponent //if the bet that would be placed would be too high moneyToBet = 5 + (int)(r.Next(moneyAvailable * 1 / 4, moneyAvailable / 2) * Math.Min(((float)lastAction.Amount / (float)moneyAvailable), 1.0f)); moneyBet += moneyToBet; return(new PlayerAction(name, "Bet1", "raise", moneyToBet)); } //now decide to call the raise that was made since the player is not placing a high or low bet else { return(new PlayerAction(name, "Bet1", "call", 0)); } } } //no fold scenario since a fold will end the round before coming here } //Console.WriteLine("didnt catch"); return(new PlayerAction(name, "Bet1", "fold", 0)); }
public override PlayerAction BettingRound2(List <PlayerAction> actions, Card[] hand) { Console.WriteLine("-> in ai betting round 2"); // evaluate the hand Card highCard = null; int handStrength = Evaluate.RateAHand(hand, out highCard); //setup action Actions action = Actions.BET; PlayerAction pa = null; Random rng = new Random(); //keep track of float amount = 0; int risk = 0; int act = 0; bool isFirst = true; float riskTaking = rng.Next(100); //low=take no risk -- high=take much risk //probably replace with calculated value based on overall game //get previous bet for (int i = actions.Count - 1; i > 0; i--) { if (actions[i].ActionPhase == "Bet1" && (actions[i].ActionName == "bet" || (actions[i].ActionName == "call") || (actions[i].ActionName == "raise"))) { previousBet = currentBet = actions[i].Amount; //update last bet (round 1 bet) break; } } //check if first if (actions[actions.Count - 1].ActionPhase == "Draw") //if was just in last phase { if (actions[actions.Count - 1].Name == Name) //if ai went last { isFirst = false; } } //check hand strength and decide on move if (handStrength == 1 || handStrength == 2) { if (riskTaking < 100 * 1 / 6) { action = Actions.FOLD; Console.WriteLine("AI gives in and folds"); } else if (riskTaking < 100 * 4 / 6) { action = Actions.CHECK; Console.WriteLine("AI plays it safe and checks"); } else if (riskTaking < 100 * 5 / 6) { act = rng.Next(3); //2/3 chance of folding if (act == 0) { action = Actions.CHECK; } else if (act == 1) { action = Actions.CHECK; } else if (act == 2) { amount = Bet(isFirst, handStrength, previousBet, riskTaking, out action); } Console.WriteLine("AI is considering taking a risk"); } else { amount = Bet(isFirst, handStrength, previousBet, riskTaking, out action); Console.WriteLine("AI is taking a risk"); } } if (handStrength > 2 && handStrength <= 5) // 3, 4, 5 { //check or evaluate risk float mod = riskTaking * (handStrength / 10 * 0.55f); if (riskTaking + mod < 100 * 1 / 10) { action = Actions.FOLD; Console.WriteLine("AI gives in and folds"); } else if (riskTaking + mod < 100 * 3 / 6) { action = Actions.CHECK; Console.WriteLine("AI plays it safe and checks"); } else if (riskTaking + mod < 100 * 5 / 6) { act = rng.Next(100); if (act + mod < 25) { action = Actions.CHECK; } else if (act + mod < 50 && !isFirst) { action = Actions.CALL; } else { amount = Bet(isFirst, handStrength, previousBet, riskTaking, out action); } Console.WriteLine("AI is considering taking a risk"); } else { amount = Bet(isFirst, handStrength, previousBet, riskTaking, out action); Console.WriteLine("AI is taking a risk"); } } if (handStrength > 5 && handStrength <= 8) // 6, 7, 8 { //check or evaluate risk float mod = riskTaking * (handStrength / 10 * 0.7f); if (riskTaking + mod < 100 * 1 / 18) { action = Actions.CHECK; Console.WriteLine("AI gives in and checks"); } else if (riskTaking + mod < 100 * 1.8 / 6) { if (!isFirst) { action = Actions.CALL; } else { amount = Bet(isFirst, handStrength, previousBet, riskTaking * 0.8f, out action); } Console.WriteLine("AI plays it safe and calls"); } else if (riskTaking + mod < 100 * 5 / 6) { act = rng.Next(100); if (act + mod < 10) { action = Actions.CHECK; } if (act + mod < 50 && !isFirst) { action = Actions.CALL; } else { amount = Bet(isFirst, handStrength, previousBet, riskTaking, out action); } Console.WriteLine("AI is considering taking a risk"); } else { amount = Bet(isFirst, handStrength, previousBet, riskTaking, out action); Console.WriteLine("AI is taking a risk"); } } if (handStrength == 9 || handStrength == 10) // 9, 10 { //check or evaluate risk //check or evaluate risk float mod = riskTaking * (handStrength / 10 * 0.9f); if (riskTaking + mod < 100 * 4.5 / 10) { if (!isFirst) { action = Actions.CALL; } Console.WriteLine("AI tries to bluff and calls"); } else if (riskTaking + mod < 100 * 7 / 10) { act = rng.Next(100); if (act + mod < 50 && !isFirst) { action = Actions.CALL; } else { amount = Bet(isFirst, handStrength, previousBet, riskTaking, out action); } Console.WriteLine("AI is considering bluffing to raise pot"); } else { amount = Bet(isFirst, handStrength, previousBet, riskTaking, out action); Console.WriteLine("AI is confident and raises the bet"); } } //end turn and submit action //create the PlayerAction switch (action) { case Actions.BET: pa = new PlayerAction(Name, "Bet2", "bet", (int)Math.Ceiling(amount)); break; case Actions.RAISE: pa = new PlayerAction(Name, "Bet2", "raise", (int)Math.Ceiling(amount)); break; case Actions.CALL: pa = new PlayerAction(Name, "Bet2", "call", (int)Math.Ceiling(amount)); break; case Actions.CHECK: pa = new PlayerAction(Name, "Bet2", "check", (int)Math.Ceiling(amount)); break; case Actions.FOLD: pa = new PlayerAction(Name, "Bet2", "fold", (int)Math.Ceiling(amount)); break; default: Console.WriteLine("Invalid menu selection - try again"); break; } Console.WriteLine("< end ai betting round 2 >"); roundNum++; return(pa); }
private void AnalyzeHand() { rank = Evaluate.RateAHand(this.Hand, out highCard); }
//Probabilities: http://www.math.hawaii.edu/~ramsey/Probability/PokerHands.html public override PlayerAction BettingRound1(List <PlayerAction> actions, Card[] hand) { // create a test hand to test reactions Card[] testHand = new Card[5]; testHand[0] = new Card("Spades", 4); testHand[1] = new Card("Diamonds", 6); testHand[2] = new Card("Diamonds", 11); testHand[3] = new Card("Spades", 12); testHand[4] = new Card("Hearts", 7); int test = (int)(((float)rng.Next(33, 100) / 0.01) * 100); //Console.Writ //info to keep track of roundNum = actions.Count; // evaluate the hand Card highCard = null; int handStrength = Evaluate.RateAHand(hand, out highCard); //update stats if (actions.Count > 0) //ai goes second { //Console.WriteLine("\n*round stats-> First Player: " + actions[0].Name + " total turns taken: " + actions.Count); for (int i = 0; i < actions.Count; i++) { //Console.WriteLine(" (" + (i) + "): PLR: " + actions[i].Name + ", action: " + actions[i].ActionName + ", inPhase: " + actions[i].ActionPhase + ", amount: " + actions[i].Amount); } } else //ai goes first { //Console.WriteLine("\n*round stats-> player 1: " + Name + " takes first turn of round."); } //setup action PlayerAction pa = null; //start turn //Console.WriteLine("\n-> in ai betting round 1"); //Console.WriteLine(" Total games played: "+roundNum); ListTheHand(hand); //if ai is first // actions available: bet, check, fold if (Round1FirstCheck(handStrength, out pa, highCard)) { // we're at round 0, increment so we get an accurate read //roundNum++; return(pa); } else // the ai is going second, actions available: check, call, raise, fold { // evaluate the enemy's hand estimatedEnemyHand = EvaluateEnemyHand(actions); //Console.WriteLine("Estimated enemy hand strength: " + estimatedEnemyHand); pa = Round1ActionSelector(TurnOrder.SECOND, actions[roundNum - 1], handStrength, highCard); return(pa); } }
public bool[] GetCardsToDelete(Card[] hand) { bool[] cardPositionToDelete = { false, false, false, false, false }; Card highCard = null; int rank = Evaluate.RateAHand(hand, out highCard); // Do not change any cards for Royal Flush, Straight Flush, Full House, Flush or Straight // In case of four of a kind try and get a better value card for the kicker if (rank == 8 && highCard.Value < 7) { if (hand[0].Value == hand[2].Value) { cardPositionToDelete[4] = true; } else { cardPositionToDelete[0] = true; } } // In case of 3 of a kind, change one card if the kicker is high, else discard 2 cards if (rank == 4 && highCard.Value > 7) { if ((hand[0].Value == hand[1].Value) && (hand[0].Value == hand[2].Value)) { cardPositionToDelete[3] = true; } else { cardPositionToDelete[0] = true; } } else if (rank == 4 && highCard.Value < 7) { if ((hand[0].Value == hand[1].Value) && (hand[0].Value == hand[2].Value)) { cardPositionToDelete[3] = true; cardPositionToDelete[4] = true; } else if ((hand[1].Value == hand[2].Value) && (hand[1].Value == hand[3].Value)) { cardPositionToDelete[0] = true; cardPositionToDelete[4] = true; } else { cardPositionToDelete[0] = true; cardPositionToDelete[1] = true; } } if (rank == 3 && highCard.Value < 7) { if ((hand[4].Value == hand[3].Value) && (hand[2].Value == hand[1].Value)) { cardPositionToDelete[0] = true; } else if ((hand[4].Value == hand[3].Value) && (hand[1].Value == hand[0].Value)) { cardPositionToDelete[2] = true; } else { cardPositionToDelete[4] = true; } } // If it is one pair or high card, check if there is a possibility of flush or straight and discard cards accordingly if (rank == 2 || rank == 1) { if (IsFlushPossible(hand, out cardPositionToDelete)) { return(cardPositionToDelete); } else if (IsStraightPossible(hand, out cardPositionToDelete)) { return(cardPositionToDelete); } else { // Discard cards with value lower than 10 for (int i = 0; i < hand.Length; i++) { if (hand[i].Value < 10) { cardPositionToDelete[i] = true; } } } } return(cardPositionToDelete); }
/****************************\ * * Opponent Profiling * ****************************/ /// <summary> /// When a new round happens, looks over bets of previous round and gathers data /// </summary> void NewRound() { ++roundCounter; // Goes through each of the opponents bets // Adds them to bet totals for each round // Notes each bet and raise int roundBet1 = 0; int roundBet2 = 0; for (int n = 0; n < prevPlayerActionList.Count; ++n) { PlayerAction a = prevPlayerActionList[n]; if (a.Name != Name) { if (a.ActionPhase == "Bet1") { roundBet1 += FindActionBet(n); } else if (a.ActionPhase == "Bet2") { roundBet2 += FindActionBet(n); } if (a.ActionName == "bet") { bets.Add(a.Amount); } else if (a.ActionName == "raise") { raises.Add(a.Amount); } } } Bets1.Add(roundBet1); Bets2.Add(roundBet2); Card highCard; int handValue = Evaluate.RateAHand(prevHand, out highCard); // If the AI wins and the opponent loses // If the opponent folded in the first phase, // we store how much the bet was that made them fold // The total bet is added to the list of bets during lost rounds if (prevMoney < Money) { PlayerAction lastAct = prevPlayerActionList[prevPlayerActionList.Count - 1]; if (lastAct.ActionPhase == "Bet1") { p1Folds.Add(FindActionBet(prevPlayerActionList.Count - 1)); } loseBets.Add(roundBet1 + roundBet2); } // If the AI loses and the opponent wins // If the AI didn't fold, that means the opponent had a better hand // We can determine that the opponent's hand was at least the same value as the AI's // So they're total bet on it is added to all possible hand values else { winBets.Add(roundBet1 + roundBet2); if (folded == false) { Speak("Your hand was at least a value of " + handValue + " and you bet " + (roundBet1 + roundBet2)); for (int n = handValue - 1; n < 10; ++n) { handBets[n].Add(roundBet1 + roundBet2); } } } }
private void AnalyzeHand() { rank = Evaluate.RateAHand(this.Hand, out highCard); // May implement more later if necessary }