Skip to content

Instantly share code, notes, and snippets.

@ZechCodes
Created July 2, 2019 20:49
Show Gist options
  • Save ZechCodes/09d5e5e6fe0e8cc5c560dffe68555636 to your computer and use it in GitHub Desktop.
Save ZechCodes/09d5e5e6fe0e8cc5c560dffe68555636 to your computer and use it in GitHub Desktop.
Really basic rock, paper, scissors CLI game.
from __future__ import annotations
from typing import AnyStr, Callable, Container, Tuple, Union
class Choice:
def __init__(self, name: AnyStr, beats: Choice = None):
self._name = name
self._beats = beats
@property
def name(self):
return self._name
def beats(self, choice: Choice) -> Choice:
""" Set the choice that this beats and then return the choice it beats so that we can easily set what it
beats."""
self._beats = choice
return choice
def wins(self, choice: Choice) -> bool:
""" Check if we have a choice that we can beat and whether that choice is the same choice that we're
testing. """
return self._beats and self._beats.name == choice.name
def get_input(message: AnyStr, valid_options: Container, converter: Callable = str):
""" Asks the user for input until they give an answer that is valid. """
user_input = None
while user_input not in valid_options:
try:
user_input = converter(input(f"{message} "))
except ValueError:
pass
return user_input
class Game:
def __init__(self):
self._choices = {}
def add_choice(self, name: AnyStr, beats: Union[AnyStr, None] = None) -> Game:
""" Creates the choice if it doesn't exist, modifies it if it already exists.
Both parameters are case insensitive strings.
"""
self._choices[name.lower()] = self.get_choice(name) if self.get_choice(name) else Choice(name)
self.get_choice(name).beats(self.get_choice(beats))
return self
def get_choice(self, name: AnyStr) -> Union[Choice, None]:
""" Safely get's a choice, returning None if it doesn't exist. """
return self._choices.get(name.lower() if name else None)
def play(self):
print("Let's Play!!")
options = tuple(self._choices.keys())
player1_input = self.get_choice(get_input(f"Player 1 choose an option ({', '.join(options)})", options, str.lower))
player2_input = self.get_choice(get_input(f"Player 2 choose an option ({', '.join(options)})", options, str.lower))
if player1_input.wins(player2_input):
print("Player 1 Wins!!!")
elif player2_input.wins(player1_input):
print("Player 2 Wins!!!")
else:
print("It was a tie")
if __name__ == "__main__":
game = Game()
game.add_choice("Rock").add_choice("Paper", "Rock").add_choice("Scissors", "Paper").add_choice("Rock", "Scissors")
keep_playing = True
while keep_playing:
game.play()
keep_playing = get_input("Would you like to play again? y or n?", (True, False), lambda val: val.lower() == "y")
else:
print("Thanks for playing!!!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment