首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >陈词滥调,纸制,剪刀,作为第一个Python程序

陈词滥调,纸制,剪刀,作为第一个Python程序
EN

Code Review用户
提问于 2021-11-03 02:33:21
回答 1查看 86关注 0票数 3

我已经有一段时间没有做过任何类型的编程了,这也是我第一次用Python编程。我只是在寻找任何一般性的反馈和提示,因为这是我的第一个计划。

代码语言:javascript
复制
# rock, paper, scissors game

import random
playerWin = 0
aiWin = 0
guess = 0
print('You are playing rock, paper, scissors. If you would like to quit, type "4"')

while int(guess) != 4:
    choices = ['', 'rock', 'paper', 'scissors']
    aiGuess = random.randint(1, 3)

    # data validation
    while True:
        guess = input('Enter "1" for rock, "2" for paper, or "3" for scissors. "4" to quit: ')
        if str(guess) in ('1', '2', '3', '4'):
            break
        else:
            print('ERROR: NOT AN OPTION. TRY AGAIN.\n')

    # check player guess vs AI guess
    if int(guess) == aiGuess:  # Tie game
        print('Tie game. The AI chose ' + choices[aiGuess] + '.')
    elif (int(guess) == 1 and aiGuess == 3) or (int(guess) == 2 and aiGuess == 1) or (
            int(guess) == 3 and aiGuess == 2):  # player wins
        print('You win! The AI chose ' + choices[aiGuess] + '.')
        playerWin += 1
    elif int(guess) == 4:  # quit break
        break
    else:  # AI wins
        print('You lost. The AI chose ' + choices[aiGuess] + '.')
        aiWin += 1

    print('SCORE: You have ' + str(playerWin) + ' points and the AI has ' + str(aiWin) + ' points.\n')

# final score print
print('\n################################################################')
print('FINAL SCORE: You ended with ' + str(playerWin) + ' points and the AI had ' + str(aiWin) + ' points.')
print('################################################################')
EN

回答 1

Code Review用户

发布于 2021-11-03 18:02:37

首先,干得好!程序看起来很坚固,界面很好,你可以处理不好的输入。

我有几个改进的建议:

UI/UX

  • 输入的"1" "2" "3" "4"方法很好,因为键彼此靠近,但是"r" "p" "s""q"可能更有语义意义。您可以对输入进行概括,以允许"r"或像"rock"这样的完整单词更加灵活。
  • 过了一段时间,Enter "1" for rock, "2" for paper, or "3" for scissors. "4" to quit:变得有些冗长和分散注意力,所以您可能需要在几轮之后将其缩写,或者使用一个特殊的"help"命令来进行说明。可能只在收到错误输入后才显示提醒。
  • ERROR: NOT AN OPTION. TRY AGAIN.是光栅由于帽子。当我陷入困境时,我更喜欢我的应用程序对我温柔,特别是当我正在享受一个放松的RPS游戏的时候。
  • 发送一个Ctrl+C来杀死这个应用程序会引发一个KeyboardError。你可以抓住这个,显示最后的分数,然后干净地退出。
  • “又玩了?”提示,设定一个目标得分,或者允许两个人一起玩会很好。

次要问题

  • 佩普-8中,始终使用snake_case,而不是camelCase
  • 在导入后添加一两行垂直空格。查看黑色,它将很好地格式化您的代码。
  • int(guess)发生6次,眼睛都很硬。如果你甚至需要转换(你可以在整个过程中使用字符串),我宁愿先做一次。
  • "AI":“”,“石头”,“纸”,“剪刀” aiGuess = random.randint(1,3)的代码可以是:random.randint= “石头”,“纸”,“剪刀” ai_guess = random.randint(0,len(选择)),或者更好的代码: ai_guess =random.choice(“石头”,“纸”,“剪刀”))
  • if str(guess) in ('1', '2', '3', '4'):中,str()强制转换是多余的,因为input()总是返回字符串。最好将有效的选择从这个硬编码的元组中移到脚本的顶部。
  • 使用f-字符串而不是+:print('SCORE:您有‘+ str(playerWin) +’分,而AI有‘+ str(aiWin) +’分。\n‘)变成了打印(f’SCORE:您有{playerWin}点,AI有{aiWin}分。\n‘)
  • \n################################################################'可能是"\n" + "#" * 64

设计

如果您的目标是使代码尽可能直接地工作,那么在全局范围内将所有内容放入一个函数都可以。但是对于较大的应用程序,您需要考虑更多的设计,以确保它是可维护和可扩展的。例如,您可能需要添加蜥蜴和史波克、图形用户界面、网络上的多人游戏或其他特性。

一个更易于维护的设计是将用户交互和游戏逻辑分开,并在适当的情况下进行概括。使用函数是实现这一目标的好方法。您的代码有注释分隔部分,如# data validation# check player guess vs AI guess# final score print。这些都是很好的功能选择;这里的评论是一个支柱。

此外,代码具有较高的圈复杂度 (嵌套和宽分支和循环)。有些情况很长,很难理解:

代码语言:javascript
复制
elif (int(guess) == 1 and aiGuess == 3) or (int(guess) == 2 and aiGuess == 1) or (
        int(guess) == 3 and aiGuess == 2):  # player wins
    ...

这将是另一个很好的重构机会;从客户端的角度来看,一个函数可以在很大程度上帮助实现类似于if player_wins(player_guess, ai_guess): ...的目标。

字典是对实体之间的映射进行编码的好方法。例如,在RPS中,每个项目之间都有关系。通过创建"X击败Y“关系的字典,我们可以避免列举所有选项的可能性,并立即进行查找,以确定一项是否优于另一项。

由于RPS游戏是有状态的,控制流在UI和游戏引擎之间来回传递,所以一两个类可能是一个合理的设计决策。

建议重写

代码语言:javascript
复制
import random


class RockPaperScissorsGame:
    PLAYER = 0
    COMPUTER = 1

    def __init__(self, objects):
        if len(objects) < 3:
            raise ArgumentError("There must be at least 3 objects")

        self._objects = objects
        self._player_score = 0
        self._computer_score = 0

    @property
    def objects(self):
        return dict(self._objects)

    @property
    def player_score(self):
        return self._player_score

    @property
    def computer_score(self):
        return self._computer_score

    def validate_choice(self, choice):
        return choice in self._objects

    def handle_round(self, player_choice, computer_choice):
        if self._objects[player_choice] == computer_choice:
            self._player_score += 1
            return self.PLAYER
        elif self._objects[computer_choice] == player_choice:
            self._computer_score += 1
            return self.COMPUTER


class RockPaperScissorsUI:
    def __init__(self, objects):
        self.objects = objects
        self.abbrevations = {x[0]: x for x in objects}

    def play_one_game(self):
        self.game = game = RockPaperScissorsGame(self.objects)
        print(f'You are playing {", ".join(self.objects)}.\n'
               'If you would like to quit, type "quit"\n')
        
        while self.play_one_round():
            print(f"You have {game.player_score} points and "
                  f"the AI has {game.computer_score} points.\n")

        print(f"\n{'#' * 64}\nYou ended with {game.player_score} points and "
              f"the AI had {game.computer_score} points.\n{'#' * 64}")

    def play_one_round(self):
        while True:
            prompt = f'Choose {", ".join(self.objects)}: '
            user_input = input(prompt).lower()
            user_input = self.abbrevations.get(user_input, user_input)

            if user_input in ("q", "quit", "exit"):
                return False
            elif self.game.validate_choice(user_input):
                self.make_move(user_input)
                return True
            else:
                print(f"Error: '{user_input}' is not an option. Try again.\n")

    def make_move(self, user_input):
        computer_choice = random.choice(list(self.objects))
        result = self.game.handle_round(user_input, computer_choice)
        result_message = {
            self.game.PLAYER: "You win!", 
            self.game.COMPUTER: "You lost!"
        }.get(result, "Tie game.")
        print(f"{result_message} The computer chose {computer_choice}.")


if __name__ == "__main__":
    objects = {
        "rock": "scissors",
        "paper": "rock",
        "scissors": "paper",
    }
    game = RockPaperScissorsUI(objects)
    game.play_one_game()

样本运行:

代码语言:javascript
复制
You are playing rock, paper, scissors.
If you would like to quit, type "quit"

Choose rock, paper, scissors: Rock
You lost! The AI chose paper.
You have 0 points and the AI has 1 points.

Choose rock, paper, scissors: rock
You lost! The AI chose paper.
You have 0 points and the AI has 2 points.

Choose rock, paper, scissors: p
You lost! The AI chose scissors.
You have 0 points and the AI has 3 points.

Choose rock, paper, scissors: asdasd
Error: 'asdasd' is not an option. Try again.

Choose rock, paper, scissors: q

################################################################
You ended with 0 points and the AI had 3 points.
################################################################
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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