Feb-27-2022, 06:08 PM
(This post was last modified: Feb-27-2022, 06:09 PM by deanhystad.)
Write the algorithm and post it here. Don't worry about what you partner wrote, just focus on what needs to be done to pick a move that beats the most common move made by the opponent.
After doing that, convert it to Python and write a standalone test program to verify it works. Something like this:
For entertainment purposes the program below plays Rock, Paper, Scissors, Lizard, Spock using a history based AI. It can also play Rock, Paper, Scissors or any other similarly constructed game based on rules you provide. Notice the lack of aggravating enumerated types and rediculously long function and variable names.
After doing that, convert it to Python and write a standalone test program to verify it works. Something like this:
def get_winning_move(history): # your code goes here return selected_move print(get_winning_move([1, 1, 1, 0, 0]), "should be 2: scissors") print(get_winning_move([1, 2, 1, 2, 0]), "should be 0: rock") print(get_winning_move([1, 0, 2, 0, 0]), "should be 1: paper")Once you have that working it should be easier to see how this code can be integrated with the existing code.
For entertainment purposes the program below plays Rock, Paper, Scissors, Lizard, Spock using a history based AI. It can also play Rock, Paper, Scissors or any other similarly constructed game based on rules you provide. Notice the lack of aggravating enumerated types and rediculously long function and variable names.
""" Rock-Paper-Scissors like rule based game creator.""" import random class Player: """A human player. Human players enter play by typing in a one letter abbreviation""" def __init__(self, plays, name=None): self.name = "Player" if name is None else name self.abbr = {play.abbr:play for play in plays.values()} prefix = "Select" if name is None else f"{name} select" self.prompt = f"{prefix} {', '.join([play.menu_name for play in plays.values()])}: " def choice(self, _): """Get player choice""" while True: abbr = input(self.prompt).upper() if abbr in self.abbr: return self.abbr[abbr] print(f"{abbr} is not a valid selection") class Computer: """A computer player. The computer's choice is based on opponent's move history""" def __init__(self, plays, name="Computer"): self.name = name self.plays = plays self.play_names = list(plays.keys()) def choice(self, history=[]): """Predict what opponent will do based on history. Select move that defeats predicted move""" opp_choice = self.plays[random.choice(self.play_names + history)] winning_plays = [play for play in self.plays.values() if play.beats(opp_choice)] return random.choice(winning_plays) class Play: """A play in a Rock/Paper/Scissor type game""" def __init__(self, name, plays): self.rules = {} self.name = name self.key = name.upper() # Pick a unique abbreviation for player selection abbr = [play.abbr.upper() for play in plays.values()] for index, self.abbr in enumerate(self.key): if self.abbr not in abbr: break self.menu_name = name.replace(name[index], f"({name[index]})", 1) def add_rule(self, loser, rule): """Tell me how I beat other moves""" self.rules[loser.upper()] = rule def beats(self, other): """Return rule if I beat other, else None""" return self.rules.get(other.key, None) class Game: """ Create a Rock/Paper/Scissor type game based on a list of rules in the form: MOVE_A defeats MOVE_B """ def __init__(self, rules): # Create plays. Rules start and end with a play name. self.plays = {} for rule in rules: words = rule.split() winner = words[0] loser = words[-1] key = winner.upper() # Make case insensitive if key not in self.plays: self.plays[key] = Play(winner, self.plays) self.plays[key].add_rule(loser, rule) def play(self, rounds=-1, p1=None, p2=None): """Play the game. Use rounds to set how many rounds are played. if < 0, play til someone wins Use p1 to set player 1 name. If None, player name is "Player". Use p2 to set select player 2 type. If None, player 2 is Computer, else Player(p1)""" player = [Player(self.plays, p1), Computer(self.plays) if p2 is None else Player(self.plays, p2)] results = { player[0].name: 0, player[1].name: 0, "Draw":0 } history = [] # Play game while rounds != 0: rounds -= 1 play = [p.choice(history) for p in player] history.append(play[0].key) # TBD: Change to only record player[0] wins? if play[0] == play[1]: results["Draw"] += 1 print("Both player select {play[0].name. Draw.\n") else: winner, rule = 0, play[0].beats(play[1]) if rule is None: winner, rule = 1, play[1].beats(play[0]) results[player[winner].name] += 1 print( f"{player[0].name} selects {play[0].name}, " f"{player[1].name} selects {play[1].name}. " f"{rule}. {player[winner].name} wins!\n") if rounds < 0: return # Game was play until winner print("\nResults") for name, count in results.items(): print(f"{name:10} : {count}") # Single player Rock/Paper/Scissors/Lizard/Spock game Game([ "Rock crushes scissors", "Rock crushes lizard", "Paper covers rock", "Paper disproves Spock", "Scissors cuts paper", "Scissors decapitates lizard", "Lizard eats paper", "Lizard poisons Spock", "Spock smashes scissors", "Spock vaporizes Rock", ]).play(-1) # Bert and Ernie play Rock/Paper/Scissors 3 times # Game(["Rock crushes scissors", "Paper covers rock", "Scissors cuts Paper"]).play(3, "Bert", "Ernie")