Enteleform
4/15/2017 - 1:34 PM

[Python] RockPaperScissors CLI Game

[Python] RockPaperScissors CLI Game

from random import choice



###############
###  Utils  ###
###############

def get_user_string(input_message):
  input_message += "\n> "
  return input(input_message)

def get_user_integer(input_message, fail_message, positive_only=False):
  integer = get_user_string(input_message)
  try:
    integer = int(integer)
  except ValueError:
    print(fail_message)
    return get_user_integer(input_message, fail_message, positive_only)

  if(positive_only) and (integer < 1):
    print("Input number must be greater than zero, try again.")
    return get_user_integer(input_message, fail_message, positive_only)
  else:
    return integer



##############
###  Game  ###
##############

class RockPaperScissors:
  options = {1:"Rock", 2:"Paper", 3:"Scissors"}
  invalid_option_message = "You must choose a number between 1 and 3, try again."
  user_score: int
  bot_score:  int

  def __init__(self):
    user_name = get_user_string("Enter your name:")
    print(f"Welcome, {user_name}, to Rock-Paper-Scissors!")
    self.start_game()

  def reset_score(self):
    self.user_score = 0
    self.bot_score  = 0

  def start_game(self):
    self.reset_score()
    max_score = get_user_integer(
      input_message = "\n\nNumber of points to win:",
      fail_message  = "Max score must be a number, try again.",
      positive_only = True,
    )
    print(
      "\n\nOptions:"
      "\n    1 (Rock)"
      "\n    2 (Paper)"
      "\n    3 (Scissors)"
    )
    while(self.user_score < max_score) and (self.bot_score < max_score):
      self.play_round()

    self.decide_game_winner()
    self.finish_game()

  def play_round(self):
    print(f"\n\nScore:  You[{self.user_score}]  Bot[{self.bot_score}]")
    user_index = get_user_integer(
      input_message = "Choose your move:",
      fail_message  = self.invalid_option_message,
    )
    user_choice = self.options.get(user_index, None)
    bot_index   = choice(list(self.options.keys()))
    bot_choice  = self.options.get(bot_index)
    choices     = (user_choice, bot_choice)

    if(user_choice == None):
      print(self.invalid_option_message)
    else:
      self.decide_round_winner(user_choice, bot_choice, choices)

  def decide_round_winner(self, user_choice, bot_choice, choices):
    choice_message = f"You picked {user_choice}."
    winner         = None
    winner_message = ""
    info_message   = ""

    if(user_choice == bot_choice):
      choice_message = f"You both picked {user_choice}."
      winner_message = "\nIt's a TIE."
    elif("Rock" in choices) and ("Scissors" in choices):
      winner  = "user" if(user_choice == "Rock") else("bot")
      info_message = "\nRock crushes Scissors."
    elif("Paper" in choices) and ("Rock" in choices):
      winner  = "user" if(user_choice == "Paper") else("bot")
      info_message = "\nPaper covers Rock."
    elif("Scissors" in choices) and ("Paper" in choices):
      winner  = "user" if(user_choice == "Scissors") else("bot")
      info_message = "\nScissors cut Paper."

    if(winner == "user"):
      winner_message = "\nYou win this round."
      self.user_score += 1
    elif(winner == "bot"):
      winner_message = "\nBot wins this round."
      self.bot_score += 1

    print(
      f"{choice_message}"
      f"{info_message}"
      f"{winner_message}"
    )

  def decide_game_winner(self):
    score_message  = f"Final Score:  You[{self.user_score}]  Bot[{self.bot_score}]"
    winner_message = "You Win!" if(self.user_score > self.bot_score) else("Bot Wins >:-]")
    print(
      f"\n\n\n\n{score_message}"
      f"\n{winner_message}"
    )

  def finish_game(self):
    play_again = get_user_string(
      "\nWould you like to play again?"
      "\n    y (yes)"
      "\n    n (no)"
    )
    if(play_again == "y"):
      self.start_game()
    else:
      print("Ok, thanks for playing!")



####################
###  Start Game  ###
####################

RockPaperScissors()