Welcome, guest | Sign In | My Account | Store | Cart

Handles logic for detecting straights and groups of repeats in the presence of wildcards and hands with more than five cards.

Python, 79 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def is_straight(hand, numwildcards=0):
    """Checks for a five card straight

    Inputs: list of non-wildcards plus wildcard count
        2,3,4, ... 10, 11 for Jack, 12 for Queen,
        13 for King, 14 for Ace
        Hand can be any length (i.e. it works for seven card games).

    Outputs:  highest card in a five card straight
              or 0 if not a straight.
        Original list is not mutated.
        Ace can also be a low card (i.e. A2345).

    >>> is_straight([14,2,3,4,5])
    5
    >>> is_straight([14,2,3,4,6])
    0
    >>> is_straight([10,11,12,13,14])
    14
    >>> is_straight([2,3,5], 2)
    6
    >>> is_straight([], 5)
    14
    >>> is_straight([2,4,6,8,10], 3)
    12
    >>> is_straight([2,4,4,5,5], 2)
    6
    """

    hand = set(hand)
    if 14 in hand:
        hand.add(1)
    for low in (10,9,8,7,6,5,4,3,2,1):
        needed = set(range(low, low+5))
        if len(needed - hand) <= numwildcards:
            return low+4
    return 0



def groups(hand, numwildcards=0):
    """Checks for pairs, threes-of-a-kind, fours-of-a-kind,
       and fives-of-a-kind

    Inputs: list of non-wildcards plus wildcard count
        2,3,4, ... 10, 11 for Jack, 12 for Queen,
        13 for King, 14 for Ace
        Hand can be any length (i.e. it works for seven card games)
    Output: tuple with counts for each value (high cards first)
        for example (3, 14), (2, 11)  full-house Aces over Jacks
        for example (2, 9), (2, 7)    two-pair Nines and Sevens
    Maximum count is limited to five (there is no seven of a kind).
    Original list is not mutated.

    >>> groups([11,14,11,14,14])
    [(3, 14), (2, 11)]
    >>> groups([7, 9, 10, 9, 7])
    [(2, 9), (2, 7)]
    >>> groups([11,14,11,14], 1)
    [(3, 14), (2, 11)]
    >>> groups([9,9,9,9,8], 2)
    [(5, 9), (2, 8)]
    >>> groups([], 7)
    [(5, 14), (2, 13)]
    """

    result = []
    counts = [(hand.count(v), v) for v in range(2,15)]
    for c, v in sorted(counts, reverse=True):
        newcount = min(5, c + numwildcards) # Add wildcards upto five
        numwildcards -= newcount - c        # Wildcards remaining
        if newcount > 1:
            result.append((newcount, v))
    return result



import doctest
print doctest.testmod()

In response to a query on comp.lang.python, these functions were offered as a starting point for writing poker programs. It is straight-forward to customize these for hi/lo games and to add a representation for suits to enable detection of a flush.

Two techniques are demonstrated. Possible straights are tested from high to low. A match is reported when any cards needed but not held are satisfied by wildcards.

In contrast, the technique for grouping is to count cards by value and rank the results by number held (most-to-least) and value (biggest-to-smallest). Starting with the most valuable group, the counts are boosted by wildcards upto a maximum five-of-a-kind. For clarity, the results screen-out singletons (anything less than a pair). This is easily changed to just screen out zero counts (to detect something like Jacks or better).

Both functions leave the input list unmutated. This could be helpful as cards are added, burned, or kept face-down during the course of play.