首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >一种简单的石纸剪刀游戏

一种简单的石纸剪刀游戏
EN

Code Review用户
提问于 2019-11-06 13:46:38
回答 1查看 147关注 0票数 2

我刚刚完成了基础中级Python课程的学习,并想测试自己。这是我的基本岩石纸剪刀游戏。

代码语言:javascript
运行
复制
def play():
    import random

    player_score = 0
    ai_score = 0

    while True:
        try:
            user_choice = int(input("\nRock: 1"
                                    "\nPaper: 2"
                                    "\nScissor: 3"
                                    "\nWrite the number of the object you choose: "))
        except NameError:
            print("You can only enter number.")
            continue
        except ValueError:
            print("You can only enter number.")
            continue

        if user_choice not in range(1, 4):
            print("Invalid number, you have to write numbers between 1-3")
            continue

        rps = {1: "Rock", 2: "Paper", 3: "Scissor"}
        ai_choice = random.randint(1, 3)

        print(f"\nPlayer's choice: {rps[user_choice]} | AI's choice: {rps[ai_choice]}")

        if user_choice == ai_choice:
            print("Draw!")
        elif user_choice == 1:
            if ai_choice == 2:
                print("AI's paper wrapped Player's rock, AI won this round!")
                ai_score += 1
            elif ai_choice == 3:
                print("Player's rock crushed AI's scissor, Player won this round!")
                player_score += 1
        elif user_choice == 2:
            if ai_choice == 1:
                print("Players's paper wrapped AI's rock, Player won this round!")
                player_score += 1
            elif ai_choice == 3:
                print("AI's scissor cut Player's paper, AI won this round!")
                ai_score += 1
        elif user_choice == 3:
            if ai_choice == 1:
                print("AI's rock crushed Player's scissor, AI won this round!")
                ai_score += 1
            elif ai_choice == 2:
                print("Player's scissor cut AI's paper, Player won this round!")
                player_score += 1

        print(f"\nPlayer's score: {player_score} | AI's score: {ai_score}"
              f"\nGame ends when player or AI's score reach 3!")

        if player_score == 3:
            print("Game over, Player won!")
            quit()
        elif ai_score == 3:
            print("Game over, AI won!")
            proceed = input("Wanna try again and show the AI your unmatched and great wisdom?"
                            "\nWrite Y or N >: ").lower()
            if proceed == "y":
                play()
            elif proceed == "n":
                quit()
            else:
                print("Invalid command, exiting program...")
                quit()


if __name__ == "__main__":
    play()

那么,你怎么看?我怎样才能做得更好,我的错误是什么?

EN

回答 1

Code Review用户

发布于 2019-11-06 16:17:04

我想说,在您的代码中有两个主要问题。

第一个是主循环,它非常不清楚,很多if语句都是用continuequit()填充的,这是spagetthi代码,它使您的代码更难读,所以很难调试,因为这会跳到任何地方。

第二个问题是缺乏面向对象程序设计( OOP ),这可以很好地适应这种情况。游戏通常使用强大的面向对象语言(Unreal使用C++,Unreal使用C#等),因为组件之间有很强的交互,并且非常有利于抽象和模块化。公平地说,这并不是真正需要的短期游戏,如岩石剪刀,但它阻止你进一步扩大游戏规模。

我建议您进行很少的设计改进:

将代码拆分为函数,第一种可能是游戏循环中应该使用的游戏获胜条件,以避免不必要的无限循环,这与常量条件(如while True: )相同。将此语句替换为while has_game_ended():,改为has_game_ended,如下所示:

代码语言:javascript
运行
复制
    def has_game_ended(player_score: int, ia_score: int) -> bool:
        if player_score == 3 or ia_score == 3:
            print("Game over: {} won!".format("player" if player_score == 3 else "AI"))
            return True
        return False

然后使用一个枚举来列出您的移动以使它们更易于在代码中重用(论文比1更有意义),并使用操作符重载启用比较,请注意,这是一个特定于游戏规则的棘手的比较。

代码语言:javascript
运行
复制
from enum import Enum

class Move(Enum):
    PAPER = 1
    ROCK = 2
    SCISSORS = 3

    def __lt__(self, other):
        return (self is Move.ROCK and other is Move.PAPER) or (self is Move.Paper and other is Move.SCISSORS) or (self is Move.SCISSORS and other is Move.ROCK)

现在你可以写:

代码语言:javascript
运行
复制
>>> player_choice = Move.PAPER
>>> ia_choice = Move.ROCK
>>> player_choice < ia_choice
True

就像

代码语言:javascript
运行
复制
player_score = player_score + int(player_choice > ia_choice)
ia_score = ia_score + int(ia_choice > player_choice)

这很好,因为它不再比较两个整数,而是比较两个Move,这与操作符重载有很大的不同。

避免脚本中的quit(),它完全减少了代码流,并且不允许很好的错误处理,相反,它更倾向于循环条件,或者尝试为意外行为定制异常的you语句(例如,当您使用无效命令时,如下面的示例所示)。

代码语言:javascript
运行
复制
def WrongCommand(Exception):
    pass

if __name__ == "__main__":
    try:
        play()
    except WrongCommand:
        print("Invalid command, exiting program...")
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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