这是我的第一场比赛,我真的很自豪,但我认为这是可怕的混乱。有什么办法可以改进吗?
#HANGMAN
# Valid Word Checker
def valid_word(word):
ill_chars = ["!","@","#","$","%","^","&","*","(",")",",",".", " ","1","2","3","4","5","6","7","8","9","0"]
for i in word:
if i in ill_chars:
print(f"\nError: It must be a letter. No symbols, numbers or spaces allowed. \n\n '{i}' is not allowed\n")
return False
if len(word) > 12:
print("\n\nError: Word is too long. Use a word with eight characters or less.")
return False
return True
word_list = []
spaces = []
guessed_letters = []
ill_chars = ["!","@","#","$","%","^","&","*","(",")",",",".", " ","1","2","3","4","5","6","7","8","9","0"]
head =" O"
armL = " /"
torso = "|"
armR = "\\"
legL = "/"
legR = " \\"
hangman_parts = [head, armL, torso, armR, legL, legR]
hangman_progress = ["",
"|",
"\n|",
"\n|"]
hangman_final = ["|~~~~|\n"]
# Check if word is valid
wordisValid = False
while True:
word = input("\n\n\nChoose any word\n\n\n").lower()
if valid_word(word) == True:
wordisValid = True
break
else:
continue
# Add to list
for i in word:
word_list.append(i)
spaces.append("_ ")
# Main Game Loop
bad_letter = 0
while wordisValid == True:
print("".join(hangman_final))
print("\n\n\n\n")
print("".join(spaces))
print("\n\nThe word has: " + str(len(word)) + " letters.")
print("\nYou've tried the following letters: " + "\n\n" + "".join(guessed_letters) + "\n\n")
# Winning Loop
if "".join(spaces) == word:
print(f"YOU WIN! The word was: {word}")
break
# Choose Letters
player_guess = input("\n\nPlease choose a letter: \n\n\n\n").lower()
guessed_letters.append(" " + player_guess)
if player_guess in ill_chars:
print(f"\nError: It must be a letter. No symbols, numbers or spaces allowed. \n\n '{player_guess}' is not allowed\n")
elif len(player_guess) > 1:
print("\nError: You must use one letter.\n")
elif player_guess == "":
print("\nError: No input provided.\n")
# Wrong Letter
elif player_guess not in word_list:
bad_letter += 1
if bad_letter == 1:
hangman_final.append(hangman_progress[1] + head)
elif bad_letter == 2:
hangman_final.append(hangman_progress[2] + " " + torso)
elif bad_letter == 3:
hangman_final.pop(2)
hangman_final.append(hangman_progress[2] + armL + torso)
elif bad_letter == 4:
hangman_final.pop(2)
hangman_final.append(hangman_progress[2] + armL + torso + armR)
elif bad_letter == 5:
hangman_final.append(hangman_progress[3] + " " + legL)
elif bad_letter == 6:
hangman_final.pop(3)
hangman_final.append(hangman_progress[3] + " " + legL + legR)
print("\n\nThe word was: " + word)
print("\n\n\n\n\n\n\n" + "".join(hangman_final))
print(" YOU GOT HUNG ")
break
print("".join(hangman_final))
print("\n\n\n\n")
print("".join(spaces))
print("\n\nThe word has: " + str(len(word)) + " letters.")
print("\nYou've tried the following letters: " + "\n\n" + "".join(guessed_letters) + "\n\n")
print(f"\n\n\n{player_guess} is not in the word. Try again.\n\n")
# END GAME
if bad_letter == 6:
break
# Add letters guessed to a list
counter = 0
for i in word:
if player_guess == i:
spaces[counter] = player_guess
counter += 1尽管它是有效的,我不确定我是否有正确的想法,当涉及到作出这种类型的项目。
发布于 2019-09-24 07:59:34
虽然很明显,您对python还不熟悉,但是仍然可以让它第一次运行。做得好!
目前,您有一个禁止字符列表。虽然这样可以工作,但默认情况下python允许unicode输入。这意味着人们可以输入成千上万的字母。我建议使用有效输入的白名单。如下所示:
VALID_LETTERS = "abcdefghijklmnopqrstuvwxyz" # This won't ever change, and typically this sort
# of things is a module-level variable.
def valid_word(word):
for letter in word:
if letter not in VALID_LETTERS:
print(f"Letter {letter} is not a valid letter. Please use just a-z.")
return
if len(word) > 8: # This was 12 in your script. Little mistake? And you might want a
# module-level constant for this as well.
print("\n\nError: Word is too long. Use a word with eight characters or less.")
return False
return True通常,在python中,我们从不会在加载模块时执行代码。详情请在这里阅读,以及我们如何防范它。我过会儿再谈这个。现在,这意味着我们应该尽可能多地使用函数--让我们称它们为main()和put ()。
main()将是主菜单函数。因为我们没有真正的菜单,这基本上会开始一个游戏,也许会问玩家是否想再玩一次。
游戏()将是一个让我们玩一个游戏的函数。这其中的大部分将是一个循环,以获取玩家的输入和计算游戏状态。基本上,脚本中不属于其他函数的所有内容都应该在game()函数中。
我以后会剪掉一些我们不需要的变量。当我们到达我们使用它们的地方时我会解释的。
如下所示:
def game():
# Variable naming is important. This is an example of a good name.
guessed_letters = []
# ill_chars = [...] We already have this variable before here!
# Lets assign the parts directly. We can index them as in "3rd part".
# And for ourselves, we comment the meaning to make sure we still know what it means a year
# from now.
hangman_parts = [
" O", # Head
" /", # Left Arm
"|" , # Torse
"\\", # Right Arm
"/", # Left Leg
" \\" # Right Leg
]
hangman_progress = ["",
"|",
"\n|",
"\n|"]
hangman_final = ["|~~~~|\n"]
# Check if word is valid
# Naming: should be word_is_valid, to be consistent with your other variables.
word_is_valid = False
while not word_is_valid:
word = input("\n\n\nChoose any word\n\n\n").lower()
word_is_valid = valid_word(word)
# With this loop condition, it'll keep asking until valid_word returns True. So we can just
# assign that value to word_is_valid directly.
# Since this is the word we're trying to guess, lets just push it upwards in
# the console a lot, so we won't see it all the time:
print("\n" * 100) # Prints 100 newlines.
# We don't need word_list, just word will do. We don't need spaces either.
while True: # Main game loop. We don't need to check for anything, we'll just use break or
# return to get out.现在我们要用一个列表理解。它几乎与生成器表达式相同,但它给出了一个真正的列表,因此我们可以问python它有多长:
# Calculate how many bad letters we have with a list comprehension:
bad_letter = len([letter for letter in guessed_letters if letter not in word])
draw_hangman(bad_letter)
if bad_letter > 5:
print("\n\n\n\nYOU GOT HUNG")
return
print("\n\n\n\n")你过去常常在两个不同的地方画你的绞刑架,而在一个地方做则更实用。它还确保如果您想要更改某些内容,则只需更改一次。
我也改变了画它的方法。为这个绘图操作设置一个函数更有用,并让它计算到目前为止如何从坏字母的数量中绘制。这使得绘图独立于当前的游戏状态。下面是我根据您对hangman_final的修改提出的版本:
def draw_hangman(bad_letter):
print(hangman_final, end="")
if bad_letter > 0: # Head
print(hangman_progress[1] + hangman_parts[0], end="")
if bad_letter == 2: # Torso and arms
print(hangman_progress[2] + " " + hangman_parts[2], end="")
elif bad_letter == 3:
print(hangman_progress[2] + "".join(hangman_parts[1:3]), end="")
elif bad_letter > 3:
print(hangman_progress[2] + "".join(hangman_parts[1:4]), end="")
if bad_letter > 4: # Legs
print(hangman_progress[3] + " " + hangman_parts[4], end="")
if bad_letter > 5:
print(hangman_parts[5], end="")在这里,我们需要打印我们猜到的字母,而下划线不是这样。我们可以在一行中计算和打印:
print(" ".join(letter for letter in word if letter in guessed_letters else "_"))对于每个字母,如果它包含在guessed_letters中,它就会打印出来,否则就会打印一个下划线。这是一个生成器表达式。这个函数几乎等于以下函数:
def make_word(word, guessed_letters):
result = []
for letter in word:
if letter in guessed_letters:
result.append(letter)
else:
result.append("_")
return result我说这几乎是因为它不完全是从其中产生的列表,即使在for循环中使用它或将它提供给"".join()这样的函数时,它的作用也是一样的。它的作用也更像一个循环,而不是一个函数,但这一点现在并不重要。
我们将结果提供给连接。请注意,我们将其输入到“".join(),中间有一个空格,这将在每个字母之间放一个空格,就像您以前做的那样。
print(f"\n\nThe word has: {len(word)} letters.") # f-strings are shorter, and easy to use.
print(f"\nYou've tried the following letters:\n\n{''.join(guessed_letters) }\n\n")
# For a string literal inside an f-string, use the other type of quotes
# This is another generator expression - this one returns a not-quite-list of booleans, and
# the all() builtin function returns True if and only if all results of the generator
# expression are True.
if all(letter in guessed_letters for letter in word):
print(f"You WIN!\nThe word was: {word}")
return
input_valid = False
while not input_valid:
new_letter = input("\n\nPlease choose a letter: \n\n\n\n").lower()
# VERY GOOD that you lowercase it! Prevents tons of weird behaviour.
if len(new_letter) > 1:
print("Please enter a single letter only.")
elif new_letter not in VALID_LETTERS:
print(f"{new_letter} is not a valid letter. Please enter a letter a-z")
elif not new_letter: # Empty strings evaluate to False
print("Please enter a letter before pressing enter.")
elif new_letter in guessed_letters:
print("You already guessed {new_letter} before!")
else:
guessed_letters.append(new_letter):
input_valid = True这与你的投入非常接近。但是我把它放在一个循环中,所以如果我们有一个无效的输入,我们就不用再遍历整个游戏循环了。我使用了一个非常简单的信号布尔值来保持它的运行,但是也许有更优雅的方法来做到这一点。不过,保持简单是永远不会错的。
现在,要玩这个游戏,只需调用game()函数。但也许我们想玩多场系列赛?让我们让我们的main()函数:
def main():
game()
while "y" in input("Play again? [Y/n]").lower():
game()为什么这是在一个单独的功能?再一次,为了扩展性。也许,我们想从另一个模块导入我们的游戏。如果是这样的话,我们不希望它在导入时运行,而是在调用函数时运行。所以我们用这个守卫结束这个脚本:
if __name__ == "__main__":
main()如果我们直接执行这个文件,这将运行main()函数并让我们玩游戏。但是如果我们导入它,它就不会,所以我们可以在需要的时候调用这个函数。
https://codereview.stackexchange.com/questions/229552
复制相似问题