Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Python appears to be passing then wrong object into a function

Here is my code I am trying to run

# -*- coding: utf-8 -*-
import pydealer
from pokerlib import HandParser
from pokerlib.enums import Value, Suit


class Player:
    def __init__(self, name: str, chips=500):
        self.name = name
        self.hand = pydealer.Stack()
        self.fold = False
        self.matching_pot = True
        self.hand_rank = None
        if name == "AI":
            self.chips = 500
        else:
            self.chips = chips

    def __str__(self):
        return self.name


class PokerGame:
    def __init__(self, players):
        self.deck = pydealer.Deck()
        self.discard_pile = pydealer.Stack()
        self.table = pydealer.Stack()
        self.players = players
        self.pot = 0
        """
        TLDR: (bet_pot=starting ante) --> pots right --> (pot=bet_pot) and bet_pot is reset --> someone raises -->repeat
        Pot and bet pot work as described, pot starts at zero and bet_pot has the initial buy in, the betting round and 
        pots right make sure that players either fold or match, at the end of that round, then bet_pot is transferred to
        pot and cleared for the next round.  Bet_pot is updated only when players raise and at the beginning.
        In addition, when a player matches his chips go to the pot not bet_pot.
        """
        self.bet_pot = 0  # Add starting bet
        self.stage = 0
        self.stage_dict = {
            0: "Pre-flop",
            1: "Post-flop/Pre-turn",
            2: "Post-turn/Pre-river",
            3: "Post-river/Final Betting round",
        }
        print("Created a game with {} players.".format(len(self.players)))

    def poker(self):
        self.deck.shuffle()
        self.deal()
        self.flop()
        self.turn()
        self.river()
        self.rank_hands()
        self.award_pot()

    def deal(self):
        for player in self.players:
            new_card = self.deck.deal(2)
            player.hand.add(new_card)

    def flop(self):
        self.discard_pile = self.deck.deal(1)
        self.table = self.deck.deal(3)
        self.stage += 1
        print("The flop is\n", self.table, "\n")

    def turn(self):
        self.discard_pile = self.deck.deal(1)
        turn_card = self.deck.deal(1)
        self.table += turn_card
        self.stage += 1
        print("The turn adds\n", turn_card)
        print("The table is\n", self.table, "\n")

    def river(self):
        self.discard_pile = self.deck.deal(1)
        river_card = self.deck.deal(1)
        self.table += river_card
        self.stage += 1
        print("The river adds\n", river_card)
        print("The table is\n", self.table, "\n")

    def convert_cards(self, convert_what, player=None):
        values = {2: Value.TWO, 3: Value.THREE, 4: Value.FOUR, 5: Value.FIVE, 6: Value.SIX, 7: Value.SEVEN,
                  8: Value.EIGHT, 9: Value.NINE, 10: Value.TEN, "Jack": Value.JACK, "Queen": Value.QUEEN,
                  "King": Value.KING, "Ace": Value.ACE}
        suits = {"Hearts": Suit.HEART, "Spades": Suit.SPADE, "Diamonds": Suit.DIAMOND, "Clubs": Suit.CLUB}
        if convert_what == "hand":
            stack = player.hand
        elif convert_what == "table":
            stack = self.table
        else:
            raise Exception("In Convert_cards, convert_what is either empty, or is an invalid option(Not hand or table")
        converted_cards = []
        for card in stack:
            card = str(card)
            temp_list = ["value", "suit"]
            for value in values.keys():
                if card.find(str(value)) == -1:
                    continue
                else:
                    temp_list[0] = values[value]
                    break
            for suit in suits.keys():
                if card.find(suit) == -1:
                    continue
                else:
                    temp_list[1] = suits[suit]
                    break
            temp_list = tuple(temp_list)
            converted_cards.append(temp_list)
        return converted_cards

    def rank_hands(self):
        for player in self.players:
            cards_to_rank = list(self.convert_cards("hand", player)) + list(self.convert_cards("table"))
            player.hand_rank = HandParser(cards_to_rank)

    def find_winner(self):
        winning_hand = HandParser([(Value.TWO, Suit.HEART)])  # Might need object to compare - I would try None
        winning_hand.parse()
        temp_winner = []
        dual_winners = False
        for player in self.players:
            player.hand_rank.parse()
            if player.hand_rank > winning_hand:
                winning_hand = player.hand
                temp_winner.append(player)
                print(player.hand_rank.handenum)
            elif player.hand_rank == winning_hand:
                dual_winners = True
                print(player.hand_rank.handenum)
        winner = temp_winner
        return winner, winning_hand, dual_winners

    def award_pot(self):
        winner, winning_hand, dual_winners = self.find_winner()
        if dual_winners:
            winnings = self.pot / 2
            winner[0].chips = winnings
            winner[1].chips = winnings
            print(f"The winners are {winner[0]}, and {winner[1]} with {winning_hand}.  They each win {winnings}")
            quit()
        else:
            winner[0].chips = self.pot
            print(f"The winner is {winner}, who won the pot of {self.pot} with {winning_hand}")
            quit()

class PokerAi(PokerGame):
    def __init__(self, name):
        super().__init__(name)

    def ai_poker(self):
        self.poker()


if __name__ == "__main__":
    game_type = "ai"  # Defaults
    user_name = "default_name"
    if game_type == "ai":
        game = PokerAi([Player(user_name, 600), Player("AI")])  # Ai player index is 1
        game.ai_poker()
# -*- coding: utf-8 -*-
import pydealer
from pokerlib import HandParser
from pokerlib.enums import Value, Suit


class Player:
    def __init__(self, name: str, chips=500):
        self.name = name
        self.hand = pydealer.Stack()
        self.fold = False
        self.matching_pot = True
        self.hand_rank = None
        if name == "AI":
            self.chips = 500
        else:
            self.chips = chips

    def __str__(self):
        return self.name


class PokerGame:
    def __init__(self, players):
        self.deck = pydealer.Deck()
        self.discard_pile = pydealer.Stack()
        self.table = pydealer.Stack()
        self.players = players
        self.pot = 0
        """
        TLDR: (bet_pot=starting ante) --> pots right --> (pot=bet_pot) and bet_pot is reset --> someone raises -->repeat
        Pot and bet pot work as described, pot starts at zero and bet_pot has the initial buy in, the betting round and 
        pots right make sure that players either fold or match, at the end of that round, then bet_pot is transferred to
        pot and cleared for the next round.  Bet_pot is updated only when players raise and at the beginning.
        In addition, when a player matches his chips go to the pot not bet_pot.
        """
        self.bet_pot = 0  # Add starting bet
        self.stage = 0
        self.stage_dict = {
            0: "Pre-flop",
            1: "Post-flop/Pre-turn",
            2: "Post-turn/Pre-river",
            3: "Post-river/Final Betting round",
        }
        print("Created a game with {} players.".format(len(self.players)))

    def poker(self):
        self.deck.shuffle()
        self.deal()
        self.flop()
        self.turn()
        self.river()
        self.rank_hands()
        self.award_pot()

    def deal(self):
        for player in self.players:
            new_card = self.deck.deal(2)
            player.hand.add(new_card)

    def flop(self):
        self.discard_pile = self.deck.deal(1)
        self.table = self.deck.deal(3)
        self.stage += 1
        print("The flop is\n", self.table, "\n")

    def turn(self):
        self.discard_pile = self.deck.deal(1)
        turn_card = self.deck.deal(1)
        self.table += turn_card
        self.stage += 1
        print("The turn adds\n", turn_card)
        print("The table is\n", self.table, "\n")

    def river(self):
        self.discard_pile = self.deck.deal(1)
        river_card = self.deck.deal(1)
        self.table += river_card
        self.stage += 1
        print("The river adds\n", river_card)
        print("The table is\n", self.table, "\n")

    def convert_cards(self, convert_what, player=None):
        values = {2: Value.TWO, 3: Value.THREE, 4: Value.FOUR, 5: Value.FIVE, 6: Value.SIX, 7: Value.SEVEN,
                  8: Value.EIGHT, 9: Value.NINE, 10: Value.TEN, "Jack": Value.JACK, "Queen": Value.QUEEN,
                  "King": Value.KING, "Ace": Value.ACE}
        suits = {"Hearts": Suit.HEART, "Spades": Suit.SPADE, "Diamonds": Suit.DIAMOND, "Clubs": Suit.CLUB}
        if convert_what == "hand":
            stack = player.hand
        elif convert_what == "table":
            stack = self.table
        else:
            raise Exception("In Convert_cards, convert_what is either empty, or is an invalid option(Not hand or table")
        converted_cards = []
        for card in stack:
            card = str(card)
            temp_list = ["value", "suit"]
            for value in values.keys():
                if card.find(str(value)) == -1:
                    continue
                else:
                    temp_list[0] = values[value]
                    break
            for suit in suits.keys():
                if card.find(suit) == -1:
                    continue
                else:
                    temp_list[1] = suits[suit]
                    break
            temp_list = tuple(temp_list)
            converted_cards.append(temp_list)
        return converted_cards

    def rank_hands(self):
        for player in self.players:
            cards_to_rank = list(self.convert_cards("hand", player)) + list(self.convert_cards("table"))
            player.hand_rank = HandParser(cards_to_rank)

    def find_winner(self):
        winning_hand = HandParser([(Value.TWO, Suit.HEART)])  # Might need object to compare - I would try None
        winning_hand.parse()
        temp_winner = []
        dual_winners = False
        for player in self.players:
            player.hand_rank.parse()
            if player.hand_rank > winning_hand:
                winning_hand = player.hand
                temp_winner.append(player)
                print(player.hand_rank.handenum)
            elif player.hand_rank == winning_hand:
                dual_winners = True
                print(player.hand_rank.handenum)
        winner = temp_winner
        return winner, winning_hand, dual_winners

    def award_pot(self):
        winner, winning_hand, dual_winners = self.find_winner()
        if dual_winners:
            winnings = self.pot / 2
            winner[0].chips = winnings
            winner[1].chips = winnings
            print(f"The winners are {winner[0]}, and {winner[1]} with {winning_hand}.  They each win {winnings}")
            quit()
        else:
            winner[0].chips = self.pot
            print(f"The winner is {winner}, who won the pot of {self.pot} with {winning_hand}")
            quit()

class PokerAi(PokerGame):
    def __init__(self, name):
        super().__init__(name)

    def ai_poker(self):
        self.poker()


if __name__ == "__main__":
    game_type = "ai"  # Defaults
    user_name = "default_name"
    if game_type == "ai":
        game = PokerAi([Player(user_name, 600), Player("AI")])  # Ai player index is 1
        game.ai_poker()

And after inputing nothing(by pressing return) until the end, I get the error:

Traceback (most recent call last):
  File "/Users/jchampeau/PycharmProjects/CP2-Final-Project/main.py", line 319, in <module>
    game.ai_poker()
  File "/Users/jchampeau/PycharmProjects/CP2-Final-Project/main.py", line 306, in ai_poker
    self.poker()
  File "/Users/jchampeau/PycharmProjects/CP2-Final-Project/main.py", line 63, in poker
    self.award_pot()
  File "/Users/jchampeau/PycharmProjects/CP2-Final-Project/main.py", line 270, in award_pot
    winner, winning_hand, dual_winners = self.find_winner()
  File "/Users/jchampeau/PycharmProjects/CP2-Final-Project/main.py", line 259, in find_winner
    if player.hand_rank > winning_hand:
  File "/Users/jchampeau/Library/Python/3.8/lib/python/site-packages/pokerlib/_handparser.py", line 69, in __gt__
    if self.handenum != other.handenum:
AttributeError: 'Stack' object has no attribute 'handenum'

Based on my understanding of the error, the function is receiving the wrong class/object which I don’t know why it is happening.
Which is interesting because the if statement works because I can see the handenum of the winning hand.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I have tried debugging it but the variable look fine in the debugger and the code prints the print(player.handenums)
I am not expecting to get an error, instead I am expecting the code to run/move on to and display the award pot print statements.

>Solution :

I believe this is your problem.

class Player:
    def __init__(self, name: str, chips=500):
        self.name = name
        self.hand = pydealer.Stack()
        ...

class PokerGame:
    ...
    def find_winner(self):
        winning_hand = HandParser([(Value.TWO, Suit.HEART)])
        ...
        for player in self.players:
            ...
            if player.hand_rank > winning_hand:
                winning_hand = player.hand

winning_hand and player.hand_rank both start as HandParser objects.

But then inside the loop, when player.hand_rank > winning_hand is true, winning_hand is reassigned to player.hand, which is a Stack object.

So on the next loop iteration, you try to compare a HandParser object to a Stack object, and you get the error.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading