In python I have a score tracker of a poker hand.
Possible card ranks:
A23456789TJQK
Straights of 3 or more cards score 1 per card. Example straight of 4 cards gives you 4 points.
So I have a score:
score = 0
A sorted list of strings (so I don't have to worry about cards at the end of the list having a straight with the beginning) representing the card ranks of my particular hand:
L4
['6', '8', '8', '9', 'T']
# Note: 8, 9, T is a straight. So I want to add 3 to score
But how can I determine if I have a straight?
What I've tried so far:
I tried converting the strings into integers, but then what do I do with the T, J, K, Q, and A? They aren't numbers.
Using strings I get an error:
for i in range(len(L4) - 1):
if(L4[i] is L4[i + 1] + 1):
sC = sC + 1
if(sC >= 3):
score += sC
L4
['6', '8', '8', '9', 'T']
Traceback (most recent call last):
File "myFile.py", line 66, in <module>
if(L4[i] is L4[i + 1] + 1):
TypeError: must be str, not int
Should I convert them to ints or should I try another way? Thanks for help in advance.
You can find all substrings of the current hand, and filter the results to find those that are sorted with an increment of 1
:
def stringify_result(f):
def wrapper(_d):
cards = {10:'T', 11:'J', 12:'Q', 13:'K'}
return list(map(lambda x:cards.get(x, str(x)), f(_d)))
return wrapper
@stringify_result
def has_straight(d):
cards = {'J': 11, 'K': 13, 'T': 10, 'Q': 12}
subs = list(filter(None, [d[b:i] for i in range(len(d)+1) for b in range(len(d)+1)]))
possibilities = list(filter(lambda x:all(x[i+1] - x[i] == 1 for i in range(len(x)-1)), [[int(cards.get(b, b)) for b in i] for i in subs]))
return [] if not possibilities else max(possibilities, key=len)
straight = has_straight(['6', '8', '8', '9', 'T'])
score = len(straight)
Output:
['8', '9', 'T']
3
Edit: to account for multiple runs, you can use itertools.groupby
:
import itertools
def has_straight(d):
cards = {'J': 11, 'K': 13, 'T': 10, 'Q': 12}
mutated_cards = list(map(lambda x:int(cards.get(x, x)), d))
_grouped = [list(b) for _, b in itertools.groupby(mutated_cards)]
subs = list(filter(None, [_grouped[b:i] for i in range(len(_grouped)+1) for b in range(len(_grouped)+1)]))
final_filtered = list(filter(lambda x:all(x[i+1][0] - x[i][0] == 1 for i in range(len(x)-1)), subs))
new_subs = [] if not final_filtered else max(final_filtered, key=lambda x:sum(len(i) for i in x))
return sum(len(i) for i in new_subs if len(i) > 1), list(map(lambda x:x[0], new_subs))
print(has_straight(['6', '8', '8', '9', 'T']))
print(has_straight(['4', '4', '5', '5', '6']))
Output:
(2, [8, 9, 10])
(4, [4, 5, 6])