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);
        }
Exemple #12
0
        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]);
        }