Python 似乎将错误的对象传递给函数

问题描述 投票:0回答:2

这是我要运行的代码

# -*- 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()

在没有输入任何内容(按回车键)直到最后,我得到错误:

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'

根据我对错误的理解,该函数正在接收错误的类/对象,我不知道为什么会这样。 这很有趣,因为 if 语句有效,因为我可以看到获胜手的 handenum。

我试过调试它但是变量在调试器中看起来很好并且代码打印了

print(player.handenums)
我不希望出现错误,而是希望代码运行/继续并显示奖池打印语句。

python python-3.x runtime-error poker
2个回答
0
投票

我相信这是你的问题。

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
player.hand_rank
都以
HandParser
对象开始。

但是在循环内部,当

player.hand_rank > winning_hand
为真时,
winning_hand
被重新分配给
player.hand
,这是一个
Stack
对象。

因此在下一个循环迭代中,您尝试将一个

HandParser
对象与一个
Stack
对象进行比较,并且您得到了错误。


0
投票

第259行:

winning_hand = player.hand
是一个
Stack
实例。
player.hand_rank
是一个
HandParser
并且与第 259 行赋值之前的
winning_hand
类型相同。更改为
winning_hand = player.hand_rank
似乎有效,但我没有详尽测试。建议学习使用源代码调试器:)

© www.soinside.com 2019 - 2024. All rights reserved.