Last active
April 15, 2018 19:26
-
-
Save tmitzka/c9fe82af7c1308676753577693bafad3 to your computer and use it in GitHub Desktop.
An improved version of Rock, Paper, Scissors.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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