首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >面向过程和面向对象的剪刀

面向过程和面向对象的剪刀
EN

Code Review用户
提问于 2014-09-08 15:27:16
回答 2查看 2K关注 0票数 4

我很适应程序风格,学习面向对象,所以我做了一个小石头剪刀游戏在这两种风格。

这个脚本在程序风格中,这个脚本在面向对象风格中。我正确地实现了这个小游戏面向对象的智慧吗?如果不是,我在哪里搞砸的?我怎样才能改进它们?

这是程序风格的代码:

代码语言:javascript
复制
import random, sys

def computer_choice():
    computer_choice = random.choice("rps")
    return computer_choice

def user_choice():
    user_ch = raw_input(" Your Choice ?   ")
    if user_ch != "r" and user_ch != "p" and user_ch != "s":
        print " Wrong input, Please try again.\n"
        user_ch = user_choice()

    return user_ch

def compare_choices(user_choice, computer_choice):
   if user_choice == "r" and computer_choice == "p":
        return "computer"
   elif user_choice == "r" and computer_choice == "s":
       return "user"
   elif user_choice == "r" and computer_choice == "r":
       return "n" # n means nul
   elif user_choice == "p" and computer_choice == "r":
      return "user"
   elif user_choice == "p" and computer_choice == "s":
      return "computer"
   elif user_choice == "p" and computer_choice == "p":
      return "n"
   elif user_choice == "s" and computer_choice == "r":
      return "computer"
   elif user_choice == "s" and computer_choice == "p":
      return "user"
   elif user_choice == "s" and computer_choice == "s":
      return "n"

def play_again():
    print "Game Over"
    choice = raw_input(" Would you like to play again? (Y/N) ")
    if choice == "y" or choice == "Y":
        play()
    elif choice == "n" or choice == "N":
        sys.exit()
    else:
        print " Wrong input, Please try again.\n"
        play_again()

def play():
    global user_score, computer_score
    i = 1
    while i <= 3:
        user_c = user_choice()
        computer_c = computer_choice()
        result = compare_choices(user_c, computer_c)
        if result == "user":
            user_score += 1
            print " Your choice was " + user_c + ", the computer's choice was "+ computer_c
            print " You WON ! \n"
        elif result == "computer":
            computer_score += 1
            print " Your choice was " + user_c + ", the computer's choice was "+ computer_c
            print " The computer won. \n"
        else:
            print " Your choice was " + str(user_c) + ", the computer's choice was "+ str(computer_c)
            play_again()
        i += 1
    print "Your score was: "+str(user_score)+", The Computer's score was: "+str(computer_score)
    if user_score > computer_score:
        print "You are the WINNER, CONGRATULATIONS! \n\n"
    else:
        print "The Computer is the WINNER. \n\n"

play_again()

user_score = computer_score = 0
play()

这是面向对象风格的代码:

代码语言:javascript
复制
import random, sys

class Player:#two methods in comun between user player and computer player
    score = 0

    def update_score(self):
        self.score += 1

    def get_score(self):
        return self.score
class Computerp(Player): # The computer player class, it has in addition to the two  Player method, it's own choose method.

    def choose(self):
        computer_choice = random.choice("rps")
        return computer_choice

class Userp(Player): # Same as computer player class

    def choose(self):
        user_ch = raw_input(" Your Choice ?   ")
        if user_ch != "r" and user_ch != "p" and user_ch != "s":
            print " Wrong input, Please try again.\n"
            user_ch = self.choose()

        return user_ch

class Game: # This is a wrapper class for the "Game logic", it has: compare_choices method, play, and play_again methods.

    def compare_choices(self, computer_choice, user_choice):
        if user_choice == "r" and computer_choice == "p":
            return "computer"
        elif user_choice == "r" and computer_choice == "s":
            return "user"
        elif user_choice == "r" and computer_choice == "r":
            return "n" # n means nul
        elif user_choice == "p" and computer_choice == "r":
            return "user"
        elif user_choice == "p" and computer_choice == "s":
            return "computer"
        elif user_choice == "p" and computer_choice == "p":
            return "n"
        elif user_choice == "s" and computer_choice == "r":
            return "computer"
        elif user_choice == "s" and computer_choice == "p":
            return "user"
        elif user_choice == "s" and computer_choice == "s":
            return "n"

    def play(self):
        user = Userp()
        computer = Computerp()
        i = 1
        while i <= 3:
            user_ch = user.choose()
            computer_ch = computer.choose()
            result = self.compare_choices(computer_ch, user_ch)
            if result == 'user':
                user.update_score()
                print " Your choice was " + user_ch + ", the computer's choice was "+ computer_ch
                print " You WON ! \n"
            elif result == 'computer':
                computer.update_score()
                print " Your choice was " + user_ch + ", the computer's choice was "+ computer_ch
                print " The computer won. \n"
            else:
               print " Your choice was " + str(user_ch) + ", the computer's choice was "+ str(computer_ch)
               self.play_again()
            i = i + 1
        print "Your score was: "+str(user.get_score())+", The Computer's score was: "+str(computer.get_score())
        if user.get_score() > computer.get_score():
            print "You are the WINNER, CONGRATULATIONS! \n\n"
        else:
            print "The Computer is the WINNER. \n\n"
        self.play_again()
game = Game()

game.play()
EN

回答 2

Code Review用户

回答已采纳

发布于 2014-09-08 17:45:15

两个版本的

进口应以单独的方式进行:

代码语言:javascript
复制
import random
import sys

可以使用字典简化两个版本中的compare_choices代码--请注意,元组可以用作字典键,这些元组是可理解且不可变的:

代码语言:javascript
复制
def compare_choices(user_choice, computer_choice):
    result = {('r', 'p'): 'computer',
              ('r', 's'): 'user',
              ('r', 'r'): None, # None is a more conventional null
              ...}
   return result[user_choice, computer_choice]

在这两种情况下,您都应该“保护”运行在脚本顶层的代码:

代码语言:javascript
复制
if __name__ == "__main__":
    ...

这使得以后更容易将它们的功能import到其他脚本中。

使用字符串格式方法,而不是连接字符串:

代码语言:javascript
复制
" Your choice was {0}, the computer's choice was {1}".format(user_ch, computer_ch)

这是更易读的,也更有效率。

代码语言:javascript
复制
 i = 1
 while i <= 3:
     ...
     i += 1

将更加整洁,因为:

代码语言:javascript
复制
for i in range(1, 4):

或者,因为您从未实际使用i的值:

代码语言:javascript
复制
for _ in range(3):

OOP版本

新Python代码中的所有类实际上应该是“新样式”类,即从object继承(这是在3.x代码中自动完成的):

代码语言:javascript
复制
class Player(object):

注意,Player.score是当前代码中的类属性,而不是实例属性。这是一个常见的“抓到”--这里不是什么大问题,因为属性是不可变的,但是应该避免:

代码语言:javascript
复制
class Player(object):        
    def __init__(self):
        self.score = 0

您的Players也不需要使用"get“和"set”方法,只需直接访问score属性:

代码语言:javascript
复制
if user.score > computer.score:

如果有必要,以后可以轻松地将属性转换为@property

您可以发出信号,表示choose不是由父类实现的,而是应该由所有子类按照以下约定实现:

代码语言:javascript
复制
class Parent(object):

    def some_method(self, *args, **kwargs):
        """This method must be implemented by classes inheriting from Parent."""
        raise NotImplementedError

ComputerPlayerUserPlayer,或者仅仅是ComputerUser,将是您的子类的更好的名称-小写p后缀是笨拙和不必要的。

过程版

代码语言:javascript
复制
global user_score, computer_score

总是一个不好的符号--而不是全局符号,考虑显式地传递这两个分数,例如作为单独的变量或在单个字典{'user': 0, 'computer': 0}中。

过程版本的递归实现意味着一个非常长的游戏最终会达到递归的极限--尝试编写一个迭代版本。

票数 5
EN

Code Review用户

发布于 2014-09-09 15:40:40

user_choice()choice()中的一个小淘气

代码语言:javascript
复制
def choose(self):
    user_ch = raw_input(" Your Choice ?   ")
    if user_ch != "r" and user_ch != "p" and user_ch != "s":
        print " Wrong input, Please try again.\n"
        user_ch = self.choose()

    return user_ch

这个函数使用递归来计算一个永远不会正确的选择。这在您的程序中留下了一个漏洞,用户可以输入足够多的错误值,并由于达到递归限制而使程序崩溃。

制作该方法的一个更安全的方法是使用while循环。

代码语言:javascript
复制
def choose(self):
    user_ch = raw_input(" Your Choice ?   ")
    while user_ch != "r" and user_ch != "p" and user_ch != "s":
        print " Wrong input, Please try again.\n"
        user_ch = raw_input(" Your Choice ?   ")

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

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

复制
相关文章

相似问题

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