To build our Rock Paper Scissors game we are going to use some elements of OOP, in fact, we are just going to create oneclass that is going to do all of it. So, without further ado...
import function choice from random module
declare class RPS
create an instance of this class called game
from random import choice
class RPS:
def __init__(self):
pass
# some more functions will go here
game = RPS()
Inside the __init__ function, we are going to have 4 variables:
opt is a list of options
usr_score and cpu_score are self-explanatory
rules is a dict that is going to help us decide who won without the need for extensive if / else statements
The last line of __init__ is going to be a call to some function match that also belongs to the class RPS.
# from now on we concentrate on the RPS class itself
class RPS:
def __init__(self):
self.opt = ['rock', 'paper', 'scissors']
self.usr_score = 0
self.cpu_score = 0
self.rules = {
'rock' : 'scissors',
'paper' : 'rock',
'scissors' : 'paper'
}
self.match()
# some more functions will go here
def match(self):
pass
Now, before we start implementing the match function, let's declare some useful 'helper' functions. I really like using functions in my code because they make debugging really easy, so do not be surprised when you see a function that is one line long...
# from now on we concentrate on the RPS class itself
class RPS:
def __init__(self):
self.opt = ['rock', 'paper', 'scissors']
self.usr_score = 0
self.cpu_score = 0
self.rules = {
'rock' : 'scissors',
'paper' : 'rock',
'scissors' : 'paper'
}
self.match()
def err(self, msg):
print(f"ERROR: {msg}")
def disp_scores(self):
print(f"SCORES:\n\tYOU: {self.usr_score}\n\tCPU: {self.cpu_score}\n")
def tie(self):
print("It's a tie")
self.usr_score += 1
self.cpu_score += 1
def usr_win(self):
print("You won!")
self.usr_score += 1
def cpu_win(self):
print("CPU won!")
self.cpu_score += 1
def ask(self):
pass
def match(self):
pass
These 'helper' functions are going to be called each time we run the match function. You may have also noticed the ask function almost at the very end of the class definition. This function has to make sure that we get user input in the correct format before evaluating the results. This function, in case of invalid user input becomes recursive, so "Yaaay!". Let's see...
First of all, in the ask function, we want to display the options. For user's convenience, we are going to enumerate them:
# now concentrating on the ask function
def ask(self):
for i in range( len(self.opt) ): print(f"{i + 1}. {self.opt[i]}")
# it's incomplete, we're gonna write some more here!
Now, we are going to ask user for input:
# now concentrating on the ask function
def ask(self):
for i in range( len(self.opt) ): print(f"{i + 1}. {self.opt[i]}")
usr = input("\nSelect one option: ")
# it's incomplete, we're gonna write some more here!
We, as software developers, have to think ahead and always assume that user is an idiot who always makes mistakes (but we still love him). Therefore, next few lines are going to deal with exceptions that may arise if an invalid input is given:
# now concentrating on the ask function
def ask(self):
for i in range( len(self.opt) ): print(f"{i + 1}. {self.opt[i]}")
usr = input("\nSelect one option: ")
try: usr = int(usr) - 1
except ValueError:
self.err("INPUT INVALID! YOU MUST INPUT A NUMBER!\n")
return self.ask()
if -1 < usr < len(self.opt): return self.opt[usr]
else:
self.err( "INPUT INVALID! YOU MUST INPUT A NUMBER BETWEEN 1 AND {len(self.opt)}!\n" )
return self.ask()
Note that whenever we encounter an error, we let user know by displaying an error message and then we return self.ask(). This is because we want to run function ask again and again until user would be so kind as to provide us with a valid input value which we are then going to return. At this point, we have actually completed three fourth of our game! Congrats!
Now the last bit: the match function. The match function is a lazy dude that uses other functions' labour to fulfill its own purpose, but we aren't angry at it... after all, we've designed it this way :) First two lines will select CPU's choice and ask user to input their answer. Let's also print those, so that the user knows what CPU's choice was. By the way, for those of you who don't know how random.choice() function works, it is a pseudo-random function that returns one value from a given list (in this case, the opt list).
# now concentrating on the match function
def match(self):
cpu = choice(self.opt)
usr = self.ask()
print(f"You chose {usr.upper()} and CPU chose {cpu.upper()}")
When we have those choices, we can evaluate and decide who is the winner. As I said earlier on, the dict called rules will help us with it. How does it work then? Well, if we take a look at the rules...
...we can see that item on the left always beats items on the right and this is very useful in this case. For every pair of choices, there are only 3 possible outcomes:
Both choices are the same and thus, it is a tie
User wins
CPU wins
Therefore, logically, the first thing to do is to check whether it is a tie (it's also the easiest one). If we use user's choice as a key and request its value from the rules and this value is equal to CPU's choice then we know that user won since we've designed rules in such way the any key 'beats' its value. If it is not a tie and user didn't win, then we must give point to the CPU. This is how it looks in code:
# focusing on the match function
def match(self):
cpu = choice(self.opt)
usr = self.ask()
print(f"You chose {usr.upper()} and CPU chose {cpu.upper()}")
if usr == cpu: self.tie()
else:
if self.rules[usr] == cpu: self.usr_win()
else: self.cpu_win()
The match function is almost complete now: only 5 lines to go. We want to display scores, which is easily done using the disp_scores function. And the last bit: we want to know whether the user wants to play one more time or quit the game, so we declare a bool variable that is going to be the answer to this question and its value will, once more, depend on the user input. If it is True, we'll call our match function again, otherwise we'll print("Bye-bye!").
# focusing on the match function
def match(self):
cpu = choice(self.opt)
usr = self.ask()
print(f"You chose {usr.upper()} and CPU chose {cpu.upper()}")
if usr == cpu: self.tie()
else:
if self.rules[usr] == cpu: self.usr_win()
else: self.cpu_win()
self.disp_scores()
endit = input("If you want to stop, enter 'q'. Otherwise, press ENTER. ").lower() == 'q'
print() # this is just for spacing
if not endit: self.match()
else: print("Bye-bye!")
That's it fellas. We are officially done now. Hope it was fun. There you have the Link to the Repl containing my source code for this game.
Rock Paper Scissors Game in 60 lines (Python3)
To build our Rock Paper Scissors game we are going to use some elements of OOP, in fact, we are just going to create one
class
that is going to do all of it. So, without further ado...import
functionchoice
fromrandom
moduleclass RPS
class
calledgame
Inside the
__init__
function, we are going to have 4 variables:opt
is alist
of optionsusr_score
andcpu_score
are self-explanatoryrules
is adict
that is going to help us decide who won without the need for extensiveif / else
statementsThe last line of
__init__
is going to be a call to some functionmatch
that also belongs to theclass RPS
.Now, before we start implementing the
match
function, let's declare some useful 'helper' functions. I really like using functions in my code because they make debugging really easy, so do not be surprised when you see a function that is one line long...These 'helper' functions are going to be called each time we run the
match
function. You may have also noticed theask
function almost at the very end of theclass
definition. This function has to make sure that we get user input in the correct format before evaluating the results. This function, in case of invalid user input becomes recursive, so "Yaaay!". Let's see...First of all, in the
ask
function, we want to display the options. For user's convenience, we are going to enumerate them:Now, we are going to ask user for
input
:We, as software developers, have to think ahead and always assume that user is an idiot who always makes mistakes (but we still love him). Therefore, next few lines are going to deal with
exception
s that may arise if an invalid input is given:Note that whenever we encounter an error, we let user know by displaying an error message and then we
return self.ask()
. This is because we want to run functionask
again and again until user would be so kind as to provide us with a valid input value which we are then going to return. At this point, we have actually completed three fourth of our game! Congrats!Now the last bit: the
match
function. Thematch
function is a lazy dude that uses other functions' labour to fulfill its own purpose, but we aren't angry at it... after all, we've designed it this way :)First two lines will select CPU's choice and
ask
user to input their answer. Let's alsoprint
those, so that the user knows what CPU's choice was. By the way, for those of you who don't know howrandom.choice()
function works, it is a pseudo-random function thatreturn
s one value from a givenlist
(in this case, theopt
list).When we have those choices, we can evaluate and decide who is the winner. As I said earlier on, the
dict
calledrules
will help us with it. How does it work then? Well, if we take a look at therules
......we can see that item on the left always beats items on the right and this is very useful in this case. For every pair of choices, there are only 3 possible outcomes:
Therefore, logically, the first thing to do is to check whether it is a tie (it's also the easiest one). If we use user's choice as a key and request its value from the
rules
and this value is equal to CPU's choice then we know that user won since we've designedrules
in such way the any key 'beats' its value. If it is not a tie and user didn't win, then we must give point to the CPU. This is how it looks in code:The
match
function is almost complete now: only 5 lines to go. We want to display scores, which is easily done using thedisp_scores
function. And the last bit: we want to know whether the user wants to play one more time or quit the game, so we declare abool
variable that is going to be the answer to this question and its value will, once more, depend on the userinput
. If it isTrue
, we'll call ourmatch
function again, otherwise we'llprint("Bye-bye!")
.That's it fellas. We are officially done now. Hope it was fun.
There you have the Link to the Repl containing my source code for this game.
Nice! Thanks for sharing! :)