0

The following code checks for all straights in a five-card hand (except 5-high, which I add in as an elif)

def straight(values,vset):
    if (max(vset) - min(vset) == 4) and numpair(values) == False and detset(values) == False and quads(values) == False:
#STRAIGHT DETECTED

Vset is just a set containing the values. The problem is, I cannot figure out a way to adapt this code to evaluate a 7-card holdem hand. Any advice?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Alec
  • 8,529
  • 8
  • 37
  • 63
  • There's a bunch of things wrong with your question: Firstly, what's your data type? Secondly, there are several functions that are undefined. Thirdly, "I cannot figure out" is hardly a problem description. In any case, that code looks very unidiomatic to me, so I'd just start with refactoring it. Maybe, once the code is a bit cleaner, a solution becomes more obvious. In any case, add unit tests! – Ulrich Eckhardt Mar 02 '19 at 05:45

2 Answers2

3

While @JohnGordon's solution works it wastefully iterates 5 times for each rank value.

A more efficient approach would be to iterate the rank from 2 to 14 and simply use a counter to keep track of the number of times so far the rank exists in the cards consecutively, and if a consecutive rank doesn't exist, reset the counter. Determine that there is a straight if the counter reaches 5. To account for the fact that an Ace (assuming its rank is 14 here) can be regarded as a 1 to form a straight with 2, 3, 4, and 5 as well, you can prepend 14 to the range of 2 to 14 for iteration:

count = 0
for rank in (14, *range(2, 15)):
    if rank in vset:
        count += 1
        if count == 5:
            print('Straight found')
            break
    else:
        count = 0
else:
    print('Straight not found')
blhsing
  • 91,368
  • 6
  • 71
  • 106
  • @blhsing what is *range(2, 15) doing? not sure what prepending for iteration is – Alec Mar 02 '19 at 06:46
  • `range(2, 15)` creates a range object that would yield numbers from 2 to 14, while the unpacking operator `*` unpacks the output of `range(2, 15)` into a tuple enclosed by the outer parentheses, together with the 14 before it (that's what prepending means), to form a tuple of `(14, 2, 3, 4, ... , 13, 14)` to be iterated over. – blhsing Mar 02 '19 at 06:48
  • I don't think I'm understanding correctly? Wouldn't that register 13,14,2,3,4 as a straight? – Alec Mar 02 '19 at 22:27
  • 1
    No it wouldn't because it only recognizes a straight when the counter reaches 5, and since `rank` is iterated from 14, 2, 3, 4, ..., to 13, 14, the counter can only reach 5 if there are 14, 2, 3, 4, 5, or 2, 3, 4, 5, 6, or 3, 4, 5, 6, 7, ..., or 10, 11, 12, 13, 14 in the cards. Having 13, 14, 2, 3, 4 won't make the counter reach 5 since `rank` does not iterate in that sequence. – blhsing Mar 02 '19 at 23:26
0

I don't know how the code works now, because you haven't shown us the code for numpair(), detset() and quads().

However, working from a clean slate, this is how I would do it:

# assume rank values are numeric 2-10, J=11, Q=12, K=13, A=14
# iterate over each rank 2 thru 10
for rank in range(2, 11):
    # if rank+0, rank+1, rank+2, rank+3, and rank+4 are all present, we have a straight
    if all(rank+n in vset for n in range(0,5)):
        print 'we have a straight'
        break
# if we never broke out of the loop, we never found a straight
else:
    print 'we do not have a straight'
John Gordon
  • 29,573
  • 7
  • 33
  • 58