0

I decided to challenge myself by creating a poker game. I am currently very confused with tuples and trying to use them properly. I am currently stuck trying to check if the hand (h) is a straight flush or not. Below is the code I am using to create a deck of cards.

numbers=(2,3,4,5,6,7,8,9,10,'J','Q','K','A')
faces=("Clubs","Diamond","Spades","Harts")
print(numbers[0],faces[0])
deck=[]


for i in numbers:
    for j in faces:
        deck.append((j,i))


hand=d[1],d[5],d[9],d[13],d[17]

The hand above is (('Diamond', 2), ('Diamond', 3), ('Diamond', 4), ('Diamond', 5), ('Diamond', 6)).

Below is the code I am having trouble with. Currently, it is only able to check if all the faces are the same (it can check if Diamond is the face for all the cards in h), but not able to check if the number is in sequence with numbers. Also I would like to make it so A can be looped, as a hand like (('Diamond', 2), ('Diamond', 3), ('Diamond', 4), ('Diamond', 5), ('Diamond', A)) is still a valid straight. I know I can use numbers to check the sequence but am trying to do it only using deck.

def straight_flush(h):
    r=True
    for (i,j) in h:
        for (a,b) in h:
            if i==a:
                r=True
            else:
               r=False
            
    return r

print(straight_flush(h))  
Alec
  • 8,529
  • 8
  • 37
  • 63
  • 1
    Not an answer to your question but making a card game is a good example for where you can use OOP (object oriented programming) – Joshua Nixon Dec 07 '20 at 15:42
  • I suggest you make it easier and do use numbers for the face values. You can always get the "display value" separately – OneCricketeer Dec 07 '20 at 15:43
  • I also recommend @OneCricketeer's comment. Assuming you're working with a single deck, a straight flush is then (1) all cards are the same suit. (2) The smallest ranked card is exactly 4 less than the highest ranked card. (If you treat A=14 as both low and high, you may need to modify this slightly to check for A,2,3,4,5). – Frank Yellin Dec 07 '20 at 15:47
  • The first thing to do is stop using the strings 'A', 'K', etc. to represent face cards. Use numbers, so that it's easier to compare them and sort by rank. Strings are for people: computers use numbers. Convert to names only when necessary to interact with people. Then, sort the hand by rank before doing all the checks. You're going to have an ugly special-case for the Wheel--no way around that. – Lee Daniel Crocker Dec 07 '20 at 19:54

1 Answers1

0

First, use numbers for the face cards. It's easier. Also, you should make a card class.

Regarding the straight flush, you need to check if the hand is a flush, then check the flush cards for a straight. Using 5-card hands (instead of 7 like in Hold'em) means you just have to check if there's a straight and a flush.

A flush is easy to detect, just see if the amount of any suit is ≥5. A straight is a bit harder. Probably the easiest way is to manually code in all the straights (i.e. detect if hand matches preset tuples representing the possible straights).

There are also algorithms for detecting straights. Here's one from a project I made to give you an idea of the structure:

def straight(cls, vset, get_vals=False):
        """Returns the name of a straight hand (string) given a set of the hand's card values.
        Returns False if a straight is not present within the hand. Also changes hand strength accordingly.
        If get_vals is true, straight() does not change strength and returns the values present in a straight."""
        count = 0

        if not get_vals:
            straight = False
            for rank in reversed([14, *range(2, 15)]):
                if rank in vset:
                    count += 1
                    min_c = rank
                    if count == 5:
                        if min_c != 14:
                            max_c = min_c + 4
                        else:
                            min_c, max_c = 1, 5
                        cls.strength = BaseStrength.STRAIGHT.value + 70*max_c
                        straight = f'Straight from {value_names[min_c]} to {value_names[max_c]}'
                        break
                else: count = 0
            return straight

Ignore get_vals. My algorithm is not the most efficient (probably far from it).

Alec
  • 8,529
  • 8
  • 37
  • 63