Python не может вызвать функцию - PullRequest
0 голосов
/ 02 декабря 2018

Я разрабатываю ножницы для бумаги из камня на питоне, и я застрял.Я сделал урок, который циклично (камень, бумага и ножницы), я хочу, чтобы компьютер знал, что это предыдущая игра.например (в первом раунде компьютер играл в рок, в следующем раунде он должен играть на бумаге)
, но я не знаю, как вызвать функцию обучения, чтобы она заработала

class Player:
def __init__(self):
    self.score = 0

def move(self):
    return 'rock'

def learn(self, my_move, their_move):
    self.my_move = my_move
    self.their_move = their_move

def beats(one, two):
return ((one == 'rock' and two == 'scissors') or
        (one == 'scissors' and two == 'paper') or
        (one == 'paper' and two == 'rock'))

class Game:
def __init__(self, p1, p2):
    self.p1 = p1
    self.p2 = p2

def play_round(self):
    move1 = input("Pick something!\n")
    move2 = self.p2.move()
    print(f"Player 1: {move1}  Player 2: {move2}")
    self.p1.learn(move1, move2)
    self.p2.learn(move2, move1)
    if beats(move1, move2):
        self.p1.score += 1
        print ("You win")
        print ("Human score = " + str(self.p1.score) + " "  + "Computer score = " + str(self.p2.score) ) 
    elif beats(move2,move1):
        self.p2.score += 1
        print ("Computer wins")
        print ("Human score = " + str(self.p1.score) + " "  + "Computer score = " + str(self.p2.score) ) 
    else:
        print ("Draw")
        print ("Human score = " + str(self.p1.score) + " "  + "Computer score = " + str(self.p2.score) )

def play_game(self):
    print("Game start!")
    for round in range(3):
        print(f"Round {round}:")
        self.play_round()
    print("Game over!")

class human_player(Player):
def move(self):
   return input("Pick something!\n")

class randomplayer(Player):
def move(self):
    return random.choice(moves)

class repeat(Player):
def move(self):
    return 'rock'

class cycleplayer(Player):
def move(self):
    # calling my_move from the Player class
    if self.learn.my_move == "rock" or "paper" or "scissors" :
        return 'rock'

    elif  self.their_move == 'rock':
        return "paper"   

    elif self.their_move == 'paper':
        return "scissors"  

    elif self.their_move == 'scissors':
        return "rock"

if HumanPlayer_choice == "cycle" :
game = Game(Player(), cycleplayer())
game.play_game()

Это ошибкаЯ получаю.

Возникло исключение: у объекта 'function' AttributeError нет атрибута 'my_move'

Я знаю, что мне нужно использовать функцию init с функцией learnфункция, чтобы заставить это работать, но я не уверен, как.

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Насколько я мог судить, в вашем коде было несколько проблем.Посмотрите на приведенный ниже пример на основе вашего кода.Есть некоторая логика, которой я не мог следовать, поэтому она может вести себя не так, как вы хотите.Предложения:

  • , поскольку вы просто хотите сохранить предыдущее движение для цикла cycle_player, сохраните его в объекте (экземпляре) цикла, а не в Player
  • , так как метод перемещения изменяется,это реализация, специфичная для дочернего класса (например, human_player, random_player, cycle_player)
  • некоторые методы лучше статичны, чем воссозданы в каждом экземпляре методов

    import random
    
    class Player:
        def __init__(self):
            self.score = 0
    
    class Game:
        def __init__(self, p1, p2):
            self.p1 = p1
            self.p2 = p2
    
        @staticmethod
        def check_result(a, b): #Return win, draw, loose for a over b
            if (a == b):
                return 'draw'
            if (a == 'rock' and b == 'scissors') or (a == 'scissors' and b == 'paper') or (a == 'paper' and b == 'rock'):
                return 'win'
            return 'loose'
    
        def play_round(self):
            #move1 = input("Pick something!\n")
            move1 = self.p1.move()
            move2 = self.p2.move()
            print(f"Player 1: {move1}  Player 2: {move2}")
            result = Game.check_result(move1, move2) # a over b
            if result == 'win':
                self.p1.score += 1
                print ("You win")
            elif result == 'loose':
                self.p2.score += 1
                print ("Computer wins")
            else:
                print ("Draw")
            print ("Human score = " + str(self.p1.score) + " "  + "Computer score = " + str(self.p2.score))
    
        def play_game(self):
            print("Game start!")
            for round in range(3):
                print(f"Round {round + 1}:")
                self.play_round()
            print("Game over!")
    
    class human_player(Player):
        def move(self):
            return input("Pick something!\n") #TODO validate input
    
    class random_player(Player): #Option in game for computer to make random moves
        def move(self):
            return random.choice(["scissors","paper","rock"])
    
    class repeat_player(Player): #Option
        def move(self):
            return 'rock'
    
    class cycle_player(Player):
        def __init__(self):
            self.previous_move = None
            super().__init__()
    
        def move(self):
            # calling my_move from the Player class
            if self.previous_move is None :
                next_move = 'rock'
            elif  self.previous_move == 'rock':
                next_move = "paper"
            elif self.previous_move == 'paper':
                next_move = "scissors"  
            elif self.previous_move == 'scissors':
                next_move = "rock"
            self.previous_move = next_move
            return next_move
    
    #game = Game(human_player(), random_player())
    #game = Game(human_player(), repeat_player())
    game = Game(human_player(), cycle_player())
    game.play_game()
    
0 голосов
/ 02 декабря 2018

Проблема в этой строке:

if self.learn.my_move == "rock" or "paper" or "scissors" :

learn функция не имеет атрибута с именем my_move.То, что вы хотели сделать, это, вероятно,

if self.my_move == "rock" or self.my_move == "paper" or self.my_move == "scissors" :

Обратите внимание, что вам нужно добавить self.my_move == перед "paper" и "scissors";в противном случае он оценивается следующим образом:

if (self.my_move == "rock") or ("paper") or ("scissors"):

, и поскольку непустые строки всегда оцениваются как True, этот случай if становится бесполезным.


Как @DmitryErohinупомянуто, есть лучший способ достичь этого без повторения:

if (self.my_move in ("rock", "paper", "scissors")):

Это гораздо менее многословно и намного более читабельно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...