patternpythonMinor
Rock paper scissors
Viewed 0 times
scissorspaperrock
Problem
I've started learning Python recently and I wanted to test myself. So, can you tell me how many I would get out of 10 and how I could improve my future coding?
```
import random
import time
print('Welcome to Rock, Paper, Scissors')
print(' '*25)
wins = 0
loses = 0
draws = 0
point= int(input('How many rounds do you want to play?'))
list = ['r','p','s']
for x in range (1,(point+1)):
computer = random.choice(list)
human=str(input('Choose (R)ock, (P)aper, or (S)cissors?'))
if human == computer:
draws = draws + 1
print('''Human: {} Computer: {} A draw
Wins = {} Loses = {} Draws = {}'''.format(human,computer,wins,loses,draws))
print(' '*25)
elif human == 'r' and computer == 'p':
loses = loses + 1
print('''Human: ROCK Computer: PAPER Computer wins
Wins = {} Loses = {} Draws = {}'''.format(wins,loses,draws))
print(' '*25)
elif human == 'r' and computer == 's':
wins = wins + 1
print('''Human: ROCK Computer: SCISSORS Human wins
Wins = {} Loses = {} Draws = {}'''.format(wins,loses,draws))
print(' '*25)
elif human == 'p' and computer == 's':
loses = loses + 1
print('''Human: PAPER Computer: SCISSORS Computer wins
Wins = {} Loses = {} Draws = {}'''.format(wins,loses,draws))
print(' '*25)
elif human == 'p' and computer == 'r':
wins = wins + 1
print('''Human: PAPER Computer: ROCK Human wins
Wins = {} Loses = {} Draws = {}'''.format(wins,loses,draws))
print(' '*25)
elif human == 's' and computer == 'p':
wins = wins + 1
print('''Human: SCISSORS Computer: PAPER Human wins
Wins = {} Loses = {} Draws = {}'''.format(wins,loses,draws))
print(' '*25)
elif human == 's' and computer == 'r':
loses = loses + 1
print('''Human: SCISSORS Computer: ROCK Compu
```
import random
import time
print('Welcome to Rock, Paper, Scissors')
print(' '*25)
wins = 0
loses = 0
draws = 0
point= int(input('How many rounds do you want to play?'))
list = ['r','p','s']
for x in range (1,(point+1)):
computer = random.choice(list)
human=str(input('Choose (R)ock, (P)aper, or (S)cissors?'))
if human == computer:
draws = draws + 1
print('''Human: {} Computer: {} A draw
Wins = {} Loses = {} Draws = {}'''.format(human,computer,wins,loses,draws))
print(' '*25)
elif human == 'r' and computer == 'p':
loses = loses + 1
print('''Human: ROCK Computer: PAPER Computer wins
Wins = {} Loses = {} Draws = {}'''.format(wins,loses,draws))
print(' '*25)
elif human == 'r' and computer == 's':
wins = wins + 1
print('''Human: ROCK Computer: SCISSORS Human wins
Wins = {} Loses = {} Draws = {}'''.format(wins,loses,draws))
print(' '*25)
elif human == 'p' and computer == 's':
loses = loses + 1
print('''Human: PAPER Computer: SCISSORS Computer wins
Wins = {} Loses = {} Draws = {}'''.format(wins,loses,draws))
print(' '*25)
elif human == 'p' and computer == 'r':
wins = wins + 1
print('''Human: PAPER Computer: ROCK Human wins
Wins = {} Loses = {} Draws = {}'''.format(wins,loses,draws))
print(' '*25)
elif human == 's' and computer == 'p':
wins = wins + 1
print('''Human: SCISSORS Computer: PAPER Human wins
Wins = {} Loses = {} Draws = {}'''.format(wins,loses,draws))
print(' '*25)
elif human == 's' and computer == 'r':
loses = loses + 1
print('''Human: SCISSORS Computer: ROCK Compu
Solution
Your program is adequate, but it doesn't "scale". Each player can choose from 3 moves; of those 9 possibilities, the 3 ties can be handled in common, for a total of 7 code branches. Handling all those cases with cut-and-paste code violates the "Don't Repeat Yourself" principle, and it makes the code hard to maintain.
I would start by introducing a class to represent the moves, and define how they relate to each other:
Next, I would extract the way the computer and human take their turns into functions:
The
With those preliminaries out of the way, the heart of the game can look quite nice.
I've renamed
I would start by introducing a class to represent the moves, and define how they relate to each other:
from collections import namedtuple
class RPSMove(namedtuple('RPSMove', ['name', 'short_name', 'beats'])):
def __gt__(self, other):
return self.beats == other.short_name
def __lt__(self, other):
return not(self == other or self > other)
def __str__(self):
return self.name
all = dict()
RPSMove.all['r'] = RPSMove('rock', short_name='r', beats='s')
RPSMove.all['p'] = RPSMove('paper', short_name='p', beats='r')
RPSMove.all['s'] = RPSMove('scissors', short_name='s', beats='p')Next, I would extract the way the computer and human take their turns into functions:
import random
from sys import exit
def computer_play():
return random.choice(list(RPSMove.all.values()))
def human_play():
while True:
try:
choice = input('Choose (R)ock, (P)aper, or (S)cissors? ')
return RPSMove.all[choice[0].lower()]
except EOFError:
print('')
exit(0)
except:
print('Error')The
human_play() function is more complex than your original due to handling of invalid choices and end-of-file (Control+D in Unix or Control+Z in Windows).With those preliminaries out of the way, the heart of the game can look quite nice.
random.seed()
human_wins, computer_wins, draws = 0, 0, 0
print('Welcome to Rock, Paper, Scissors')
print('')
rounds = int(input('How many rounds do you want to play? '))
for _ in range(rounds):
human_move, computer_move = human_play(), computer_play()
if human_move > computer_move:
result = 'Human wins'
human_wins += 1
elif human_move < computer_move:
result = 'Computer wins'
computer_wins += 1
else:
result = 'A draw'
draws += 1
print('Human: %-17s Computer: %-17s %s' %
(human_move, computer_move, result))
print('Human wins = %-11d Computer wins = %-11d Draws = %-11d' %
(human_wins, computer_wins, draws))
print('')I've renamed
wins and loses to human_wins and computer_wins to avoid anthropocentrism.Code Snippets
from collections import namedtuple
class RPSMove(namedtuple('RPSMove', ['name', 'short_name', 'beats'])):
def __gt__(self, other):
return self.beats == other.short_name
def __lt__(self, other):
return not(self == other or self > other)
def __str__(self):
return self.name
all = dict()
RPSMove.all['r'] = RPSMove('rock', short_name='r', beats='s')
RPSMove.all['p'] = RPSMove('paper', short_name='p', beats='r')
RPSMove.all['s'] = RPSMove('scissors', short_name='s', beats='p')import random
from sys import exit
def computer_play():
return random.choice(list(RPSMove.all.values()))
def human_play():
while True:
try:
choice = input('Choose (R)ock, (P)aper, or (S)cissors? ')
return RPSMove.all[choice[0].lower()]
except EOFError:
print('')
exit(0)
except:
print('Error')random.seed()
human_wins, computer_wins, draws = 0, 0, 0
print('Welcome to Rock, Paper, Scissors')
print('')
rounds = int(input('How many rounds do you want to play? '))
for _ in range(rounds):
human_move, computer_move = human_play(), computer_play()
if human_move > computer_move:
result = 'Human wins'
human_wins += 1
elif human_move < computer_move:
result = 'Computer wins'
computer_wins += 1
else:
result = 'A draw'
draws += 1
print('Human: %-17s Computer: %-17s %s' %
(human_move, computer_move, result))
print('Human wins = %-11d Computer wins = %-11d Draws = %-11d' %
(human_wins, computer_wins, draws))
print('')Context
StackExchange Code Review Q#36368, answer score: 4
Revisions (0)
No revisions yet.