我必须用Python编写有关玩playing子手游戏的代码。目前,我的代码无法用猜中的字母正确替换“ _”,只能替换其中的一个而不显示所有猜中的字母。
我的代码如下:
import random
word = random.choice(["bread", "clouds", "plane"])
guess = 0
correct_guess = 0
play_again = True
print(word)
name = input("Hello, what's your name? ")
print('Hello', name)
status = input('Do you wish to play hangman? Yes/No ')
hyphens = print('_ ' * (len(word)))
if status == 'No' 'no' 'N' 'n':
exit()
while play_again is True:
letter = input('Guess a letter: ')
if letter in word:
guess = guess + 1
correct_guess = correct_guess + 1
print('You guessed a letter correctly!')
position = word.find(letter)
print("The letter is in position", position + 1, "out of", len(word), "in the word. Guess Count:", guess)
if position == 0:
print(letter, "_ _ _ _")
if position == 1:
print("_", letter, "_ _ _ ")
if position == 2:
print("_ _", letter, "_ _ ")
if position == 3:
print("_ _ _", letter, "_ ")
if position == 4:
print("_ _ _ _", letter)
else:
guess = guess + 1
print("That letter isn't in the word. Guess Count:", guess)
if guess == 10:
print('Bad luck. You lost.')
play = input('Do you want to play again? ')
if play == 'No' 'no' 'N' 'n':
exit()
if correct_guess == 5:
print('Congratulations! You have guessed the word! The word was', word + '.')
play = input('Do you want to play again? ')
if play == 'No' 'no' 'N' 'n':
exit()
非常感谢您的帮助。另外,我对编程知识不多,而且还很陌生。
詹姆斯
答案 0 :(得分:1)
您不能像这样写表达式:
if status == 'No' 'no' 'N' 'n':
正确的方法是:
if play == 'No' or play == 'no' or play == 'N' or play == 'n':
或:
if play in ['No' ,'no', 'N' ,'n']
一种解决方案:
import random
word = random.choice(["bread", "clouds", "plane"])
print(word)
name = input("Hello, what's your name? ")
print('Hello', name)
status = input('Do you wish to play hangman? Yes/No ')
def play():
if status == 'No' or status == 'no' or status == 'N' or status == 'n':
print ("Goodbye")
return # exit
else:
print('_ ' * (len(word))) # _ _ _ _ _
guess = 0
correct_guess = 0
play_again = True
pos_list = ['_' for x in range(len(word))] # define list where you will put your guessed letters ['_', '_', '_', '_', '_']
while play_again is True:
letter = input('Guess a letter: ')
if letter in word:
guess = guess + 1
correct_guess = correct_guess + 1
print('You guessed a letter correctly!')
position = word.find(letter)
print("The letter is in position", position + 1, "out of", len(word), "in the word. Guess Count:", guess)
pos_list[position] = letter # save letter at position # ['_', '_', '_', 'a', '_']
print (' '.join(pos_list)) # _ _ _ a _
else:
guess = guess + 1
print("That letter isn't in the word. Guess Count:", guess)
if guess == 10:
print('Bad luck. You lost.')
play = input('Do you want to play again? ')
if play == 'No' or play == 'no' or play == 'N' or play == 'n':
print("Goodbye")
return
else:
print('_ ' * (len(word)))
if correct_guess == len(word):
print('Congratulations! You have guessed the word! The word was', word + '.')
play = input('Do you want to play again? ')
if play == 'No' or play == 'no' or play == 'N' or play == 'n':
print("Goodbye")
return
else:
print('_ ' * (len(word)))
play()
答案 1 :(得分:0)
稍微清理一下,删除重复的代码。也是有问题的情况:
if status == 'No' 'no' 'N' 'n':
将其更改为:
if status.lower().startswith("n"):
降低用户输入的字母也很重要。这里是完整的工作代码。
import random
import re
def start():
status = input('Do you wish to play hangman? Yes/No ')
if status.lower().startswith("n"):
return True
# Computer chooses word
word = random.choice(["bread", "clouds", "plane"])
# Setup game vars
guess = []
game_status = ["_"] * len(word)
while True:
print(" ".join(game_status))
letter = input('Guess a letter: ').lower()
if letter in guess:
print("You already tried that one.")
continue
guess.append(letter)
if letter in word:
print('You guessed a letter correctly!')
positions = [m.start() for m in re.finditer(letter, word)]
for pos in positions:
game_status[pos] = letter
else:
print("That letter isn't in the word.")
if len(guess) == 10:
print(f'Bad luck {name}. You lost. The word was: {word}.')
return
if "_" not in game_status:
print(f'Congratulations {name}! You have guessed the word! The word was {word}.')
return
# Welcome
name = input("Hello, what's your name? ")
print('Hello', name)
while True:
stop = start()
if stop:
break
print("Goodbye!")
答案 2 :(得分:0)
TL; DR :' '.join(l if l in guessed_letters else '_' for l in word)
是一个衬里,但对于OP,我已经详细介绍了。
我想对我的评论稍加扩展。
编写出色代码的一种方法是颠倒编写和测试代码,然后对尚未编写的代码进行先测试。这就是测试驱动的开发。
有许多测试代码的工具,例如unittest
,但我将在此处演示的一个工具是pytest
。
首先,我们确定我们要实现的一小部分功能。在这种情况下,以hangman形式返回字符串。这需要两个输入,我们要猜的单词和字母要猜的单词。我想将其实现为一个函数,所以我将编写该函数,但现在放置pass
。
现在是时候用输入和期望输出注释功能了。 现在总比没有好。
def hangman_word(word, guessed_letters):
"""Returns a string in hangman form where letters are hyphens
or guessed letters. Letters or hyphens are space separated.
`word` is a string. This is the word to be printed in hangman form.
`guessed_letters` is a list of the letters guessed that should be shown.
For example::
>>> hangman_word('bordereau', ['o', 'd', 'e'])
'_ o _ d e _ e _ _'
"""
pass
然后我们编写测试,但是我们故意这样做。我们想涵盖可能出问题的不同方面...不要猜测字母,重复字母,字母顺序与单词顺序不同。每个测试都针对每个方面。 Pytest将对以test_
开头的函数运行测试。
def test_hangman_word_no_guessed_letters():
assert hangman_word('zonule', []) == '_ _ _ _ _ _'
def test_hangman_word_one_letter():
assert hangman_word('zonule', ['n']) == '_ _ n _ _ _'
def test_hangman_word_multiple_letters_ordered():
assert hangman_word('zonule', ['n', 'u']) == '_ _ n u _ _'
def test_hangman_word_multiple_letters_unordered():
assert hangman_word('zonule', ['u', 'n']) == '_ _ n u _ _'
def test_hangman_word_repeated_letters():
assert hangman_word('bordereau', ['o', 'd', 'e']) == '_ o _ d e _ e _ _'
def test_hangman_word_guessed_letter_wrong():
assert hangman_word('hypostrophe', ['o', 'd', 'e']) == '_ _ _ o _ _ _ o _ _ e'
def test_hangman_word_multiple_repeats():
assert hangman_word('intempestive', ['t', 'd', 'e']) == '_ _ t e _ _ e _ t _ _ e'
def test_hangman_word_all_letters():
assert hangman_word('intempestive', list('intempestive')) == 'i n t e m p e s t i v e'
if __name__ == '__main__':
print('main has run')
如果我运行pytest,则使用功能hangman_word
和这些测试一起在名为hang_man.py
的文件中进行测试
C:\Users\Andrew\Desktop>pytest hang_man.py
我会得到详细的报告
C:\Users\Andrew\Desktop>pytest hang_man.py
============================= test session starts =============================
platform win32 -- Python 3.4.0, pytest-4.2.0, py-1.7.0, pluggy-0.8.1
rootdir: C:\Users\Andrew\Desktop, inifile:
collected 8 items
hang_man.py FFFFFFFF [100%]
================================== FAILURES ===================================
____________________ test_hangman_word_no_guessed_letters _____________________
def test_hangman_word_no_guessed_letters():
> assert hangman_word('zonule', []) == '_ _ _ _ _ _'
E AssertionError: assert None == '_ _ _ _ _ _'
E + where None = hangman_word('zonule', [])
hang_man.py:21: AssertionError
________________________ test_hangman_word_one_letter _________________________
def test_hangman_word_one_letter():
> assert hangman_word('zonule', ['n']) == '_ _ n _ _ _'
E AssertionError: assert None == '_ _ n _ _ _'
E + where None = hangman_word('zonule', ['n'])
<<REMOVED>>
========================== 8 failed in 0.21 seconds ===========================
因此所有8个测试均失败。 好。现在我们可以编写代码了。
现在我知道足够的python编写一个内衬,所以我将pass
替换为
return ' '.join(l if l in guessed_letters else '_' for l in word)
当我再次运行pytest时...
C:\Users\Andrew\Desktop>pytest hang_man.py
=========================================================================================================== test session starts ============================================================================================================
platform win32 -- Python 3.4.0, pytest-4.2.0, py-1.7.0, pluggy-0.8.1
rootdir: C:\Users\Andrew\Desktop, inifile:
collected 8 items
hang_man.py ........ [100%]
=================== 8 passed in 0.13 seconds ===================
这里的要点是我拥有知道的可重复使用的代码,因为我已经对其进行了测试,现在我可以继续进行其他方面的工作,例如计算不正确的猜测和无效的输入方面。
我决定使用面向对象的状态模式设计(出于自我学习的目的)来实现此目的,因此我想也将其保留在这里。虽然代码比功能样式大,但优点是代码可测试性强,可以很好地将游戏机制与输入分开。
运行游戏只是运行问题:
game = Context('represents', lives=15)
game.startGame()
class Context(object):
"""A class that keeps track of the hangman game context and current state.
This follows a State Design Pattern.
`word` is string. This is the word to guess.
`guessed_letters` is a list containing letters guessed
`lives` is a number that is the number of incorrect guesses allowed.
`state` is class representing the state of the game.
`message` is a string message from processing the letter guess.
The :meth:`.process` method processes guessed letters, updating the
lives, guessed_letters and message for the gameplay.
"""
def __init__(self, word, lives=10):
self.word = word
self.guessed_letters = []
self.lives = lives
self.state = HoldingState()
self.message = ''
def won(self):
"""Tests if all letters of in word are in guessed_letters"""
return all(l in self.guessed_letters for l in self.word)
def lost(self):
"""Tests if we have run out of lives"""
return self.lives <= 0
def hangman_word(self):
"""Returns a string in hangman form where letters are hyphens
or guessed letters. Letters or hyphens are space separated.
`word` is a string. This is the word to be printed in hangman form.
`guessed_letters` is a list of the letters guessed that should be shown.
For example::
>>> hangman_word('bordereau', ['o', 'd', 'e'])
'_ o _ d e _ e _ _'
"""
return ' '.join(l if l in self.guessed_letters else '_' for l in self.word)
def process(self, letter):
"""Requests the state to process the guessed letter.
The State takes care of updating the lives, guessed_letters and providing a
message for the gameplay"""
self.state.process(letter, self)
def startGame(self):
"""Runs the game.
Checks for final states (WonState / DeadState) else shows the hangman
word, letters guessed and takes as input the letter guessed and
processes this.
"""
while True:
if self.state == WonState():
print(f'You win! The word was indeed {self.word}')
return
if self.state == DeadState():
print(f'You lose! The word was {self.word}')
return
print('Hangman Word:', self.hangman_word() + '\n')
print('Letters guessed: ' + ' '.join(sorted(self.guessed_letters)) + '\n')
letter = input('Guess a letter: ')
self.process(letter)
print('\n' + self.message + '\n')
class BaseState(object):
"""Represents a state of the context.
This is an abstract base class. Subclasses must override and
implement the :meth:`.process` method.
The :meth:`.process` method updates the context variables and changes the
context state.
"""
def process(self, letter, context):
"""Updates the context variables and changes the context state..
**This method is not implemented in this base class; subclasses
must override this method.**
"""
raise NotImplementedError
def __eq__(self, other):
"""Overrides the default implementation
Tests equality of states by testing if there are the same class
"""
if isinstance(other, self.__class__):
return True
return False
class HoldingState(BaseState):
"""The default state."""
def process(self, letter, context):
if letter in context.guessed_letters:
context.state = RepeatedGuessState()
elif letter in context.word:
context.state = CorrectGuessState()
else:
context.state = IncorrectGuessState()
# Calls process again to return to HoldingState / WonState / DeadState
context.state.process(letter, context)
class RepeatedGuessState(BaseState):
"""An intermediate state."""
def process(self, letter, context):
context.message = "You've repeated a guess!"
context.state = HoldingState()
class CorrectGuessState(BaseState):
"""An intermediate state."""
def process(self, letter, context):
context.message = "Correct guess!"
context.guessed_letters.append(letter)
if context.won():
context.state = WonState()
else:
context.state = HoldingState()
class IncorrectGuessState(BaseState):
"""An intermediate state."""
def process(self, letter, context):
context.lives -= 1
context.message = f"Incorrect guess! You've lost a life. {context.lives} lives remaining"
context.guessed_letters.append(letter)
if context.lost():
context.state = DeadState()
else:
context.state = HoldingState()
class DeadState(BaseState):
"""A final state representing a lost game."""
def process(self, letter, context):
pass
class WonState(BaseState):
"""A final state representing a game won."""
def process(self, letter, context):
pass
if __name__ == '__main__':
game = Context('represents')
game.startGame()
这通过了以下测试(pytest):
def test_start_to_correct():
game = Context('represents')
game.process('r')
assert game.state == HoldingState()
assert game.lives == 10
def test_start_to_incorrect():
game = Context('represents')
game.process('i')
assert game.state == HoldingState()
assert game.lives == 9
def test_repeated_guess():
game = Context('represents')
game.process('i')
game.process('i')
assert game.state == HoldingState()
assert game.lives == 9
def test_guesses():
game = Context('word', lives=4)
game.process('a')
assert game.lives == 3
def test_win():
game = Context('word', lives=4)
game.process('w')
game.process('o')
game.process('r')
game.process('d')
assert game.state == WonState()
def test_lost():
game = Context('wort', lives=4)
game.process('a')
assert game.lives == 3
game.process('b')
assert game.lives == 2
game.process('c')
assert game.lives == 1
game.process('d')
assert game.lives == 0
assert game.state == DeadState()