Skip to content

Instantly share code, notes, and snippets.

@tmitzka
Last active April 15, 2018 19:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmitzka/c9fe82af7c1308676753577693bafad3 to your computer and use it in GitHub Desktop.
Save tmitzka/c9fe82af7c1308676753577693bafad3 to your computer and use it in GitHub Desktop.
An improved version of Rock, Paper, Scissors.
"""Rock, Paper, Scissors.
There are two playing modes: user vs computer, and computer vs computer.
The game will continue until one player reaches a set score number.
Finally the user can decide whether to start a new game.
2018-03
"""
import random
import time
# Rock, Paper, Scissors:
RPS = ("Rock", "Paper", "Scissors")
# Score required to win the game:
MAX_SCORE = 3
# Length of pauses between game sections.
# Change this value to make the game faster or slower:
SECONDS = 1.5
class RockPaperScissors():
"""A two-way game of Rock, Paper, Scissors."""
def __init__(self):
"""Initialize attributes."""
self.new_game = True
self.round_counter = 0
self.players = {}
for player_key in ("player1", "player2"):
self.players[player_key] = {
"hand": "",
"score": 0,
"human": False,
"name": None,
}
# Let user choose playing mode.
self.choose_mode()
def choose_mode(self):
"""Ask if a human will play, and set attributes accordingly."""
print("Hello, human! Make your choice:")
print("\n1) Human vs Computer")
print("2) Computer vs Computer")
choice = ""
while (choice not in "12") or (len(choice) != 1):
choice = input("\nPlease enter 1 or 2: ")
player1, player2 = self.players.keys()
if choice == "1":
self.players[player1]["human"] = True
self.players[player1]["name"] = "You"
self.players[player2]["name"] = "Computer"
else:
self.players[player1]["name"] = "Player 1"
self.players[player2]["name"] = "Player 2"
def choose_forms(self):
"""Let the user make a choice, or choose a random number."""
print(f"\n\n== ROUND {self.round_counter} ==")
for player in self.players:
# Human player:
if self.players[player]["human"]:
print()
for number, form in enumerate(RPS, 1):
print(f"{number}) {form}")
number = ""
while (number not in "123") or (len(number) != 1):
number = input("\nPlease enter 1, 2, or 3: ")
self.players[player]["hand"] = int(number) - 1
# Computer player:
else:
self.players[player]["hand"] = random.randrange(3)
def decide_round_winner(self):
"""Decide who wins."""
player1, player2 = self.players.keys()
p1_hand = self.players[player1]["hand"]
p2_hand = self.players[player2]["hand"]
if ((p1_hand == 0 and p2_hand == 2) or
(p1_hand == 1 and p2_hand == 0) or
(p1_hand == 2 and p2_hand == 1)):
winner = player1
elif ((p2_hand == 0 and p1_hand == 2) or
(p2_hand == 1 and p1_hand == 0) or
(p2_hand == 2 and p1_hand == 1)):
winner = player2
else:
winner = None
return winner
def show_score(self):
"""Show both players' score."""
print("\n\n== SCORE ==\n")
for player in self.players.values():
print(f"{player['name']}: {player['score']}")
def decide_total_winner(self):
"""Show the total winner of this game."""
total_winner = None
for player, value in self.players.items():
if value["score"] == MAX_SCORE:
total_winner = player
return total_winner
def choose_new_game(self):
"""Ask whether to start a new game.
If the answer is yes, set flag attribute and
reset attributes.
"""
answer = ""
while (answer not in "yn") or (len(answer) != 1):
answer = input("\nStart a new game? (y/n) ").lower()
if answer == "y":
new_game = True
self.round_counter = 0
for player in self.players.values():
player["score"] = 0
else:
new_game = False
return new_game
def play(self):
"""Start game loop and call game methods."""
print("\n== Welcome to ROCK, PAPER, SCISSORS! ==\n")
print(f"The game will end when a player has won {MAX_SCORE} times.")
input("Press ENTER to begin. ")
while self.new_game:
# Raise round counter.
self.round_counter += 1
# Let the players choose their forms.
self.choose_forms()
# Decide the round winner.
round_winner = self.decide_round_winner()
# Show the players' choices.
print()
for player in self.players.values():
time.sleep(SECONDS)
print(f"{player['name']} chose: {RPS[player['hand']]}")
# Show who has won this round or whether it was a tie.
# Raise the winner's score.
if round_winner:
time.sleep(SECONDS)
print(f"{self.players[round_winner]['name']} won!")
self.players[round_winner]["score"] += 1
else:
time.sleep(SECONDS)
print("It's a tie!")
# Show the players' score.
time.sleep(SECONDS)
self.show_score()
# Check if a player has reached the maximum score number.
# If so, declare the total winner.
total_winner = self.decide_total_winner()
if total_winner:
total_winner_name = self.players[total_winner]["name"]
print(f"\n* Winner: {total_winner_name} *".upper())
# Ask whether the user wants to start a new game.
print()
time.sleep(SECONDS)
self.new_game = self.choose_new_game()
print("\nGoodbye, human. Until next time.")
def main():
"""Create game object and start its play() method."""
rps_game = RockPaperScissors()
rps_game.play()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment