创建了一个无限循环,但不知道为什么它是无限的

Created an endless loop, but can't tell why it is endless

所以我正在 python 使用 classes 创建纸牌游戏。我把它全部设置到它应该工作的地步。但是当我 运行 它只是永远不会停止 运行。我不太确定如何使此代码最小化并可重现,因为我不知道问题出在哪里。 这是我写的代码。

它必须在 play_uno() class 对象中。

""" UNO Simulator """
import random

class card():
    def __init__(self, value, color, wild):
        '''
        An UNO deck consists of 108 cards, of which there are 76 Number cards,
        24 Action cards and 8 Wild cards. UNO cards have four color "suits",
        which are red, yellow, blue and green.
        '''
        self.card_nums = ['0','1','2','3','4','5','6','7','8','9']
        self.card_colors = ['red','blue','green','yellow']
        self.spec_cards = ['draw2','reverse','skip']
        self.wild_cards = ['wild','wild_draw_4']
        if wild == False:
            self.value = self.card_nums[value]
            self.color = self.card_colors[color]
        elif wild == 'special':
            self.value = self.spec_cards[value]
            self.color = self.card_colors[color]
        elif wild == True:
            self.value = self.wild_cards[value]
            self.color = None

class generate_deck():
    def __init__(self):
        self.number_cards = self.get_num_cards()
        self.special_cards = self.get_special_cards()
        self.wild_cards = self.get_wild_cards()
        self.cards = self.number_cards + self.special_cards + self.wild_cards
        random.shuffle(self.cards)

    def get_num_cards(self):
        # only one zero per color
        with_zeroes = [card(i,j,False) for i in range(10) for j in range(4)]
        no_zeroes = [card(i,j,False) for i in range(1,10) for j in range(4)]
        return no_zeroes + with_zeroes

    def get_wild_cards(self):
        wild_draw4s = [card(i,None,True) for i in range(2) for x in range(2)]
        wilds = [card(i,None,True) for i in range(2) for x in range(2)]
        return wilds + wild_draw4s

    def get_special_cards(self):
        return [card(i,j,'special') for i in range(3) for j in range(4) for x in range(2)]

class player():
    def __init__(self, name):
        self.wins = 0
        self.name = name
        self.cheater = False
        self.cards = ''
        self.turn = 0
        self.uno = 0

class play_uno():
    def __init__(self, num_players = 3, num_cheaters = 0, cards_per_player = 5):
        # get started
        self.rules = 'default'
        self.status = 'ongoing'
        self.deck = generate_deck().cards
        self.played_cards = []
        self.dro = 0
        self.direction = 0
        self.top_card = self.deck.pop() # random card as first card to play on
        self.tot_turns = 0

        # generate players, make cheaters later
        self.players = [player('player' + str(i)) for i in range(num_players + num_cheaters)]

        # give each player 7 cards to start
        for _player_ in self.players:
            _player_.cards = [self.draw_card() for i in range(cards_per_player)]

        # start playing turns in order
        # do not know how to reverse yet
        """
        Right now it is endless for some reason.
        """
        while self.status == 'ongoing':
            for _player in self.players:
                self.turn(_player)

    def draw_card(self):
         # draws random card from deck instead of card on top
         if len(self.deck) == 0:
             self.re_shuffle()
             self.dro += 1
         return self.deck.pop()

    def re_shuffle(self):
         self.deck = self.played_cards
         random.shuffle(self.deck)
         self.played_cards = []
         return self.deck, self.played_cards

    def play_card(self, player_cards, _card):
        self.top_card = _card
        return player_cards.remove(_card), self.played_cards.append(_card), self.top_card

    def game_over(self, winner):
        winner.wins += 1
        self.game_status = 'over'

    def turn(self, _player):
        played = False
        # check if someone played wild card last turn
        if self.top_card.value in card(1,2,None).wild_cards:
            self.top_card.color = random.choice(card.card_colors)
            if self.top_card.value == 'wild_draw_4':
                _player.cards += [self.draw_card() for i in range(4)]
                self.tot_turns += 1
                return _player
        # check for special cards
        elif self.top_card.value in card(1,2,None).spec_cards:
            if self.top_card.value == 'draw2':
                _player.cards += [self.draw_card() for i in range(4)]
                self.tot_turns += 1
                return _player
            # for now we are treating reverse cards like skips
            elif self.top_card.value == 'reverse' or self.top_card.value == 'skip':
                played = True
                self.tot_turns += 1
                return _player
        # If its a normal card, or regular wild
        if played == False:
            for _card in _player.cards:
                if _card.color == self.top_card.color:
                    self.play_card(_player.cards, _card)
                    played = True
                    break
                elif _card.value == self.top_card.value:
                    self.play_card(_player.cards, _card)
                    played = True
                    break
        # if the player cannot play at all
        # rn they just move on if they have to draw,
        # cant play the card they just drew.
        if played == False:
            _player.cards += [self.draw_card()]
            played = True
            self.tot_turns += 1
        # check if the player won or not
        if len(_player.cards) == 0:
            self.game_over(_player)
        elif len(_player.cards) == 1:
            _player.uno += 1
        return _player.cards

play_uno__init__ 末尾的 while 循环检查 status,它永远不会改变。

循环在每次迭代 players 中的每一个上调用 turn。您必须在某处更改 status 或者您必须在 while 循环中放置一个 if ...: break(例如 if not _player.cards)。

编辑:看来您在 game_over 中的意思是 self.status 而不是 self.game_status。尝试将 game_status 更改为 status

我没有 运行 代码,但我认为您应该在再次抽奖之前测试玩家的牌数。像这样:

if len(_player.cards) == 0:
    self.game_over(_player)
elif len(_player.cards) == 1:
    _player.uno += 1

if played == False:
    _player.cards += [self.draw_card()]
    played = True
    self.tot_turns += 1

或者说这个游戏的规则不一样?我真的不记得了。

play_uno class 的函数 turn 中,您正在检查某些 wild/special 卡片。例如,如果该值为 reverse,则函数命中 return _player 行,该行结束函数的执行,玩家无法再玩另一张牌。

如果要确保其余代码是 运行.

,请将 return 语句移至函数末尾