private static bool HighCard(ref Card[] table, HandDescriptor result) { result.Rank = HandRankings.High_Card; result.GenerateTiebreaker(table); return(true); }
private static bool TryTwoPair(ref Card[] table, HandDescriptor result) { int firstPair = 0; int secondPair = 0; for (int i = Card.MaxRank; i >= 2; i--) { if (table.Count(c => c.Rank == i) >= 2) { if (firstPair == 0) { firstPair = i; } else if (secondPair == 0) { secondPair = i; } else { break; } } } if (firstPair != 0 && secondPair != 0) { result.Rank = HandRankings.Two_Pair; result.Tiebreaker = firstPair << 16 | secondPair; return(true); } return(false); }
private static bool TryFullHouse(ref Card[] table, HandDescriptor result) { int hasThree = 0, hasTwo = 0; for (int i = Card.MaxRank; i >= 2; i--) { int count = table.Count(c => c.Rank == i); if (count >= 3 && hasThree == 0) { hasThree = i; } else if (count >= 2 && hasTwo == 0) { hasTwo = i; } if (hasThree > 0 && hasTwo > 0) { result.Rank = HandRankings.Full_House; result.Tiebreaker = hasThree << 16 | hasTwo; return(true); } } return(false); }
private static bool TryFourOfAKind(ref Card[] table, HandDescriptor result) { for (int i = Card.MaxRank; i >= 2; i--) { if (table.Count(c => c.Rank == i) == 4) { result.Rank = HandRankings.Four_of_a_Kind; result.Tiebreaker = i; return(true); } } return(false); }
private static bool TryPair(ref Card[] table, HandDescriptor result) { for (int i = Card.MaxRank; i >= 2; i--) { if (table.Count(c => c.Rank == i) >= 2) { result.Rank = HandRankings.Pair; result.Tiebreaker = i; return(true); } } return(false); }
private static bool TryFlush(ref Card[] table, HandDescriptor result) { for (int suit = 0; suit < 4; suit++) { if (table.Count(c => c.Suit == (Suit)suit) >= 5) { result.Rank = HandRankings.Flush; result.GenerateTiebreaker(table.Where(c => c.Suit == (Suit)suit)); return(true); } } return(false); }
// Yes, I know hashtables are much faster but I want move names too. public static HandDescriptor GetHandResult(Card[] table, Player player) { Card[] allCards = new Card[table.Length + player.Cards.Length]; Array.Copy(table, 0, allCards, 0, table.Length); Array.Copy(player.Cards, 0, allCards, table.Length, player.Cards.Length); HandDescriptor hand = new HandDescriptor(); hand.Player = player; for (int i = 0; i < 10; i++) { if (TryHand((HandRankings)i, ref allCards, hand)) { return(hand); } } return(null); }
private static bool TryRoyalFlush(ref Card[] table, HandDescriptor result) { for (int suit = 0; suit < 4; suit++) { for (int i = Card.MaxRank; i >= 9; i--) { if (i == 9) { result.Rank = HandRankings.Royal_Flush; result.Tiebreaker = 0; return(true); } else if (!table.Any(c => c.Suit == (Suit)suit && c.Rank == i)) { break; } } } return(false); }
private static bool TryStraight(ref Card[] table, HandDescriptor result) { for (int i = Card.MaxRank; i >= 2 + 4; i--) { for (int j = i; j >= i - 5; j--) { if (j == i - 5) { result.Rank = HandRankings.Straight; result.Tiebreaker = i; return(true); } else if (!table.Any(c => c.Rank == j)) { break; } } } return(false); }
private static bool TryHand(HandRankings hand, ref Card[] table, HandDescriptor result) { switch (hand) { case HandRankings.Royal_Flush: return(TryRoyalFlush(ref table, result)); case HandRankings.Four_of_a_Kind: return(TryFourOfAKind(ref table, result)); case HandRankings.Straight_Flush: return(TryStraightFlush(ref table, result)); case HandRankings.Full_House: return(TryFullHouse(ref table, result)); case HandRankings.Flush: return(TryFlush(ref table, result)); case HandRankings.Straight: return(TryStraight(ref table, result)); case HandRankings.Three_of_a_Kind: return(TryThreeOfAKind(ref table, result)); case HandRankings.Two_Pair: return(TryTwoPair(ref table, result)); case HandRankings.Pair: return(TryPair(ref table, result)); case HandRankings.High_Card: return(HighCard(ref table, result)); } return(false); }
private static bool TryStraightFlush(ref Card[] table, HandDescriptor result) { for (int i = Card.MaxRank; i >= 2 + 4; i--) { for (int suitIndex = 0; suitIndex < 4; suitIndex++) { for (int j = i; j >= i - 5; j--) { if (j == i - 5) { result.Rank = HandRankings.Straight_Flush; result.Tiebreaker = i; return(true); } else if (!table.Any(c => c.Suit == (Suit)suitIndex && c.Rank == j)) { break; } } } } return(false); }
private void Advance() { do { CurrentBetter = (CurrentBetter + 1) % Players.Count; if (CurrentBetter == MaxBetter) { // Advance if (Table == null || Table.Length == 0) { Table = new Card[3]; for (int i = 0; i < 3; i++) { Table[i] = _deck.Pop(); } } else if (Table.Length == 3) { var tmp = new Card[4]; Array.Copy(Table, 0, tmp, 0, 3); tmp[3] = _deck.Pop(); Table = tmp; } else if (Table.Length == 4) { var tmp = new Card[5]; Array.Copy(Table, 0, tmp, 0, 4); tmp[4] = _deck.Pop(); Table = tmp; } else if (Table.Length == 5) { List <HandDescriptor> hands = new List <HandDescriptor>(); SendToPlayers("Revealing hands..."); // Get hands foreach (Player player in Players.Where(p => p.State == PlayerState.Playing)) { HandDescriptor hand = PokerEngine.GetHandResult(Table, player); foreach (var player1 in Players.Where(p => p != player)) { player1.Client.triggerEvent("SET_PLAYER_CARDS", player.Client.name, player.Cards[0].ToJsCode(), player.Cards[1].ToJsCode()); } hands.Add(hand); } API.shared.sleep(5000); foreach (var hand in hands) { SendToPlayers("Player ~n~" + hand.Player.Client.name + "~n~ has " + hand.HandName); } int min = hands.Min(h => (int)h.Rank); var potentialwinners = hands.Where(h => (int)h.Rank == min).ToList(); int tiebreakermax = potentialwinners.Max(h => h.Tiebreaker); var winners = potentialwinners.Where(h => h.Tiebreaker >= tiebreakermax).ToArray(); int take = Pot / winners.Length; foreach (var winner in winners) { winner.Player.Money += take; winner.Player.Client.triggerEvent("SHARD_CUSTOM", "winner", 5000); SendToPlayers("Player ~n~" + winner.Player.Client.name + "~n~ has won the round with a ~g~" + winner.HandName); if (OnPlayerWinRound != null) { OnPlayerWinRound.Invoke(winner.Player.Client, take, winner.HandName); } } foreach (var losers in Players.Except(winners.Select(w => w.Player))) { losers.Client.triggerEvent("SHARD_CUSTOM", "loser", 5000); if (OnPlayerLoseRound != null) { OnPlayerLoseRound.Invoke(losers.Client); } } API.shared.sleep(5000); EndRound(); return; } object[] newArgs = new object[Table.Length + 1]; newArgs[0] = Table.Length; for (int i = 0; i < Table.Length; i++) { newArgs[i + 1] = Table[i].ToJsCode(); } Players.ForEach(p => p.Client.triggerEvent("SET_TABLE_CARDS", newArgs)); API.shared.sleep(5000); } } while (Players[CurrentBetter].State == PlayerState.Folded); GiveTurn(Players[CurrentBetter]); }