首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >希望简化我的第一个python,纸张,剪刀项目

希望简化我的第一个python,纸张,剪刀项目
EN

Code Review用户
提问于 2020-05-05 20:59:39
回答 2查看 107关注 0票数 0

最近(昨天),我开始使用python,我的目标是不使用任何教程等,因为我必须按照这些教程来完成一个小项目。我的第一个项目是我推荐做的是一个简单的游戏,岩石,纸,剪刀。我用了大约三十分钟就做好了,而且很好。每个游戏都能得到3分,这非常简单,但是现在既然我已经完成了,我希望能找到一种方法来简化代码,如果有其他方法的话。我真的把它伸出来了,因为我在没有帮助的情况下使用基本的东西。

代码语言:javascript
复制
# Rock Papers Scissors
import random

option = ["Rock", "Paper", "Scissor"]
game = True


def start_game():
    point_player = 0
    point_ai = 0
    game_end = True
    while game:
        rock = False
        paper = False
        scissor = False
        if point_player == 3:
            game_end = False
        elif point_ai == 3:
            game_end = False
        if game_end:
            print("Choose an option. (R,P,S)")
            selection = input()
            if selection == 'R':
                selection = 'Rock'
                rock = True
            elif selection == 'P':
                selection = 'Paper'
                paper = True
            elif selection == 'S':
                selection = 'Scissor'
                scissor = True
            else:
                print("That's not an option")
                exit()
            print("=======================")
            print("You chose " + selection)
            ai_response = random.choice(option)
            print("The A.I chose " + ai_response)
            print("=======================")
            if ai_response == "Rock":
                while rock:
                    print("Oh! That's a tie no points.")
                    break
                while scissor:
                    print("Oh, you lost :( +1 to A.I")
                    point_ai = point_ai + 1
                    break
                while paper:
                    print("Looks like you beat the A.I! +1 Point")
                    point_player = point_player + 1
                    break
            elif ai_response == "Paper":
                while rock:
                    print("Oh, you lost :( +1 to A.I")
                    point_ai = point_ai + 1
                    break
                while scissor:
                    print("Looks like you beat the A.I! +1 Point")
                    point_player = point_player + 1
                    break
                while paper:
                    print("Oh! That's a tie no points.")
                    break
            elif ai_response == "Scissor":
                while rock:
                    print("Looks like you beat the A.I! +1 Point")
                    point_player = point_player + 1
                    break
                while scissor:
                    print("Oh! That's a tie no points.")
                    break
                while paper:
                    print("Oh, you lost :( +1 to A.I")
                    point_ai = point_ai + 1
                    break
            print("You have " + str(point_player) + " points")
            print("The A.I has " + str(point_ai) + " points.")
            print("=======================")
        else:
            if point_ai > point_player:
                print("The A.I won! RIP U")
            else:
                print("Dang! You won this time.")
            exit()


print("|=========================|")
print("|    Rock Paper Scissor   |")
print("|       (R) (P) (S)       |")
print("|=========================|")
print("Would you like to start? y/n")
answer = input()
if answer == "y":
    print("Welcome to the game of Rock Paper Scissors")
    start_game()
elif answer == "n":
    print('Well ok then.. Fine leave')
    exit()
else:
    print("That's not an option.")
EN

回答 2

Code Review用户

回答已采纳

发布于 2020-05-05 21:14:03

代码语言:javascript
复制
game_end = True
while game:        
    if point_player == 3:
        game_end = False
    elif point_ai == 3:
        game_end = False
    if game_end:

        ...


    else:
        if point_ai > point_player:
            print("The A.I won! RIP U")
        else:
            print("Dang! You won this time.")
        exit()

可简化为:

代码语言:javascript
复制
while True:        
    if point_player == 3 or point_ai == 3:
        break

        ...

if point_ai > point_player:
    print("The A.I won! RIP U")
else:
    print("Dang! You won this time.")

所有的

代码语言:javascript
复制
while rock:
    print("Oh! That's a tie no points.")
    break

可以写成:

代码语言:javascript
复制
if rock:
    print("Oh! That's a tie no points.")

而不是point_ai = point_ai + 1,您可以将其缩短为point_ai += 1。我还将分离出决定谁获胜的代码,因为这会使我们更容易理解逻辑中发生的事情。

代码语言:javascript
复制
    winner = 'tie' # should be either 'player', 'tie', or 'ai'
    if ai_response == "Rock":
        if scissor: 
            winner = 'ai'
        if paper: 
            winner = 'player'
    elif ai_response == "Paper":
        if rock: 
            winner = 'ai'
        if scissor: 
            winner = 'player'
    elif ai_response == "Scissor":
        if rock: 
            winner = 'player'
        if paper: 
            winner = 'ai'

    if winner == 'tie':
        print("Oh! That's a tie no points.")
    if winner == 'player':
        print("Looks like you beat the A.I! +1 Point")
        player_points += 1
    if winner == 'ai':
        print("Oh, you lost :( +1 to A.I")
        ai_points += 1

rockpaperscissors Booleans代表玩家所做的选择,然后为ai所做的选择设置一个字符串,感觉很奇怪。对于这两种情况,我都会使用相同的数据类型。如果我们坚持对两个变量都使用字符串,并且对一些变量名进行了一些更改,那么我们可以得到:

代码语言:javascript
复制
while True:
    if player_points == 3 or ai_points == 3:
        break
    print("Choose an option. (R,P,S)")
    player_choice = input()
    if player_choice == 'R':
        player_choice = 'Rock'
    elif player_choice == 'P':
        player_choice = 'Paper'
    elif player_choice == 'S':
        player_choice = 'Scissor'
    else:
        print("That's not an option")
        exit()
    print("=======================")
    print("You chose " + player_choice)
    ai_choice = random.choice(option)
    print("The A.I chose " + ai_choice)
    print("=======================")

    winner = 'tie' # should be either 'player', 'tie', or 'ai'
    if ai_choice == "Rock":
        if player_choice == 'Scissor': 
            winner = 'ai'
        if player_choice == 'Paper': 
            winner = 'player'
    elif ai_choice == "Paper":
        if player_choice == 'Rock': 
            winner = 'ai'
        if player_choice == 'Scissor':
            winner = 'player'
    elif ai_choice == "Scissor":
        if player_choice == 'Rock': 
            winner = 'player'
        if player_choice == 'Paper': 
            winner = 'ai'

    if winner == 'tie':
        print("Oh! That's a tie no points.")
    if winner == 'player':
        print("Looks like you beat the A.I! +1 Point")
        player_points += 1
    if winner == 'ai':
        print("Oh, you lost :( +1 to A.I")
        ai_points += 1
            
    print("You have " + str(player_points) + " points")
    print("The A.I has " + str(ai_points) + " points.")
    print("=======================")

在某些方面,这看起来更糟,主要是因为变量名较长,但很快一切都会好转。我想现在是时候把这个游戏分解成多个功能了。我喜欢把我所有的打印语句与逻辑分开。在本例中,我将把所有的print语句保存在start_game函数中,并将所有的逻辑放在start_game函数之外。这有助于我们轻松地阅读和理解正在发生的事情,然后如果我们遇到了问题,我们可以研究其逻辑产生不正确结果的特定功能。这也使得单元测试逻辑变得更容易。

代码语言:javascript
复制
def get_players_choice():
    print("Choose an option. (R,P,S)")
    player_choice = input()
    if player_choice == 'R':
        player_choice = 'Rock'
    elif player_choice == 'P':
        player_choice = 'Paper'
    elif player_choice == 'S':
        player_choice = 'Scissor'
    else:
        player_choice = False

    return player_choice

def get_ai_choice():
    return random.choice(option)

def calculate_winner(player_choice, ai_choice):
    ''' returns either 'player', 'tie', or 'ai' '''
    winner = 'tie'
    if ai_choice == "Rock":
        if player_choice == 'Scissor': 
            winner = 'ai'
        if player_choice == 'Paper': 
            winner = 'player'
    elif ai_choice == "Paper":
        if player_choice == 'Rock': 
            winner = 'ai'
        if player_choice == 'Scissor':
            winner = 'player'
    elif ai_choice == "Scissor":
        if player_choice == 'Rock': 
            winner = 'player'
        if player_choice == 'Paper': 
            winner = 'ai'
    return winner

def display_results(winner):
    if winner == 'tie':
        print("Oh! That's a tie no points.")
    elif winner == 'player':
        print("Looks like you beat the A.I! +1 Point")
    elif winner == 'ai':
        print("Oh, you lost :( +1 to A.I")
            
    print("You have " + str(player_points) + " points")
    print("The A.I has " + str(ai_points) + " points.")
    print("=======================")

def start_game():
    player_points = 0
    ai_points = 0
    while True:
        if player_points == 3 or ai_points == 3:
            break

        player_choice = get_players_choice()
        if player_choice is False:
            print("That's not an option")
            exit()
        
        print("=======================")
        print("You chose " + player_choice)
        ai_choice = get_ai_choice()
        print("The A.I chose " + ai_choice)
        print("=======================")

        winner = calculate_winner(player_choice, ai_choice)

        if winner == 'player':
            player_points += 1
        elif winner == 'ai':
            ai_points += 1
            
        display_results(winner)

    if ai_points > player_points:
        print("The A.I won! RIP U")
    else:
        print("Dang! You won this time.")

现在我们重构的时候有了一点改进。这有点像国际象棋,你做的越多,你就会跳出更多的模式。让我们从get_players_choice函数开始。一种模式是,当要求用户输入,而不是要求'R','P','S',我们可以抓住第一个字符,小写它,然后检查。然后我们将接受“r”、“R”、“Rock”、“Rock”或任何以字母“r”开头的内容。其他一些事情:

代码语言:javascript
复制
    print("Choose an option. (R,P,S)")
    player_choice = input()

是相同的

代码语言:javascript
复制
player_choice = input("Choose an option. (R,P,S)")

虽然我说过我喜欢将打印语句和逻辑分开,但display_results显然是一个函数,它完全是关于在屏幕上显示文本的,同样地,人们期望一个名为get_players_choice的函数所做的不仅仅是逻辑。我们将使用输入函数,这需要向用户询问输入,并且需要告诉他们输入是否无效。无论如何,这是我修改过的get_players_choice函数。

代码语言:javascript
复制
def get_players_choice():
    while True:
        player_choice = input("Choose an option (R,P,S), or push enter to exit")

        if not player_choice: # If they pushed enter
            return False

        first_char = player_choice[0].lower()

        if first_char == 'r':
            return 'Rock'
        elif first_char == 'p':
            return 'Paper'
        elif first_char == 's':
            return 'Scissor'

        print("That's not an option")

display_choices和display_results实际上可以结合在一起。我们的最终结果就是这个。还有一些额外的改进可以做,但这些是重要的是你的目标是什么。代码可以很容易地扩展是很重要的吗?表演很重要吗?你喜欢面向对象的设计吗?等。

代码语言:javascript
复制
''' A Rock Papers Scissors game '''
import random

def get_players_choice():
    while True:
        player_choice = input("Choose an option (R,P,S), or push enter to exit: ")

        if not player_choice: # If they pushed enter
            return False

        first_char = player_choice[0].lower()

        if first_char == 'r':
            return 'Rock'
        if first_char == 'p':
            return 'Paper'
        if first_char == 's':
            return 'Scissor'

        print("That's not an option")


def get_ais_choice():
    return random.choice(["Rock", "Paper", "Scissor"])

def calculate_winner(player, ai):
    ''' Takes either 'Rock', 'Paper', or 'Scissors', for both the player and the ai.
        returns either 'player', 'tie', or 'ai' '''

    if ai == "Rock":
        if player == 'Scissor': return 'ai'
        if player == 'Paper':   return 'player'

    elif ai == "Paper":
        if player == 'Rock':    return 'ai'
        if player == 'Scissor': return 'player'

    elif ai == "Scissor":
        if player == 'Rock':   return 'player'
        if player == 'Paper':  return 'ai'

    return 'tie'

def display_round_outcome(player_choice, ai_choice, winner, player_points, ai_points):
    print("=======================")
    print("You chose " + player_choice)
    print("The A.I chose " + ai_choice)
    print("=======================")

    if winner == 'tie':
        print("Oh! That's a tie no points.")
    elif winner == 'player':
        print("Looks like you beat the A.I! +1 Point")
    elif winner == 'ai':
        print("Oh, you lost :( +1 to A.I")

    print(f"You have {player_points} points")
    print(f"The A.I has {ai_points} points.")
    print("=======================")


def start_game():
    player_points = 0
    ai_points = 0

    while True:
        if player_points >= 3 or ai_points >= 3:
            break

        player_choice = get_players_choice()
        ai_choice = get_ais_choice()

        if player_choice is False:
            break

        winner = calculate_winner(player_choice, ai_choice)

        if winner == 'player':
            player_points += 1
        elif winner == 'ai':
            ai_points += 1

        display_round_outcome(player_choice, ai_choice, winner, player_points, ai_points)

    if ai_points > player_points:
        print("The A.I won! RIP U")
    elif ai_points == player_points:
        print("It's a tie.")
    else:
        print("Dang! You won this time.")


print("|=========================|")
print("|    Rock Paper Scissor   |")
print("|       (R) (P) (S)       |")
print("|=========================|")
print("Would you like to start? y/n")
answer = input()
if answer == "y":
    print("Welcome to the game of Rock Paper Scissors")
    start_game()
elif answer == "n":
    print('Well ok then.. Fine leave')
else:
    print("That's not an option.")

让我知道你有什么问题,我写什么写得很快,没有很好地解释我的决定。但是,我希望这种方式有助于了解如何重构这段代码,并希望您能够看到,当您拥有所有的代码片段时,阅读和调试最终版本是多么的容易。当您很久以前编写的复杂代码,或者是其他东西编写的代码,并且您试图找出正在发生的事情时,两者之间的区别要明显得多。

编辑:

我弟弟对于如何重构这段代码得出了一个非常相似的结论,但他找到了一种更短的方法来检查谁是赢家。这是他的calculate_winner函数。

代码语言:javascript
复制
what_beats_what = {
  'Paper': 'Rock',
  'Scissors': 'Paper',
  'Rock': 'Scissors',
}

def get_winner(user_weapon, ai_weapon):
    if what_beats_what[user_weapon] == ai_weapon:
        return 'USER'
    elif what_beats_what[ai_weapon] == user_weapon:
        return 'AI'
    else:
        return 'TIE'

而且,这场比赛不可能以平局结束,因为谁先拿到3分,谁就永远是赢家。

票数 1
EN

Code Review用户

发布于 2020-05-05 21:05:36

这个主题称为重构。我可以把你链接到我最喜欢的一本关于这个主题的书和网站上,但我会留下一些一般性的建议。

一个好的开始是将你的程序分解成更小的功能块。确保它们的名字很好,并且很容易理解,换句话说,想象一下您是一个从未见过这段代码并不得不修复它的问题的人。

如果一个文件变得太大,您可能需要将其分解为几个文件,每个文件都有自己的子功能。

在Python编程语言中和以后,有许多关于这个主题的很好的站点和讲座。我鼓励您在分解了第一批建议并与同行共享这些代码并收到来自他们的反馈后,来研究它们。看看你的理解,并要求澄清你不了解的部分。保持开放的心态,并知道这其中有很大一部分是主观的。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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