// 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); }