List.pop() 不能像预期的那样作为函数参数工作

List.pop() doesnt work as expected as a function argument

真的很奇怪我做了一个纸牌游戏并做了这个功能:

def draw_card_from_top(destination, departure): 
    if len(departure.cards) > 0:   
        destination.add_card(departure.cards.pop(0))

如果我放入目的地甲板和出发甲板,它会按预期工作。目的地牌组从出发牌组的顶部获取卡片。

但我也做了这个功能,应该给每个玩家发 8 张牌:

def deal_new_game(players, departure):
    for i in range(len(players)):
        for j in range(CARDS_PER_ROUND):
            draw_card_from_top(players[i].deck, departure) 

现在我有以下问题;每个玩家应该从出发牌组中将 8 张牌添加到他自己的目标牌组中。但是由于某种原因,每个玩家现在都有一个完整的套牌副本,所以 1 张而不是 8 张所有 32 张牌和 2 张。每个人都有相同的顺序

------ 完整的来源 ------

main.py:

import _card, _deck, _player, game

is_invalid = True
while is_invalid:
    try:
        player_count = int(input('How many players? (3 or 4): '))
        if player_count == 3 or player_count == 4:
            is_invalid = False
    except ValueError:
        pass

player = []
for i in range(player_count):
    player.append(_player.Player())

game_deck = _deck.Deck(game.create_new_deck())
game_deck.shuffle_deck()

_player.py:

import _deck

class Player():
    def __init__(self):
        self.deck = _deck.Deck()
        self.score = 0

_deck.py:

from random import shuffle

class Deck():
    # Ein Deck ist eine Ansammlung von einer oder mehreren Karten ('Card()''s)
    def __init__(self, _cards=[]):
        self.cards = _cards
    
    def print_deck(self):
        for i in range(0, len(self.cards)):
            print(self.cards[i].term)

    def shuffle_deck(self):
        shuffle(self.cards)
    
    def deck_size(self):
        return len(self.cards)

    def add_card(self, card):
        self.cards.append(card)

_card.py:

class Card():
    # Eine Karte besteht aus folgenden 3 Attributen:
        # 1. color, die Color gibt an, um welche Farbe es sich handelt, 'Kreuz', 'Pik', 'Herz', 'Raute'
        # 2. value, die Value gibt an, welchen Wert eine Karte hat. ZB hat die Herz 10 die value 10 und ein Kreuz Bube die value 11
        # 3. term, der Term gibt an wie die Karte im Spiel bereichnet wird, so ist die Herz 7 die 'H7' oder die Pik Dame 'PQ'
    def __init__(self, _color, _value, _term):
        self.color = _color
        self.value = _value
        self.term = _term

game.py:

import _card

CARDS_PER_ROUND = 8

def create_new_deck():
    cards = []
    for i in range(4):
        if i == 0:
            color = 'Kreuz'
            term_color = 'K'
        if i == 1:
            color = 'Pik'
            term_color = 'P'
        if i == 2:
            color = 'Herz'
            term_color = 'H'
        if i == 3:
            color = 'Raute'
            term_color = 'R'
        
        for value in range(7, 15):
            if value <= 10:
                term_value = str(value)
            if value == 11:
                term_value = 'B'
            if value == 12:
                term_value = 'D'
            if value == 13:
                term_value = 'K'
            if value == 14:
                term_value = "A"

            cards.append(_card.Card(color, value, term_color + term_value))    
    return cards

def draw_card_from_top(destination, departure): 
    if len(departure.cards) > 0:   
        destination.add_card(departure.cards.pop(0))

def draw_card_by_index(destination, departure, index): 
    if len(departure.cards) >= index:   
        destination.add_card(departure.cards.pop(index))

def deal_new_game(players, departure):
    for i in range(len(players)):
        for j in range(CARDS_PER_ROUND):
            draw_card_from_top(players[i].deck, departure) 
            
            # TODO irgendwas buggt hier voll rum. Spieler-Decks bestehen nach Aufruf der Funktion komplett aus vollständigen Decks.

您的 _deck.py 模块中的 mutable default parameter 引起的问题。

当您创建一个新的 Deck() 时,它的 self.card 属性对于所有实例都是相同的(因为初始化定义中的 card=[])。

如果你把它改成这样,它应该可以正常工作:

def __init__(self, _cards=None):
    self.cards = [] if _cards is None else _cards

我们的想法是避免对参数使用可变默认值。根据您希望 Deck 在使用卡片列表创建时执行的操作(制作副本或使用参考),您可能需要以不同的方式实现它。

第一个示例使用对 _cards 列表的引用。要使用副本,您可以保留可变默认值,因为您不会将其保存在对象实例中:

def __init__(self, _cards=[]):
    self.cards = _cards.copy()