I'm trying to make a basic card game, and in order to keep track of whose turn it is, I decided on making a game class, each instance of which is a separate game. Then when the game instance is initialised, it would also initialise the player objects and deck and card objects, and tie them to that game object. To do this I tried to pass the game object 'self' to the functions that initialise the other objects, so that they could refer back to the game object.
This has not worked. Edit: error is NameError: global name 'game' is not defined
Is the idea completely impossible/immoral/the-worst-thing-ever, or is it a perfectly viable way of achieving my aims, but I'm just implementing it incorrectly?
The whole code is at the end, but a cut-down version that hopefully will illustrate the scenario---or at least enough of it to answer the core question---in a less complicated way follows:
from collections import deque
from random import shuffle
DECK = {"value_range": (1, 6),
"black_multiple": 2,
"red_multiple": 2,
"dead": 12}
class Game:
"""A game instance."""
def __init__(self, deck=DECK):
self.deck = Deck(self, **deck)
self.deck.shuffle()
class Deck:
def __init__(self, game, value_range, black_multiple, red_multiple, dead):
self.deck = deque()
for value in range(*value_range):
for i in range(black_multiple):
self.deck.append(Card(game, value, "Black"))
for i in range(red_multiple):
self.deck.append(Card(game, value, "Red"))
for i in range(dead):
self.deck.append(Card(game))
def shuffle(self):
shuffle(self.deck)
def draw(self):
return self.deck.popleft()
And here is the whole (unfinished) code, for if that's not enough information:
from collections import deque
from random import shuffle
DECK = {"value_range": (1, 6),
"black_multiple": 2,
"red_multiple": 2,
"dead": 12}
class Game:
"""A game instance."""
def __init__(self, player_names=["Simon", "Will"], start_cards=2,
deck=DECK):
self.deck = Deck(self, **deck)
self.deck.shuffle()
self.players = deque()
for name in player_names:
self.players.append(Player(self, name))
for player in self.players:
player.draw(start_cards)
def lose(self, player):
# print(player.name + "loses.")
pass
def new_turn(self):
self.players.rotate(-1)
def get_active(self):
return self.players[0]
def get_passive(self):
return list(self.players)[1:]
class Card:
"""A card instance.
Black cards get an extra method! Dead cards have value and colour False."""
def __init__(self, game, value=False, colour=False):
self.value = value
self.colour = colour
def get_value(self):
return self.value
def get_colour(self):
return self.colour
if self.colour == "Black":
def action(self, target):
active = game.get_active()
responders = game.get_passive()
for responder in responders:
if responder.respond(self.value) == False:
continue
else:
if target == active:
target = responder
else:
target = active
break
target.draw(self.value)
class Player:
def __init__(self, game, name):
self.name = name
self.hand = {}
def draw(self, value):
for i in range(value):
try:
draw_card = game.deck.draw()
except IndexError:
game.lose(self)
break
else:
self.hand.append(draw_card)
continue
def get_hand(self):
return self.hand
class Deck:
def __init__(self, game, value_range, black_multiple, red_multiple, dead):
self.deck = deque()
for value in range(*value_range):
for i in range(black_multiple):
self.deck.append(Card(game, value, "Black"))
for i in range(red_multiple):
self.deck.append(Card(game, value, "Red"))
for i in range(dead):
self.deck.append(Card(game))
def shuffle(self):
shuffle(self.deck)
def draw(self):
return self.deck.popleft()
Thanks for taking the time to read this! I've not done much formal coding training/practice before, so I'm trying to muddle my way through learning Python by trial-and-error/PyDocs.