我正在创建一个简单的子手游戏程序,其中的密码是从大型词典(300,000多个单词)中选择的。我正在用一个更小的字典来测试代码,而我想要过滤掉的东西之一就是任何包含大写字母的单词。我一直在尝试这样做,但是目前我的代码只会过滤掉一些包含大写或完全大写的单词。
代码如下:
class Hangman(object):
def __init__(self, level=5, non_ascii=False, dictionary='ezdict.txt', allow_uppercase=False, non_alpha=False):
global os
import os
import random
self.level = level
self.score = 0
self.loss = 6
self.wordbank = []
self.used_letters = []
self.game_dict = []
self.empty_gallows = " _____\n | |\n |\n |\n |\n |\n |\n |\n_|_________\n|/ \|\n| |"
self.first_gallows = " _____\n | |\n | O\n |\n |\n |\n |\n |\n_|_________\n|/ \|\n| |"
self.second_gallows = " _____\n | |\n | O\n | |\n |\n |\n |\n |\n_|_________\n|/ \|\n| |"
self.third_gallows = " _____\n | |\n | O\n | /|\n |\n |\n |\n |\n_|_________\n|/ \|\n| |"
self.fourth_gallows = " _____\n | |\n | O\n | /|\\\n |\n |\n |\n |\n_|_________\n|/ \|\n| |"
self.fifth_gallows = " _____\n | |\n | O\n | /|\\\n | /\n |\n |\n |\n_|_________\n|/ \|\n| |"
self.sixth_gallows = " _____\n | |\n | O\n | /|\\\n | / \\\n |\n |\n |\n_|_________\n|/ \|\n| |"
self.gal_list = [self.empty_gallows, self.first_gallows, self.second_gallows, self.third_gallows, self.fourth_gallows, self.fifth_gallows, self.sixth_gallows]
with open(dictionary, 'r') as file:
self.words = file.read().split('\n')
for i in self.words:
if (len(i) <= self.level) and (len(i) > 0):
self.game_dict.append(i)
if non_ascii == False:
for i in self.game_dict:
try:
i.encode('ascii')
except UnicodeEncodeError:
self.game_dict.remove(i)
if non_alpha == False:
for i in self.game_dict:
if i.isalpha() != True:
self.game_dict.remove(i)
if allow_uppercase == False:
for i in self.game_dict:
if any(letter.isupper() for letter in i):
self.game_dict.remove(i)
self.secret_word = random.choice(self.game_dict)
for i in list(self.secret_word):
self.wordbank.append('_')
os.system('clear')
def __play_again(self):
play_again = input("Would you like to play again? Type 'yes' or 'no': ")
if play_again == 'yes':
Hangman().play()
elif play_again == 'no':
os.system('clear')
exit
else:
print('Please check your input and try again.')
self.__play_again()
def play(self): # Think about implementing an option to choose the word
print(self.game_dict) # For Testing
print(self.gal_list[self.score])
print('\n', ' '.join(self.wordbank))
print('\nPREVIOUSLY GUESSED LETTERS:', ' '.join(self.used_letters))
self.__user_input()
def __user_input(self):
print(self.secret_word) # For testing
self.guess = ''
while self.guess == '':
self.guess = input('Guess a letter: ')
if len(self.guess) != 1:
os.system('clear')
print('Please guess a single letter!')
self.play()
elif self.guess in self.used_letters:
os.system('clear')
print('This letter has already been guessed.')
self.play()
elif len(self.guess) == 1:
if self.guess in self.secret_word:
for i in range(len(self.secret_word)):
if self.guess == self.secret_word[i]:
self.wordbank[i] = self.guess
#print(self.wordbank) # For testing
else:
self.score += 1
self.used_letters += self.guess
win_check = ''
for i in self.wordbank:
win_check += i
if win_check == self.secret_word:
os.system('clear')
print("You've won the game!")
self.__play_again()
elif self.score == self.loss:
os.system('clear')
print("Sorry, you've lost this round...")
print('The secret word was ' + str(self.secret_word) + '.')
self.__play_again()
else:
os.system('clear')
self.play()
h = Hangman()
h.play()
引起问题的部分是这样:
if allow_uppercase == False:
for i in self.game_dict:
if any(letter.isupper() for letter in i):
self.game_dict.remove(i)
文本文件包含以下单词,这些单词包含在名为“ exdict.txt”的文件中:
twinkle
little
star
how
wonder
what
you
are
up
above
the
world
so
high
like
diamond
in
sky
ABC
DEF
XYZ
HIK
bourrées
günter
contraction's
bob's
o'connell
对于大写字母,似乎只检查列表中的所有其他单词,但我完全感到困惑。它应该过滤掉所有带有大写字符的单词,但其中一半始终存在。启动游戏时会打印出可用单词列表(self.game_dict)。
答案 0 :(得分:2)
您是modifying the data structure while iterating over,会导致完全错误的循环:
永远不要更改要循环的容器,因为该容器上的迭代器 不会通知您所做的更改,并且 您已经注意到,很可能会产生完全不同的循环 和/或不正确的。
相反,重新定义game_dict
来过滤掉不需要的项目:
if allow_uppercase == False:
self.game_dict = [item for item in self.game_dict
if not any(letter.isupper() for letter in item)]