0

我正在使用 Python 3 和 PySide 创建一个新游戏。该游戏是游戏密码的简单 UI,基本上从列表中拉出一个随机值,显示它,一旦完成值(单词),从列表中删除该单词,以免使用两次。奇怪的问题是,GUI 一次只允许选择 4 个单词,然后抛出一个 ValueError,说列表是空的,这显然是错误的,因为你只经历了 4 个单词才会出现错误。

#!/usr/bin/python

import sys
from PySide import QtCore, QtGui
from random import *

from game_gui import Ui_main_window
from game_list import cards




class game_window(QtGui.QWidget, Ui_main_window):
    def __init__(self, parent=None):
        super(game_window, self).__init__(parent)

        self.setupUi(self)

        global password_label
        password_label = self.password_label

        global get_button
        get_button = self.get_button
        get_button.clicked.connect(self.button_clicked)


    def label_clear(self):
        password_label.setText('Push Button To Get New Word')
        get_button.setText('Push Me To Get A Word')
        get_button.clicked.connect(self.button_clicked)

    def button_rename(self):
        get_button.setText('Push To Clear Word')
        get_button.clicked.connect(self.label_clear)


    def button_clicked(self):
        card_to_play = choice(cards)

        password_label.setText(card_to_play)
        cards.remove(card_to_play)
        self.button_rename()


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = game_window()
    window.show()
    sys.exit(app.exec_())

错误是:

Traceback (most recent call last):
  File "/usr/lib/python3.3/random.py", line 249, in choice
    i = self._randbelow(len(seq))
  File "/usr/lib/python3.3/random.py", line 225, in _randbelow
    r = getrandbits(k)          # 0 <= r < 2**k
ValueError: number of bits must be greater than zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "game_code.py", line 58, in button_clicked
    card_to_play = choice(cards)
  File "/usr/lib/python3.3/random.py", line 251, in choice
    raise IndexError('Cannot choose from an empty sequence')
IndexError: Cannot choose from an empty sequence

这两个错误都出现了约 50 次。

任何帮助是极大的赞赏。

编辑:根据要求,这是列表。

cards = [
    'scripture',
    'miracle',
    'garment',
    'prophecy',
    'tomb',
    'staff',
    'spirit',
    'garden of eden',
    'heaven',
    'sulpher',
    'nephelim',
    'knowledge',
    'armageddon',
    'plague',
    'commandment',
    'sovereignty',
    'resurrection',
    'wine',
    'cherub',
    'sandals',
    'wilderness',
    'gehena',
    'famine',
    'temple',
    'passover',
    'baptism',
    'leprosy',
    'ark',
    'drachma',
    'pharaoh',
    'levites',
    'scroll',
    'chaff',
    'boils',
    'Holy Spirit',
    'dragon',
    'lots',
    'Babylon',
    'tent',
    'parable',
    'scales',
    'Urim & Thummim',
    'scarlet',
    'transfiguration',
    'flame',
    'wild beast',
    'straw',
    'Red Sea',
    'pearl',
    'emerald',
    'swine',
    'demon',
    'Tartarus',
    'wine',
    'turtledove',
    'gnat',
    'camel',
    'garment',
    'shroud',
    'tomb',
    'Most Holy',
    'curtain,'
    'olive branch',
    'dust',
    'Cherub',
    'bull',
    'scorpion',
    'Nephilim',
    'privy',
    'sacrifice',
    'earthquake',
    'abyss',
    'fasting',
    'stake',
    'sling',
    'Samson',
    'Goliath',
    'betrayer',
    'slanderer',
    'murderer',
    'circumcision',
    'astrologer',
    'Hades',
    'chariot',
    'cistern',
    'balsalm',
    'undergarment',
    'bruise',
    'shipwreck',
    'fish',
    'intestines',
    'conscience',
    'curtain',
    'hypocrisy',
    'whitewash',
    'grave',
    'spear',
    'breastplate',
    'helmet',
    'leviathan',    
    ]
4

1 回答 1

1

cards发生这种情况时显然是空的。

len(seq)然后是0,导致ValueError,但这IndexError是您必须担心的另一个异常。

您的代码会立即在同一函数中删除该单词,而不是稍后,因此每次button_clicked()调用时,您都会从中删除一个随机元素cards

演示显示带有空列表的异常:

>>> from random import choice
>>> choice([])
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/random.py", line 249, in choice
    i = self._randbelow(len(seq))
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/random.py", line 225, in _randbelow
    r = getrandbits(k)          # 0 <= r < 2**k
ValueError: number of bits must be greater than zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/random.py", line 251, in choice
    raise IndexError('Cannot choose from an empty sequence')
IndexError: Cannot choose from an empty sequence

您必须通过调试语句找出为什么您的列表被清空的速度比您想象的要快。

请注意,您正在操作一个全局列表,因此从该列表中删除选项不会在您完成游戏时恢复它们。随着单词被删除,您的列表将继续缩小,直到为空。

也许您想跟踪您使用的单词。存储您在一组中使用的卡片:

class game_window(QtGui.QWidget, Ui_main_window):
    def __init__(self, parent=None):
        super(game_window, self).__init__(parent)

        self.used = set()

        # rest of your `__init__`

    # ...

    def button_clicked(self):
        while True:
            card_to_play = choice(cards)
            if card_to_play not in self.used:
                break
            if not set(cards).difference(self.used):
                raise ValueError('Not enough cards, used {}, can pick from {}'.format(len(self.used), len(set(cards))))

        password_label.setText(card_to_play)
        self.used.add(card_to_play)
        self.button_rename()

现在cards保持不变,每个新game_window的都会有一个新的空used集来填补。或者,您可以在想要重新开始游戏时重置used(使用 将其设置为新的、新鲜的、空的集合)。self.used = set()

于 2013-05-20T23:49:45.880 回答