0

Hi Guys. I am new here. I am trying to run a Poker program that can detect the different hands in poker.
here is my code

class Card:
        # A card is an Object with a suit and rank
        # attributes.

    def __init__(self, rank, suit):
        # To create a new Card, we pass in strings
        # representing the rank and suit (e.g.,
        # "A" and "H" for the ace of hearts).
        # We then populate a new Card object
        # with the appropriate information.
        self.rank = rank
        self.suit = suit

    def __str__(self):
        # This function defines a string used to print
        # this object.  
        return self.rank + self.suit

    def getRank(self):
        # return my rank
        return self.rank

    def getSuit(self):
        # return my suit
        return self.suit

class Deck:
        # A Deck is an Object which contains a list of Cards. 

    def __init__(self):
        # Create a new deck of cards. 
        self.cards = []
        for r in ["A", "2","3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]:
            for s in "SHDC":
                newCard = Card(r, s)
                self.cards.append(newCard)
        # The random module contains a number of useful
        # functions including one that randomly reorders
        # a list.
        from random import shuffle
        shuffle(self.cards)

    def __str__(self):
        # This returns a string representing the Deck.  Defining
        # this function allows `print deck' to work properly.
        s = ""
        for c in self.cards:
            s = s + c.__str__() + " "
        return "[ " + s + "]"

    def shuffleDeck(self):
        # Return a random permutation of the cards in the
        # deck.
        from random import shuffle
        shuffle(self.cards)

    def nextCard(self):
        # Remove and return the first card from the deck.
        c = self.cards.pop(0)
        return c

    def size(self):
        # Ask how many cards are left in the deck.
        return len(self.cards)
class Hand:
    # A Hand is an object that contains a list of 5 cards.  We need to 
    # be able to draw a hand from a deck and evaluate it to see what
    # it contains. 

    # These two arrays are used to compute the right place to index
    # into the other arrays created below.
    suits = [ "S", "H", "D", "C" ]
    ranks = ["A", "2", "3", "4", "5", "6", "7",
             "8", "9", "10", "J", "Q", "K"]
    #Ranks = {'A' : 1, '2' :2, '3': 3, '4' : 4, '5' : 5, '6' : 6, '7' :7, '8': 8, '9':9,
             #'10': 10, 'J' :11, 'Q' : 12, 'K' : 13}
    counter= None
    rindex= None

    def __init__(self, deck):
        # A hand is simply the first five cards in the deck, if there are
        # five cards available.
        if ( deck.size() < 5 ):
            print "Not enough cards left!"
            return
        self.mycards = []
        for i in range(5):
            card = deck.nextCard()           # returns next card
            self.mycards.append(card)        # appends it to the hand
        self.processHand()

    def processHand(self):
        # These are used to record the information in the hand:
        self.myranks = [0] * 13 
        self.mysuits = [0] * 4	
        # For each card, extract and record its suit and rank in myranks
        # and mysuits arrays.
        for c in self.mycards:
            r = c.getRank()
            rind = Hand.ranks.index(r)
            self.myranks[rind] = self.myranks[rind] + 1
            s = c.getSuit()
            sind = Hand.suits.index(s)
            self.mysuits[sind] = self.mysuits[sind] + 1

    def __str__(self):
        s=""
        for c in self.mycards:
            s= s + c.__str__() + " "
        return "[ " + s + " ]"

    # You may need some auxiliary functions beyond what is here. 

    def hasFlush(self):
        # checks if any of the suits in mysuits has 5; if so, then there is a flush.
        if 5 in self.mysuits:
            return True
        return False
                

    def hasFourOfAKind(self):
        # Checks if any of the cards in myranks list has 4 of the same value; if so, then there are four of a kind.
        if 4 in self.myranks:
            return True
        return False
                

            
            

    def hasThreeOfAKind(self):
        # checks to see if first card's rank is equal to second card's rank; if not
        # then goes through loop of temp in other cards; process repeated with second card check again subsequent cards
        #  uses iteration to see number of times the ranks match; if match two times, then there is a three of a kind.
        if 3 in self.myranks:
            return True
        return False
        

    def hasPair(self):
        # checks to see if two cards match using algorithm described in hasThreeOfAKind(self)
        if 2 in self.myranks:
            return True
        return False



    def hasTwoPair(self):
        # Loop through the rankList. Then, use temp as pointer
        # that points to the next card  after rank. Compares pointer's rank to temp's
        # rank. iteration keeps track of how many matches in the hand. 
        iteration= 0
        result= False
        rankList= self.myranks.tolist()
        
        for pointer in self.rankList:
            for temp in self.rankList[rankList.index(pointer)+1 : len(self.rankList)-1]:
            
                if pointer== temp:
                    iteration= iteration + 1
            
            
        if iteration == 2:
            result = True
        return result
       

            
    def hasStraight(self):
        # Does this code work?
        # Convert myranks array to a list. loop through the five ranks in cards.
        # Temp runs from the rank after cards to the end of cards list. If the value
        # in the rank array after the counter is equal to the rank of the next card
        # in cards and the previous condition is satisfied
        # in all of the ranks, then there is a straight.
        animal= 0
        for kite in self.myranks:
            coyote= self.myranks[trap+1]
            if 1 in kite and 1 in coyote:
                animal= animal + 1
        if 1 in self.myranks[0]:
            animal= animal + 1
        if animal == 4:
            return True
        return False
         
                  

    def hasFullHouse(self):
        
        integer= 0
        countess= 0
        for beans in self.myranks:
            if 2 in beans:
                integer+= 1

        for bill in self.myranks:
            if 3 in bill:
                countess= countess + 1
        if integer== 1 and countess== 1:
            return True
        return False
                
            
        

    def hasRoyalStraight(self):
        clock= 0
        control= 0
        for mod in self.mysuits:
            if 4 in mod:
                clock= clock + 1
        for trap in self.myranks:
            time= self.myranks[trap+1]
            if 1 in trap and 1 in time:
                control= control + 1
        if 1 in self.myranks[0]:
            control= control + 1
        if clock== 1 and control == 4:
            return True
        return False
            

    def hasStraightFlush(self):
        flash= 0
        bash= False
        cash= False
        lash= False
        for kitten in self.myranks:
            kat= self.myranks[kitten+1]
            if 1 in self.myranks[kitten]:
                bash= True
            if 1 in self.myranks[kat]:
                bash= True
            if bash== True and cash== True:
                flash= flash + 1
        if 1 in self.myranks[0]:
            flash= flash + 1
        if 5 in self.mysuits:
            lash= True
        if flash == 4 and lash== True:
            return True
        return False

    def evaluateHand(self):
        
        if self.hasStraightFlush():
            return "Straight Flush"
        elif self.hasFourOfAKind():
            return "Four of a kind"
        elif self.hasFullHouse():
            return "Full House"
        elif self.hasFlush():
            return "Flush"
        elif self.hasStraight():
            return "Straight"
        elif self.hasThreeOfAKind():
            return "Three of a kind"
        elif self.hasTwoPair():
            return "Two pair"
        elif self.hasPair():
            return "Pair"
        else:
            return "Nothing"

when I try to execute the code.

d= Deck()
h= Hand(d)
h.evaluateHand()

It gives me this error:
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
h.evaluateHand()
File "C:\Python26\Poker.py", line 237, in evaluateHand
if self.hasStraightFlush():
File "C:\Python26\Poker.py", line 228, in hasStraightFlush
if 1 in self.myranks[kitten] and 1 in self.myranks[kat]:
TypeError: argument of type 'int' is not iterable

I looked under the error in this forum, and thought that perhaps python is trying to concatenate self.myranks[kitten] and 1, so I broke the code into different lines.
But the error still remains.

How should I fix it?

4
Contributors
11
Replies
13
Views
6 Years
Discussion Span
Last Post by xtra333
0

You don't have
if 1 in self.myranks[kitten] and 1 in self.myranks[kat]:
in any of the code you posted. Is there more than one version of this program?

It apparently thinks that self.myranks[kitten] or [kat] is an integer. Do a
print type(self.myranks[kitten])
before the offending line and see what prints. Then you will have to try and discover where self.myranks[x] is set to an integer if it indeed is one now. Note that you initialize it to a list of integers, not a list of lists, i.e. a list would be
if 1 in self.myranks

How should I fix it?

Don't create it in the first place. Don't write long blocks of code without testing and ask someone else to clean up your mess. At a minimum, test each function after you write it.

def evaluateHand(self):
 
        if self.hasStraightFlush():
            return "Straight Flush"
        elif self.hasFourOfAKind():
            return "Four of a kind"
        elif self.hasFullHouse():
            return "Full House"
        elif self.hasFlush():
            return "Flush"
        elif self.hasStraight():
            return "Straight"
        elif self.hasThreeOfAKind():
            return "Three of a kind"
        elif self.hasTwoPair():
            return "Two pair"
        elif self.hasPair():
            return "Pair"
        else:
            return "Nothing"

The above function can be optimized by testing for a pair, and not testing for 3 or 4 of a kind if a pair isn't found. along the lines of:

def evaluateHand(self):
        return_lit = 'Nothing'
        if self.hasStraight():
            return_lit = "Straight"
            if self.hasStraightFlush():
                return_lit = "Straight Flush"
        elif self.hasPair():
            return_lit = "Pair"
            if self.hasThreeOfAKind():
                return_lit = "Three of a kind"
                if self.hasFourOfAKind():
                    return_lit = "Four of a kind"
                elif self.hasFullHouse():
                   return_lit = "Full House"
##   etc 

return return_lit

Edited by woooee: n/a

0

I see. so you are saying that self.myranks[kitten] is a list of integers ??
I will try printing the line like you said.
and wooee, I did know how to test before today, so that is why I wrote long lines of code.

0

And wooee, you were right the program thinks that self.myranks[kitten] is an integer. the program printed out 1.

0

So I changed my code for hasStraightFlush(self) to just the line "return hasFlush(self) and hasStraight(self)" and a new error message occurs:
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
h.evaluateHand()
File "C:\Python26\Poker.py", line 249, in evaluateHand
if self.hasStraightFlush():
File "C:\Python26\Poker.py", line 225, in hasStraightFlush
return hasFlush(self) and hasStraight(self)
NameError: global name 'hasFlush' is not defined
Why does python think hasFlush is a global name?

0

Because it hasn't been defined. You defined (and should use)
return self.hasFlush()

self.xxx means that it is a member of the class

return hasFlush(self)
is passing self to a hasFlush function outside of the class.

Edited by woooee: n/a

0

The same error happened even after I called self.hasFlush() .
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
h.evaluateHand()
File "C:\Python26\Poker.py", line 249, in evaluateHand
File "C:\Python26\Poker.py", line 225, in hasStraightFlush
# two previous methods and evaluate whether the cards satisfy the criteria through a boolean.
NameError: global name 'hasFlush' is not defined
>>>

0

Anyone have any ideas on how I should fix it? I tried Hands.hasFlush() and Hands(self).hasFlush() and Hands.hasFlush(self) all to no avail.

0

Or

Hands.hasFlush()

for outside the class Hands, or

self.hasFlush()

if it's inside the class that defines hasFlush().

Cheers and Happy coding

Edited by Beat_Slayer: n/a

0

thank you Beat_Slayer. I appreciate your response to my questions

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.