首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OOP Hangman游戏

OOP Hangman游戏
EN

Code Review用户
提问于 2021-08-11 07:19:59
回答 1查看 2.1K关注 0票数 15

我和我女儿正在努力自学Python和OOP。我们写了一个刽子手游戏,我们真的很想得到一些反馈。我们朝正确的方向前进了吗?我们如何改进它呢?任何让Python程序员感到“哎哟”的东西?有什么能让OOP专家畏缩的吗?我们遇到了各种各样的问题。例如,当只有一个实例时,我们应该实例化类吗?随时可以残忍!我们已经把它写在这里了:https://replit.com/@scripta/Hangman#main.py

根据ASM的建议,将调用功能更改为"Game“类。

非常感谢您花了大量时间和精力对代码进行评论。对于最初在这篇文章中更改代码表示歉意(见上面),下面是一个新帖子,其中包含了大多数建议:OOP Hangman游戏-修正代码

代码语言:javascript
复制
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()      
EN

回答 1

Code Review用户

发布于 2021-08-11 14:42:21

欢迎来到代码评审!

如果你刚开始学习,那似乎很不错。以下是一些没有具体顺序的评论:

编辑:在贴出答案后,我看到了大多数答案不过,我还是会把它留在这里,因为它可能有用。

  • 通常,在佩普-8上读一读。这是一个普遍的风格指南,广泛遵循的社会。例如,您没有使用一致的间距:
代码语言:javascript
复制
# No slace on the left of the assignment
progress_string= progress_string+" "+char+" "
# Space on the left
self.guesses_made = set()
  • 关于OOP设计,Gallows的设计很差。它被用作命名空间的王者,所有的方法都是类方法,它有类属性,但它也是实例。它应该是一个具有其属性和方法的类。
  • bools的使用:
代码语言:javascript
复制
if condition:
  return True
else:
  return False

可改为:

代码语言:javascript
复制
retun condition

例如,guessed方法在Guesses

  • Guesses#made方法可以简化如下:
代码语言:javascript
复制
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的东西。
  • wordguessesgallows应该是Game在初始化时创建的S属性。它们也可以在初始化时调用的initreset方法上创建。这将允许以更明确的方式重新启动游戏(目前您只需调用play两次)。
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/265940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档