Python How to access class function variable - python

This was a Rock scissors paper game code ,its a humanplayer versus a reflectplayer. Reflectplayer who copy the last time humanplayer move and show the move. I tried to access the move2 from the play_round to ReflectPlayer . But How? Isn't game1.play_round.move2 work?
import random
moves = ['rock', 'paper', 'scissors']
class Player:
def move(self):
return 'rock'
def learn(self, my_move, their_move):
pass
class RandomPlayer:
def move(self):
all = ["rock","scissors","paper"]
ranint = random.randint(0,2)
return all[ranint]
def learn(self, my_move, their_move):
pass
class HumanPlayer:
def move(self):
ans = input("Rock Paper or Scissors?").lower()
return ans
def learn(self,my_move,their_move):
pass
class ReflectPlayer:
def move(self):
i = 1
RSP = ["rock","paper","scissors"]
print(self.move2)
if i == 1:
i += 1
return RSP[random.randint(0,2)]
elif game1.play_round.move2 == RSP[0]:
return RSP[0]
elif game1.play_round.move2 == RSP[1]:
return RSP[1]
elif game1.play_round.move2 == RSP[2]:
return RSP[2]
else:
print("Wrong input !")
pass
def learn(self,my_move,their_move):
pass
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 = self.p1.move()
move2 = self.p2.move()
print(f"Player 1: {move1} Player 2: {move2}")
if beats(move1 , move2) == True:
print(f"This Round : Player 1 WIN")
elif beats(move2 , move1) == True:
print(f"This Round : Player 2 WIN")
elif move1 == move2:
print("This Round : TIE")
else:
print("Wrong Input !")
self.p1.learn(move1, move2)
self.p2.learn(move2, move1)
def play_game(self):
print("Game start!")
for round in range(3):
print(f"Round {round}:")
self.play_round()
print("Game over!")
if __name__ == '__main__':
game1 = Game(ReflectPlayer(),HumanPlayer())
game1.play_game()

Consider changing your implementation to pass the last moves played to the move() method. If your player needs to use the previous moves then you can access them easily. If not just discard them. I am assuming that you will have other types of players that can benefit from this.
rsp = ['rock', 'paper', 'scissors']
class ReflectPlayer:
def move(self, lastOpponentMove):
if lastOpponentMove == None:
return rsp[random.randint(0,2)]
elif lastOpponentMove == rsp[0]:
return rsp[0]
elif lastOpponentMove == rsp[1]:
return rsp[1]
elif lastOpponentMove == rsp[2]:
return rsp[2]
else:
print("Wrong input !")
pass
def learn(self,my_move,their_move):
pass
Possible adaption on the Game class:
class Game:
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
self.lastP1Move = None
self.lastP2Move = None
def play_round(self):
move1 = self.p1.move(lastP2Move)
move2 = self.p2.move(lastP1Move)
lastP1Move = move1
lastP2Move = move2
print(f"Player 1: {move1} Player 2: {move2}")
if beats(move1 , move2) == True:
print(f"This Round : Player 1 WIN")
elif beats(move2 , move1) == True:
print(f"This Round : Player 2 WIN")
elif move1 == move2:
print("This Round : TIE")
else:
print("Wrong Input !")
self.p1.learn(move1, move2)
self.p2.learn(move2, move1)
Some notes:
You defined rsp as global in the beginning so you can use that list instead of creating new ones.
The way you implemented the check to see if it was the first play would make it so that i would be 1 everytime. (I changed to see if you are receiving a None last move).
Check your indentation in the play_round method
Hope this helps

Related

Error in Python code for Rock Paper Scissors

I am a python newbie and this is my first question on stackoverflow so sorry if it's not correct. I am programming my own rock, paper scissors game in Python, which includes a computer class which remembers the previous turn of the player. However, I can only get it to return random.choice moves, and I am not sure where I am going wrong?
moves = ['rock', 'paper', 'scissors']
class Player:
def __init__(self):
self.my_move = None
self.their_move = None
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 MemoryPlayer(Player):
def move(self):
if self.their_move in moves:
return self.their_move
else:
return random.choice(moves)
class Game:
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
self.scorep1 = 0
self.scorep2 = 0
# starting score of both players
def play_round(self):
firstmove = self.p1.move()
secondmove = self.p2.move()
print(f"Player 1: {firstmove} Player 2: {secondmove}")
# prints move of Player 1 and Player 2 after each round
if beats(firstmove, secondmove):
self.scorep1 += 1
print(f"Player 1 Wins. Score: {self.scorep1}"
f" to {self.scorep2}")
elif beats(secondmove, firstmove):
self.scorep2 += 1
print(f"Player 2 Wins. Score: {self.scorep2}"
f" to {self.scorep1}")
else:
print(f"Boring - TIE. Score: {self.scorep1}"
f" to {self.scorep2}")
# uses beats function in if and else statement to define score increase
# if player 1 move beats player 2 move and vice versa
def play_game(self):
print("Game start!")
self.rounds = 3
for round in range(self.rounds):
print(f"Round {round}:")
self.play_round()
print(f"Game over! Final score:\
Player 1: {self.scorep1}), Player 2: {self.scorep2}")
# prints final secores for Player 1 and Player 2
if self.scorep1 > self.scorep2:
print("Player 1 is Triumphant")
# if player 1 score is greater than player 2 - prints winning statement
elif self.scorep2 > self.scorep1:
print("Player 2 is Triumphant")
# if player 2 score is greater than player 1 - prints winning statement
else:
print("Boring - TIE")
if __name__ == '__main__':
game = Game(HumanPlayer(), MemoryPlayer())
# randomly chooses opposing NPC
game.play_game()

My main function is repeating in an infinite loop and I do not know why

I am running a program that plays rock, paper, scissors. I have executed the code multiple times and everytime I do, the input asking the user to pick 0,1,2 repeats more than one time. It is only supposed to be asked one time per game cycle. Can anyone help me figure out why this is happening, and how to fix it?
import random
# Function: Display Menu
# Input: none
# Output: none
# displays the game rules to the user
def displayMenu():
print("Welcome! Let's play rock, paper, scissors.")
print("The rules of the game are:")
print("\tRock smashes scissors")
print("\tScissors cut paper")
print("\tPaper covers rock")
print("\tIf both the choices are the same, it's a tie")
# Function: Get Computer Choice
# Input: none
# Output: integer that is randomly chosen, a number between 0 to 2
def getComputerChoice():
computerChoice = random.randrange(0,3)
return computerChoice
# Function: Get Player Choice
# Input: none
# Output: integer that represents the choice
# Asks the user for their choice: 0 for rock, 1 for paper, or 2 for scissors
def getPlayerChoice():
playerChoice = int(input("Please choose (0) for rock, (1) for paper or (2) for scissors"))
return playerChoice
# Function: Play Round
# Input: two integers--one representing the computer's choice and the other representing the player's choice
# Output: integer (-1 if computer wins, 1 if player wins, 0 if there is a tie)
# This method contains the game logic so it stimulates the game and determines a winner
def playRound(getcomputerChoice, getplayerChoice):
if getplayerChoice == 0 and getcomputerChoice == 2:
return 1
elif getcomputerChoice == 0 and getplayerChoice == 2:
return -1
elif getplayerChoice == 2 and getcomputerChoice == 1:
return 1
elif getcomputerChoice == 2 and getplayerChoice == 1:
return -1
elif getplayerChoice == 1 and getcomputerChoice == 0:
return 1
elif getcomputerChoice == 1 and getplayerChoice == 0:
return 1
else:
return 0
# Function: Continue Game
# Input: none
# Output: boolean
# Ask the user is they want to continue (Y/N), and then return True or False accordingly
def continueGame():
playAgain = input("Do you want to continue playing? Enter (y) for yes or (n) for no.")
if playAgain.lower() == "y":
return True
elif playAgain.lower() == "n":
return False
# Function: main
# Input: none
# Output: none
def main():
displayMenu()
getPlayerChoice()
if getPlayerChoice() == 0:
choicePlayer = "rock"
elif getPlayerChoice() == 1:
choicePlayer = "paper"
elif getPlayerChoice() == 2:
choicePlayer = "scissors"
getComputerChoice()
if getComputerChoice() == 0:
choiceComputer = "rock"
elif getComputerChoice() == 1:
choiceComputer = "paper"
elif getComputerChoice() == 2:
choiceComputer = "scissors"
print("You chose", choicePlayer + ".")
print("The computer chose", choiceComputer + ".")
playRound(getComputerChoice(), getPlayerChoice())
continueGame()
while continueGame() == True:
displayMenu()
getPlayerChoice()
getComputerChoice()
playRound(getComputerChoice(), getPlayerChoice())
continueGame()
playerCounter = 0
computerCounter = 0
tieCounter = 0
while playRound(getPlayerChoice(), getPlayerChoice()) == -1:
computerCounter += 1
while playRound(getPlayerChoice(), getPlayerChoice()) == 1:
playerCounter += 1
while playRound(getPlayerChoice(), getPlayerChoice()) == 0:
tieCounter += 1
print()
print("You won", playerCounter, "game(s).")
print("The computer won", computerCounter, "game(s).")
print("You tied with the computer", tieCounter, "time(s).")
print()
print("Thanks for playing!")
# Call Main
main()
It's because when you do:
if getPlayerChoice() == 0:
choicePlayer = "rock"
You are actually calling the method again.
You should do:
p_choice = getPlayerChoice()
if p_choice == 0:
...

TypeError: move() missing 1 required positional argument: 'HumanMove'

My code is not working. It says required argument 'HumanMove'.
I pretty much don't understand what python is trying to tell me.
see the code below.
The computer is bugging at this line: HumanMove = self.HumanPlayer.move()
import random
#Create player class
class Player:
def move(self):
return 'rock'
def learn(self, my_move, their_move):
pass
#Create random player class
class RandomPlayer:
def __init__(self):
Player.__init__(self)
def move(self, RandomPlayerMove):
self.move = RandomPlayerMove
#use imported random function
RandomPlayerMove = random.randint(1,3)
#Computer choice is either rock, paper, or scissors
if RandomPlayerMove == ("Rock"):
print("The computer choses ROCK")
elif RandomPlayerMove == ("Paper"):
print("The computer choses PAPER")
else:
print("The computer choses SCISSORS")
#return value
return RandomPlayerMove
#Create human player class
class HumanPlayer:
def __init__(self):
Player.__init__(self)
def move(self, HumanMove):
return HumanMove
##class that remembers what move the opponent played last round
class ReflectPlayer:
def __init__(self, ReflectPlayer):
Player.__init__(self)
self.ReflectPlayer = ReflectPlayer
#def move
def move(self, move):
self.move = move
def getmove(self, move):
return self.move
#define cycleplayer class that remembers what move it played last round,
# and cycles through the different moves.
class CyclePlayer:
def __init__(self, CyclePlayer):
Player.__init__(self)
self.CyclePlayer = CyclePlayer
self.human_player_history = {} # stores the frequency of human player
moves
for move in moves:
self.human_player_history[move] = 0
def move(self, max_move):
max_move = max(self.human_player_history.items(), key=lambda elem:
elem[1])[0]
if max_move == 'rock':
return 'paper'
if max_move == 'scissors':
return 'rock'
if max_move == 'paper':
return 'rock'
def beats(one, two):
return ((one == 'rock' and two == 'scissors') or
(one == 'scissors' and two == 'paper') or
(one == 'paper' and two == 'rock'))
#Create game class
class Game:
def __init__(self, HumanPlayer, RandomPlayer):
self.HumanPlayer = HumanPlayer
self.RandomPlayer = RandomPlayer
def play_round(self):
HumanMove = self.HumanPlayer.move()
RandomPlayerMove = self.RandomPlayer.move()
print(f"HumanPlayer: {HumanMove} RandomPlayer: {RandomPlayerMove}")
self.HumanPlayer.learn(HumanMove, RandomPlayerMove)
self.RandomPlayer.learn(RandomPlayerMove, HumanMove)
if beats(HumanMove, RandomPlayerMove):
print("HumanPlayer wins this round")
self.HumanPlayer.score += 1
elif beats(RandomPlayerMove, HumanMove):
print("RandomPlayer wins this round")
self.RandomPlayer.score += 1
else:
print("It's Tie, Play again!")
print(f"Scores, HumanPlayer: {self.p1.score} RandomPlayer:
{self.p2.score}")
def move(self, HumanMove):
^^^^^^^^^
return HumanMove
You defined move with the parameter HumanMove. When you call the method you must supply an argument for that parameter.

Python SyntaxError: invalid syntax [elif my_move == 'rock']

I'm developing a rock paper scissors on python and I'm getting this syntax error
any help is appreciated
class Player:
def move(self):
return 'rock'
def learn(self, my_move, their_move):
self.my_move = my_move
self.their_move = their_movee here
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)
my_score = 0
computer_score = 0
if beats(move1, move2):
my_score = my_score + 1
print ("You win")
print ("Human score = " + str(my_score) + " " + "Computer score = " + str(computer_score) )
elif beats(move2,move1):
computer_score = computer_score + 1
print ("Computer wins")
print ("Human score = " + str(my_score) + " " + "Computer score = " + str(computer_score) )
else:
print ("Draw")
print ("Human score = " + str(my_score) + " " + "Computer score = " + str(computer_score) )
def play_game(self):
print("Game start!")
for round in range(3):
print(f"Round {round}:")
self.play_round()
print("Game over!")
class cycleplayer(Player):
def move(self):
if round == 0 :
return 'rock'
elif self.my_move == 'rock'
return "paper"
elif self.my_move == 'paper'
return "scissors"
else self.my_move == 'scissors'
return "rock"
on the cycleplayer subclass I want the program to take the previous move and use it in the current round
I get an error on the first elif in the subclass cycleplayer
the error points on "rock"
invalid syntax ()
In addition to the missing colons after your elif's and the disallowed condition following else, this might have an issue because of the white space. Be sure to indent the member functions within your classes!

Python 3: Why does my class' function run twice?

I have a class which contains this attack function:
def attack(self, victim):
strike = 0
if victim.strength > self.strength:
strike = 40
else:
strike = 70
successChance = randint(1,100)
if successChance > strike:
self.lives -= 1
return False
else:
victim.lives -= 1
return True
It is only supposed to run once each time a user presses a button, however it runs twice meaning that every button press counts as two. I know the error is in my class function because the error occurs during test runs of the class.
The only code within the class which calls the function is my test function which only runs internally. Yet the problem persists in my GUI code.
This is my class function:
class Player(object):
def __init__(self, name="", lives=DEFAULT_LIVES):
self._name = name
self.lives = lives
self.strength = randint(1,10)
if self._name== "Test":
self.lives = 1000
if self._name== "":
self._name = "John Smith"
def __str__(self):
return (self._name + " Life: " + str(self.lives) + " Strength: " + str(self.strength))
def getLives(self):
return self.lives
def getStrength(self):
self.strength = randint(1,10)
return self.strength
def getName(self):
return self._name
def isAlive(self):
if self.lives <= 0:
return False
return True
def attack(self, victim):
if victim.strength > self.strength:
strike = 40
else:
strike = 70
successChance = randint(1,100)
if successChance > strike:
print(successChance)
self.lives -= 1
return False
else:
print(successChance)
victim.lives -= 1
return True
def test():
player = Player("Tyler")
opponent = Player(choice(opponentList))
while player.isAlive() == True and opponent.isAlive() == True:
print(player)
print(opponent)
player.attack(opponent)
player.isAlive()
opponent.isAlive()
if not player.attack(opponent):
print("You lost")
else:
print("You won")
print("Game Over")
if __name__ == '__main__':
test()
Well if looks like you're actually calling the function twice in test():
#your old code:
while player.isAlive() == True and opponent.isAlive() == True:
print(player)
print(opponent)
player.attack(opponent) #called once here
player.isAlive()
opponent.isAlive()
if not player.attack(opponent):#called 2nd time here
print("You lost")
else:
print("You won")
print("Game Over")
I'd try this instead:
while player.isAlive() and opponent.isAlive():
print(player)
print(opponent)
player_attack_was_successful = player.attack(opponent)
#player.isAlive() #(does this line even do anything?)
#opponent.isAlive()
if player_attack_was_successful:
print("You won")
else:
print("You lost")
print("Game Over")

Categories

Resources