2

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.

4

1 回答 1

2

你在做什么应该没问题。在你的 and__init__方法中DeckPlayer你应该将引用存储到game

def __init__(self, game, *args):
    self.game = game

你现在没有这样做,所以我不知道你以后会如何引用这个游戏。

例如,在玩家的draw方法中,你做game.lose(). 这需要self.game.lose()在您在__init__方法中将其分配给 self 之后。

于 2013-09-05T15:45:40.790 回答