Really weird I make a card game and made this function:
def draw_card_from_top(destination, departure):
if len(departure.cards) > 0:
destination.add_card(departure.cards.pop(0))
it works as expected if I put in a destination deck and a departure deck. The destination deck gets the card from the top of the departure deck.
But I also made this function which should deal 8 cards to every player:
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)
Now I have the following problem; each player should add 8 cards from the departure deck to his own, the destination deck. But for some reason each of the players now has a complete copy of the deck, so 1 instead of 8 all 32 cards and 2. Everyone has the same order
------ Complete source -------
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.
CodePudding user response:
The problem caused by the mutable default parameter in your _deck.py
module.
When you create a new Deck(), its self.card attribute is the same for all instances (because of card=[]
in the init definition).
If you change it to this, it should work properly:
def __init__(self, _cards=None):
self.cards = [] if _cards is None else _cards
The idea is to avoid using a mutable default for a parameter. Depending on what you want the Deck to do when it is created with a card list (make a copy or use the reference), you may need to implement this differently.
The first example uses a reference to the _cards list. To use a copy, you could keep the mutable default since you're not going to save it in the object instance:
def __init__(self, _cards=[]):
self.cards = _cards.copy()