在扑克python项目中我的card dealer类出现问题

2024-05-16 01:24:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在从事德克萨斯州hold'em扑克游戏项目,并被我的新卡交易课程所困扰:

import random

cardnames = ['2C', '2D', '2H', '2S', '3C', '3D', '3H', '3S',
             '4C', '4D', '4H', '4S', '5C', '5D', '5H', '5S',
             '6C', '6D', '6H', '6S', '7C', '7D', '7H', '7S',
             '8C', '8D', '8H', '8S', '9C', '9D', '9H', '9S',
             '10C', '10D', '10H', '10S', '11C', '11D', '11H', '11S',
             '12C', '12D', '12H', '12S', '13C', '13D', '13H', '13S',
             '14C', '14D', '14H', '14S']

class Card_Dealer():
    def __init__(self):
        self.cards = cardnames
        self.cards_available = cardnames.copy()

        self.dealing_to_hands()
        self.dealing_to_table()


    def dealing_to_hands(self):
        self.playercards = []
        self.p1_cards = []
        self.p2_cards = []
        self.p3_cards = []
        self.p4_cards = []
        hands = [self.playercards, self.p1_cards,
                      self.p2_cards, self.p3_cards,
                      self.p4_cards]

        for hand in hands:
            card = random.choice(self.cards_available)
            hand[0][1] = card
            hand[0][0] = self.cards.index(card)
            self.cards_available.remove(card)
            card = random.choice(self.cards_available)
            hand[1][1] = card
            hand[1][0] = self.cards.index(card)
            self.cards_available.remove(card)


    def dealing_to_table(self):
        self.cardsontable = {1: None, 2: None, 3: None, 4: None, 5: None}
        for a in self.cardsontable:
            card_name = random.choice(self.cards_available)
            card_ind = self.cards.index(card_name)
            card = (card_ind, card_name)
            self.cardsontable[a] = card
            self.cards_available.remove(card_name)

我的第一个问题是,当我尝试调用玩家卡(例如p1_卡)时,我会收到以下错误消息:

Traceback (most recent call last):
  File "C:/Users/Buza Dani/Documents/Programming/Projects/Texas_Holdem/poker_cards.py", line 229, in <module>
    print(Card_Dealer().p1_cards)
  File "C:/Users/Buza Dani/Documents/Programming/Projects/Texas_Holdem/poker_cards.py", line 195, in __init__
    self.dealing_to_hands()
  File "C:/Users/Buza Dani/Documents/Programming/Projects/Texas_Holdem/poker_cards.py", line 211, in dealing_to_hands
    hand[0][1] = card

IndexError: list index out of range

第二个问题是,如果我能够解决第一个问题,每次我都会从类中调用一个变量,它们会发生变化,因为在初始化过程中列表会增长,而由于随机性,我调用的实际变量每次都会不同

我需要一些解释来帮助解决这些问题,因为我是一个非常初学者


Tags: tonameinselfnoneindexrandomcard
2条回答

我对您的代码段进行了一些编辑,并添加了许多注释:

# so-63712958.py

import random
    
class Card_Dealer():
    # You may define either card names as a class constant or
    # you pass it as an argument to your __init__ function
    CARDNAMES  = ['2C', '2D', '2H', '2S', '3C', '3D', '3H', '3S',
             '4C', '4D', '4H', '4S', '5C', '5D', '5H', '5S',
             '6C', '6D', '6H', '6S', '7C', '7D', '7H', '7S',
             '8C', '8D', '8H', '8S', '9C', '9D', '9H', '9S',
             '10C', '10D', '10H', '10S', '11C', '11D', '11H', '11S',
             '12C', '12D', '12H', '12S', '13C', '13D', '13H', '13S',
             '14C', '14D', '14H', '14S']

    def __init__(self):
        self.cards = cardnames
        self.cards_available = self.CARDNAMES.copy()

        # You may set the initial value of these instance
        # variables into the __init__ function.
        # Your previous implementation won't allow you
        # to deal two hands

        self.playercards = []
        self.p1_cards = []
        self.p2_cards = []
        self.p3_cards = []
        self.p4_cards = []
        self.hands = [self.playercards, self.p1_cards,
                      self.p2_cards, self.p3_cards,
                      self.p4_cards]

        # You could rethink your game with a variable number of players.
        # In that case, you can create a dict with n keys and default
        # empty list. Your players dict will correspond to the current
        # self.hands
        # You will later add another function to change cards which will
        # inspect for content for player at index n and replace in the
        # list the card(s)

        # You may shuffle cards in the __init__ since the dealer
        # is not shuffling them every time he/she puts them on
        # the table or give one to a player

        # https://stackoverflow.com/questions/10048069
        random.shuffle(self.cards_available)
        self.dealing_to_hands()

        # dealing_to_table() happens only once at __init__
        # you may not need to define it into a separate function
        # since the implementation would be quite trivial

        # I am not sure to understand why you wanted cardsontable to be a dict
        self.cardsontable = []

        for _ in range(5):
            self.cardsontable.append(self.cards_available.pop())

    def dealing_to_hands(self):
        for hand in self.hands:
            # Deal two cards to each player
            for _ in range(2):
                 hand.append(self.cards_available.pop())

if __name__ == "__main__":
    cd = Card_Dealer()
    print("Cards on the table: ", cd.cardsontable)
    print("Player 1 cards: ", cd.p1_cards)

这是建议的输出:

$ python3 so-63712958.py 
Cards on the table:  ['5C', '12S', '7H', '7C', '2S']
Player 1 cards:  ['2C', '13C']

我会选择一个字典数据结构来存储可变数量的玩家,并将表中的牌存储在列表中(与实际操作相反)。你的函数看起来像

def __init__(self, n_players):
    self.cards = cardnames
    self.cards_available = self.CARDNAMES.copy()

    # Initialize an dict with a given number of players
    # and an empty list as default value
    self.players = dict.fromkeys(range(n_players))

    random.shuffle(self.cards_available)

    # Deal two cards to each player
    for p_index in self.players:
        self.players[p_index] = []
        for _ in range(2):
            self.players[p_index].append(self.cards_available.pop())

    self.cardsontable = []
    for _ in range(5):
        self.cardsontable.append(self.cards_available.pop())

def get_card_for_player(self, p_index):
    return self.players[p_index]

def change_card_for_player(self, p_index, c_index):
    # where c_index is 0, 1
    self.players[p_index].pop(c_index)
    self.players[p_index].append(self.cards_available.pop())

下面这个简单的程序将生成以下输出

cd = Card_Dealer(4) # 4 players game
print("Cards on the table: ", cd.cardsontable)
print("Players cards: ", cd.players)
cd.change_card_for_player(0, 0) # first player change first card
print("Player 1 cards: ", cd.get_card_for_player(0))

输出:

Cards on the table:  ['2S', '8S', '13C', '13H', '5C']
Players cards:  {0: ['4C', '9D'], 1: ['4D', '14H'], 2: ['11H', '10D'], 3: ['10S', '9H']}
Player 1 cards:  ['9D', '12C']

这是否接近您在接下来的练习步骤中预期使用的值

让我们看一下这个问题的方法:

def dealing_to_hands(self):
    self.playercards = []
    self.p1_cards = []
    self.p2_cards = []
    self.p3_cards = []
    self.p4_cards = []
    hands = [self.playercards, self.p1_cards,
                  self.p2_cards, self.p3_cards,
                  self.p4_cards]

    for hand in hands:
        card = random.choice(self.cards_available)
        hand[0][1] = card

从5个空列表开始,然后将它们放在名为hands的列表中。然后你迭代那个大列表。但这些单独的列表仍然是空的。每个hand都是一个空列表,因此hand[0]会失败,hand[0][1]也会失败(您无法访问空列表的第一个条目)。相反,可以使用.append()附加到每个列表。比如:

for hand in hands:
    card = random.choice(self.cards_available)
    hand.append(card)

我想我不明白你的第二个问题。难道你不想让名单上满是随机的卡片吗?每次调用dealing_to_hands()dealing_to_table()时,都会将各种变量设置为某种原始状态。看起来cards_available确实需要不时刷新,但您可以使用一种新方法,在交易前始终刷新可用卡列表:

def deal():
    self.cards_available = cardnames.copy()
    self.dealing_to_hands()
    self.dealing_to_table()

相关问题 更多 >