我和我女儿正在努力自学Python和OOP。我们写了一个刽子手游戏,我们真的很想得到一些反馈。我们朝正确的方向前进了吗?我们如何改进它呢?任何让Python程序员感到“哎哟”的东西?有什么能让OOP专家畏缩的吗?我们遇到了各种各样的问题。例如,当只有一个实例时,我们应该实例化类吗?随时可以残忍!我们已经把它写在这里了:https://replit.com/@scripta/Hangman#main.py
根据ASM的建议,将调用功能更改为"Game“类。
非常感谢您花了大量时间和精力对代码进行评论。对于最初在这篇文章中更改代码表示歉意(见上面),下面是一个新帖子,其中包含了大多数建议:OOP Hangman游戏-修正代码
import random
class Word:
def __init__(self):
words = ("foxglove", "captain", "oxygen", "microwave", "rhubarb")
self._word = random.choice(words)
self.letters_in_word=set(self._word)
@property
def word(self):
return self._word
def progress(self, guesses):
# create string of underscores and guessed letters to show progress to guessing word
progress_string= ""
for char in self.word:
if guesses.guessed(char):
progress_string= progress_string+" "+char+" "
else:
progress_string= progress_string +" _ "
return(progress_string)
def guessed(self, guesses):
letters_guessed = self.letters_in_word.intersection(guesses.guesses_made)
if letters_guessed == self.letters_in_word:
return True
else:
return False
class Guesses:
def __init__(self):
# guesses holds all guesses made (wrong or right)
self.guesses_made = set()
def guessed(self,char):
if char in self.guesses_made:
return True
else:
return False
def record(self,guess,word):
# All valid guesses (wrong or right) are added to the guesses set
self.guesses_made.add(guess)
if not guess in word.letters_in_word:
Gallows.record_bad_guess()
def made(self):
# to sort the set of guesses made we need to cast it to a list
guesses_list= list(self.guesses_made)
guesses_list.sort()
guesses_string=""
#comma separate the guesses
for char in guesses_list:
guesses_string= guesses_string+char+","
return guesses_string
class Gallows:
_bad_guesses=0
gallows_images = (" \n \n \n \n \n__________",
" \n | \n | \n | \n | \n_|________",
" _____\n | \n | \n | \n | \n_|________",
" _____\n |/ \n | \n | \n | \n_|________",
" _____\n |/ |\n | \n | \n | \n_|________",
" _____\n |/ |\n | O \n | \n | \n_|________",
" _____\n |/ |\n | O \n | | \n | \n_|________",
" _____\n |/ |\n | O \n | /| \n | \n_|________",
" _____\n |/ |\n | O \n | /|\\ \n | \n_|________",
" _____\n |/ |\n | O \n | /|\\ \n | / \n_|________",
" _____\n |/ |\n | O \n | /|\\ \n | / \\\n_|________",)
@classmethod
def record_bad_guess(cls):
cls._bad_guesses +=1
@classmethod
def hanged(cls):
if cls._bad_guesses >= len(cls.gallows_images)-1:
return True
else:
return False
@classmethod
def draw(cls):
return cls.gallows_images[cls._bad_guesses]
class Game:
def get_letter(self, guesses):
while True:
char= input("\nPlease enter your guess: ")
if len(char)<1:
print ("You didn't choose a letter!")
elif len(char)!=1:
print ("One letter at a time!")
elif not char.isalpha():
print ("Alphabetic characters only!")
elif guesses.guessed (char):
print ("You already guessed that letter")
else:
break
return (char)
def display_progress(self, target, gallows, guesses):
print("\n",target.progress(guesses))
print(gallows.draw())
print("\nUsed: \n",guesses.made())
def play(self):
target= Word()
guesses= Guesses()
gallows= Gallows()
while True:
guess= self.get_letter(guesses)
guesses.record(guess,target)
self.display_progress(target, gallows, guesses)
if target.guessed(guesses):
print("\nYou win, well done")
break
if gallows.hanged():
print ("\nI win. The word was:",target.word)
break
if __name__ == "__main__":
game= Game()
game.play() 发布于 2021-08-11 14:42:21
欢迎来到代码评审!
如果你刚开始学习,那似乎很不错。以下是一些没有具体顺序的评论:
编辑:在贴出答案后,我看到了大多数答案不过,我还是会把它留在这里,因为它可能有用。
# No slace on the left of the assignment
progress_string= progress_string+" "+char+" "
# Space on the left
self.guesses_made = set()Gallows的设计很差。它被用作命名空间的王者,所有的方法都是类方法,它有类属性,但它也是实例。它应该是一个具有其属性和方法的类。if condition:
return True
else:
return False可改为:
retun condition例如,guessed方法在Guesses中
Guesses#made方法可以简化如下:sorted_guesses = list(self.guesses_made).sort()
return ",".joint(sorted_guesses)Guesses只是一个集合的包装器,所以它不应该是一个类,而应该是游戏对象中的一个属性。Guesses#made方法可以是Game方法。Guesses#record方法不应该依赖于Gallows (它没有真正的意义),所以它只是一个set#add。made不会告诉我任何事情,除非我把它读成Guesses#made。因此,它可能应该重命名为类似于made_guesses的东西。word、guesses和gallows应该是Game在初始化时创建的S属性。它们也可以在初始化时调用的init或reset方法上创建。这将允许以更明确的方式重新启动游戏(目前您只需调用play两次)。https://codereview.stackexchange.com/questions/265940
复制相似问题