Hi all, I'm trying to make a Poker program. This is what I have so far but I'm not sure how I can check to see if the deck is a Royal Flush, Straight, etc. Could anyone help me get started? This is what my output should be.

Enter the number of hands to play: 3

Hand 1: 9D 9H 6C 3S 8C
Hand 2: AS 2C 8H JD 4S
Hand 3: 3C 7D 5S 6H 4H

Hand 1: Two Pair
Hand 2: High Card
Hand 3: Straight

Hand 3 wins.

class Card (object):
  RANKS = (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)

  SUITS = ('S', 'D', 'H', 'C')

  def __init__ (self, rank, suit):
    self.rank = rank
    self.suit = suit

  def __str__ (self):
    if self.rank == 11:
      rank = 'J'
    elif self.rank == 12:
      rank = 'Q'
    elif self.rank == 13:
      rank = 'K'
    elif self.rank == 14:
      rank = 'A'
    else:
      rank = self.rank
    return str(rank) + self.suit

import random

class Deck(object):
  """ A deck containing 52 cards."""

  def __init__(self):
  """Creates a full deck of cards."""
    self._cards = []
    for suit in Card.SUITS:
      for rank in Card.RANKS:
        c = Card(rank, suit)
        self._cards.append(c)

  def shuffle(self):
  """Shuffles the cards."""
    random.shuffle(self._cards)

  def deal(self):
  """Removes and returns the top card or None 
    if the deck is empty."""
      if len(self) == 0:
        return None
      else:
        return self._cards.pop(0)

  def __len__(self):
  """Returns the number of cards left in the deck."""
    return len(self._cards)

  def __str__(self): 
  """Returns the string representation of a deck."""
    self.result = ''
    for c in self._cards:
      self.result = self.result + str(c) + '\n'
      return self.result

class Poker (object):
  
  def __init__ (self, numHands):
    self.deck = Deck()
    self.deck.shuffle()
    self.hands = []
    numCards_in_Hand = 5

    for i in range (numHands):
      hand = []
      for j in range (numCards_in_Hand):
        hand.append (self.deck.deal())
      self.hands.append (hand)

  def isRoyal (self, hand):
    ...

  def isStraight (self, hand):
    ...

  def isFour (self, hand):
    ...

  def isFull (self, hand):
    ...

  def isFlush (self, hand):
    ...

  def isStraight (self, hand):
    ...

  def isThree (self, hand):
    ...

  def isTwo (self, hand):
    ...

  def isOne (self, hand):
    ...

  def isHigh (self, hand):
    ...

def main():
  cond = True
  while (cond):
    numHands = input("Enter the number of hands to play: ")
    cond = numHands <= 2 and numHands >= 6

main()

Test the code you have before posting it here. For example, in the Deck class, there is an indentation error, and the variable "c" [c = Card(rank, suit)] is an instance of the class Card. To access the rank and suit from the Deck class, you would use
self._cards[ctr].rank and self._cards[ctr].suit
where ctr = a number between 0 through 51. Is this what you want? Also,
if len(self) == 0:
should error because "self" is a pointer to this class and has no length.

To answer your question directly, if all cards are the same suit as the first card, it is a flush. If the hand is sorted in numerical order and each card = previous card +1 then you have a straight. For now though, get the code you have working (print the deck after it is created and the hands after they are dealt at the very least). Note that you can also use a dictionary for changing the numbers to J, Q, K, or A. Also, you would possibly use a dictionary to store the relative value of the different hands so you know which hand wins.

rank_dict = {11: 'J',
             12: 'Q',
             13: 'K',
             14: 'A' }

## test dictionary use
rank = [2, 12]
for r in rank:
    print r,
    if r in rank_dict:
        print rank_dict[r]
    else:
        print r
"""
    The dictionary replaces the following code

    if self.rank == 11:
      rank = 'J'
    elif self.rank == 12:
      rank = 'Q'
    elif self.rank == 13:
      rank = 'K'
    elif self.rank == 14:
      rank = 'A'
"""

Edited 5 Years Ago by woooee: n/a

Thanks so much for your reply. I modified my code so it prints each deck of cards. I also spent some time figuring out how to print each deck with the highest valued card first. I'm stuck at what to do next since I don't know how to check my cards. Also how could I use a dictionary to check to see which hand wins? Would the dictionary implement some form of point system? Sorry if my knowledge sounds limited, this is my first program using classes and I'm still trying to absorb how things work.

import string, math, random

class Card (object):
  RANKS = (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)

  SUITS = ('S', 'D', 'H', 'C')

  def __init__ (self, rank, suit):
    self.rank = rank
    self.suit = suit

  def __str__ (self):
    if self.rank == 14:
      rank = 'A'
    elif self.rank == 11:
      rank = 'J'
    elif self.rank == 12:
      rank = 'Q'
    elif self.rank == 13:
      rank = 'K'
    else:
      rank = self.rank
    return str(rank) + self.suit

  def __cmp__ (self, other):
    if (self.rank < other.rank):
      return -1
    elif (self.rank > other.rank):
      return 1
    else:
      return 0


class Deck (object):
  def __init__ (self):
    self.deck = []
    for suit in Card.SUITS:
      for rank in Card.RANKS:
        c = Card (rank, suit)
	self.deck.append (c)

  def shuffle (self):
    random.shuffle (self.deck)

  def __len__ (self):
    return len (self.deck)

  def deal (self):
    if len(self) == 0:
      return None
    else:
      return self.deck.pop(0)

  def __str__ (self):
    result = ''
    for c in self.deck:
      result = result + str(c) + '\n'
    return result

class Poker (object):
  def __init__ (self, numHands):
    self.deck = Deck()
    self.deck.shuffle ()
    self.hands = []
    numCards_in_Hand = 5

    for i in range (numHands):
      hand = []
      for j in range (numCards_in_Hand):
        hand.append (self.deck.deal())
      self.hands.append (hand)

  def play (self):
    for i in range (len(self.hands)):
      sortedHand = sorted (self.hands[i], reverse = True)
      hand = ''
      for card in sortedHand:
        hand = hand +  str (card) + ' '
      print 'Hand ' + str(i+1) + ': ' + hand 

  def isRoyal (self, hand):
    ...

  def isStraightFlush (self, hand):
    ...

  def isFour (self, hand):
    ...

  def isFull (self, hand):
    ...

  def isFlush (self, hand):
    ...

  def isStraight (self, hand):
    ...

  def isThree (self, hand):
    ...

  def isTwo (self, hand):
    ...

  def isOne (self, hand):
    ...

  def isHigh (self, hand):
    ...


def main():
  numHands = input ('Enter the number of hands to play: ')
  while (numHands < 2 or numHands > 6):
    numHands = input ('Enter the number of hands to play: ')
  game = Poker (numHands)
  game.play()

main()

If someone could do a function so I could use as a reference, it would be greatly appreciated.

Hi, I'm in desperate need of help. I reworked this program to something like this. I get the error

File "poker.py", line 116, in find_flush
    suits.add(card.suit)
AttributeError: 'str' object has no attribute 'suit'

Am I at least going the right direction? Any help would be greatly appreciated.

import string, math, random

class Card (object):
  RANKS = (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)

  SUITS = ('S', 'D', 'H', 'C')

  def __init__ (self, rank, suit):
    self.rank = rank
    self.suit = suit

  def __str__ (self):
    if self.rank == 14:
      rank = 'A'
    elif self.rank == 11:
      rank = 'J'
    elif self.rank == 12:
      rank = 'Q'
    elif self.rank == 13:
      rank = 'K'
    else:
      rank = self.rank
    return str(rank) + self.suit

  def __cmp__ (self, other):
    if (self.rank < other.rank):
      return -1
    elif (self.rank > other.rank):
      return 1
    else:
      return 0


class Deck (object):
  def __init__ (self):
    self.deck = []
    for suit in Card.SUITS:
      for rank in Card.RANKS:
        c = Card (rank, suit)
	self.deck.append (c)

  def shuffle (self):
    random.shuffle (self.deck)

  def __len__ (self):
    return len (self.deck)

  def deal (self):
    if len(self) == 0:
      return None
    else:
      return self.deck.pop(0)

  def __str__ (self):
    result = ''
    for c in self.deck:
      result = result + str(c) + '\n'
    return result

class Poker (object):
  def __init__ (self, numHands):
    self.deck = Deck()
    self.deck.shuffle ()
    self.hands = []
    numCards_in_Hand = 5

    for i in range (numHands):
      hand = []
      for j in range (numCards_in_Hand):
        hand.append (self.deck.deal())
      self.hands.append (hand)

  def play (self):
    for i in range (len(self.hands)):
      sortedHand = sorted (self.hands[i], reverse = True)
      hand = ''
      for card in sortedHand:
        hand = hand +  str (card) + ' '
      print 'Hand ' + str(i+1) + ': ' + hand 
    print

    results = {}
    for i in range (len(self.hands)):
      for hand in self.hands:
        results[hand] = self.find_flush(card.suit)
        results[hand] = self.find_straight(card.suit)
        results[hand] = self.find_fullhouse(card.suit)
        results[hand] = self.find_kindsandpairs(card.suit)

        if results[hand] == 10:
          print 'Hand ' + str(i+1) + 'Royal Flush'
        elif results[hand] == 9:
          print 'Hand ' + str(i+1) + 'Straight Flush'
        elif results[hand] == 8:
          print 'Hand ' + str(i+1) + 'Four of a Kind'
        elif results[hand] == 7:
          print 'Hand ' + str(i+1) + 'Full House'
        elif results[hand] == 6:
          print 'Hand ' + str(i+1) + 'Flush'
        elif results[hand] == 5:
          print 'Hand ' + str(i+1) + 'Straight'
        elif results[hand] == 4:
          print 'Hand ' + str(i+1) + 'Three of a Kind'
        elif results[hand] == 3:
          print 'Hand ' + str(i+1) + 'Two Pair'
        elif results[hand] == 2:
          print 'Hand ' + str(i+1) + 'One Pair'
        elif results[hand] == 1:
          print 'Hand ' + str(i+1) + 'High Card'


  def find_flush(self, hand):
    suits = set()
    vals = []
    for card in hand:
      suits.add(card.suit)
      vals.append(card.val)
    if len(suits) == 1:
      # we know it's some type of flush
      if sorted(vals) == [10, 11, 12, 13, 14]:
        return 10 #Its a royal flush
      else:
        straight_flush = True
        for i in range(len(vals) - 1):
          if vals[i] + 1 != vals[i + 1]:
            # if the values aren't consecutive, i.e.,
            # for 7, 8, 9, 10, 11,
            # 7 + 1 == 8, 8 + 1 == 9, etc...
            straight_flush = False
        if straight_flush:
          return 9 #its a straight flush
        else:
          return 6 #its a flush   

  def find_straight(self, hand):
    vals = []
    for card in hand:
      vals.append(card.val)
    for i in range(len(vals) - 1):
      if vals[i] == vals[i+1]: #check to see if there is a straight
        return 5 

  def find_fullhouse(self, hand):
    vals = []
    for card in hand:
      vals.append(card.val)
    vals = sorted(vals)
    for i in range(len(vals) - 1):
      if vals[0] == vals[2] and vals[3] == vals[4]:  #After vals is sorted if the first three are the same and the last two are the same then its a full house.
        return 7  # its a full house
      elif vals[0] == vals[1] and vals[2] == vals[4]: #Check the other case
        return 7 #check the other case
    
  def find_kindsandpairs(self, hand):
    vals = []
    for card in hand:
      vals.append(card.val)
    vals = sorted(vals)
    for i in range(len(vals) - 1):
      if vals[0] == vals[3] or vals[1] == vals[4]:
        return 8 #its four of a kind
      elif vals[0] == vals[2] or vals[2] == vals[4]:
        return 4 #its three of a kind
      elif vals[0] == vals[1] and vals[2] == vals[3]:
        return 3 # its a two pair
      elif vals[1]==vals[2] and vals[3] == vals[4]:
        return 3  #its a two pair checking another case
      elif vals[0]==vals[1] and vals[3] == vals[4]:
        return 3 #its a two pair checking out final case
      elif vals[0] == vals[1] or vals[1] == vals[2] or vals[2]==vals[3] or vals[3] == vals[4]:
        return 2 # there is just a pair
      else:
        return 1 #there is just a high card


  
def main():
  numHands = input ('Enter the number of hands to play: ')
  while (numHands < 2 or numHands > 6):
    numHands = input ('Enter the number of hands to play: ')
  game = Poker (numHands)
  game.play()

main()

Edited 5 Years Ago by RICH148: n/a

Looks to me like

card.suit

is giving you that error b/c there hasn't been a Card class object created, no?

You created a Poker object in

game = Poker(numhands)

, but i don't see where a Card object occurs. Could need some thing like

cards = Card()

under main().

Do the cards need to be their own class anyhow?

Could you explain what you are doing to check for a pair?

This article has been dead for over six months. Start a new discussion instead.