Feb-28-2022, 07:09 PM
(This post was last modified: Feb-28-2022, 08:48 PM by deanhystad.)
Trying to stay within the restraints of the original code I would write the code like this:
Adding in the history based AI is just a few new lines.
import random from enum import IntEnum class GameResults(IntEnum): Win = 0 Lose = 1 Draw = 2 class GameAction(IntEnum): Piedra = 0 Papel = 1 Tijeras = 2 def __str__(self): """Return str more suited for program.""" return f"{self.name}[{self.value}]" winning_results = { (GameAction.Piedra, GameAction.Tijeras) : "Piedra smashes tijeras", (GameAction.Papel, GameAction.Piedra) : "Papel covers piedra", (GameAction.Tijeras, GameAction.Papel) : "Tijeras cuts Papel", } def get_user_action(): """Get user selection""" prompt = f"""\nPick {", ".join([str(action) for action in GameAction])}: """ while True: try: action = input(prompt) return GameAction(int(action)) except ValueError: print(f"{action} is not a valid choice") def get_computer_action(): """Get computer selection""" return random.choice(list(GameAction)) def assess_game(user_action, computer_action): if user_action == computer_action: return GameResults.Draw, "" if (user_action, computer_action) in winning_results: return GameResults.Win, winning_results[(user_action, computer_action)] return GameResults.Lose, winning_results[(computer_action, user_action)] def main(): """Play a game of rock, paper, scissors""" while True: user_action = get_user_action() computer_action = get_computer_action() result, rule = assess_game(user_action, computer_action) if result == GameResults.Draw: print("Player and computer pick {}. Draw".format(user_action.name)) elif result == GameResults.Win: print("Player picks {}, computer picks {}. {}. Player wins!".format( user_action.name, computer_action.name, rule)) else: print("Player picks {}, computer picks {}. {}. Computer wins.".format( user_action.name, computer_action.name, rule)) if input("\nAnother round? (y/n): ").upper() != "Y": break if __name__ == "__main__": main()I don't think the enumerated types add value, but they aren't too onerous.
Adding in the history based AI is just a few new lines.
import random from enum import IntEnum class GameResults(IntEnum): Win = 0 Lose = 1 Draw = 2 class GameAction(IntEnum): Piedra = 0 Papel = 1 Tijeras = 2 def __str__(self): """Return str more suited for program.""" return f"{self.name}[{self.value}]" winning_results = { (GameAction.Piedra, GameAction.Tijeras) : "Piedra smashes tijeras", (GameAction.Papel, GameAction.Piedra) : "Papel covers piedra", (GameAction.Tijeras, GameAction.Papel) : "Tijeras cuts Papel", } def get_user_action(): """Get user selection""" prompt = f"""\nPick {", ".join([str(action) for action in GameAction])}: """ while True: try: action = input(prompt) return GameAction(int(action)) except ValueError: print(f"{action} is not a valid choice") def get_computer_action(history=[]): """Get computer selection. Use history to predict what user will do""" user_action = random.choice(history + list(GameAction)) computer_actions = [action for action in list(GameAction) if (action, user_action) in winning_results] return random.choice(computer_actions) def assess_game(user_action, computer_action): if user_action == computer_action: return GameResults.Draw, "" if (user_action, computer_action) in winning_results: return GameResults.Win, winning_results[(user_action, computer_action)] return GameResults.Lose, winning_results[(computer_action, user_action)] def main(): """Play a game of rock, paper, scissors""" history = [] while True: user_action = get_user_action() computer_action = get_computer_action(history) result, rule = assess_game(user_action, computer_action) if result == GameResults.Draw: print("Player and computer pick {}. Draw".format(user_action.name)) elif result == GameResults.Win: print("Player picks {}, computer picks {}. {}. Player wins!".format( user_action.name, computer_action.name, rule)) else: print("Player picks {}, computer picks {}. {}. Computer wins.".format( user_action.name, computer_action.name, rule)) if input("\nAnother round? (y/n): ").upper() != "Y": break history.append(user_action) if __name__ == "__main__": main()Adding lizard and Spock is easy with the right infrastructure.
import random from enum import IntEnum class GameResults(IntEnum): Win = 0 Lose = 1 Draw = 2 class GameAction(IntEnum): Piedra = 0 Papel = 1 Tijeras = 2 Lagarto = 3 Spock = 4 def __str__(self): """Return str more suited for program.""" return f"{self.name}[{self.value}]" winning_results = { (GameAction.Tijeras, GameAction.Papel) : "Tijeras cuts Papel", (GameAction.Papel, GameAction.Piedra) : "Papel covers piedra", (GameAction.Piedra, GameAction.Lagarto) : "Piedra crushes lagarto", (GameAction.Lagarto, GameAction.Spock) : "Lagarto poisons Spock", (GameAction.Spock, GameAction.Tijeras) : "Spock smashes tijeras", (GameAction.Tijeras, GameAction.Lagarto) : "Tijeras decapitates lagarto", (GameAction.Lagarto, GameAction.Papel) : "Lagarto eats papel", (GameAction.Papel, GameAction.Spock) : "Papel disproves Spock", (GameAction.Spock, GameAction.Piedra) : "Spock vaporizes piedra", (): "\nand as it always has\n", (GameAction.Piedra, GameAction.Tijeras) : "Piedra smashes tijeras", def get_user_action(): """Get user selection""" prompt = f"""\nPick {", ".join([str(action) for action in GameAction])}: """ while True: try: action = input(prompt) return GameAction(int(action)) except ValueError: print(f"{action} is not a valid choice") def get_computer_action(history=[]): """Get computer selection. Use history to predict what user will do.""" user_action = random.choice(history + list(GameAction)) computer_actions = [action for action in list(GameAction) if (action, user_action) in winning_results] return random.choice(computer_actions) def assess_game(user_action, computer_action): if user_action == computer_action: return GameResults.Draw, "" if (user_action, computer_action) in winning_results: return GameResults.Win, winning_results[(user_action, computer_action)] return GameResults.Lose, winning_results[(computer_action, user_action)] def main(): """Play a game of rock, paper, scissors""" print("\n".join(["\nRules of the game:\n"] + [rule for rule in winning_results.values()])) history = [] while True: user_action = get_user_action() computer_action = get_computer_action(history) result, rule = assess_game(user_action, computer_action) if result == GameResults.Draw: print("Player and computer pick {}. Draw".format(user_action.name)) elif result == GameResults.Win: print("Player picks {}, computer picks {}. {}. Player wins!".format( user_action.name, computer_action.name, rule)) else: print("Player picks {}, computer picks {}. {}. Computer wins.".format( user_action.name, computer_action.name, rule)) if input("\nAnother round? (y/n): ").upper() != "Y": break history.append(user_action) if __name__ == "__main__": main()