Python Forum

Full Version: Rock paper scissors in python with "algorithm"
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3
In the end I was able to do it thanks to what I was looking for through the dictionary of victory made
You are thinking about this backward. Why do you have a game history? The computer's next action is based on the results of the current game. The computer AI is one line per result. This program should be about 30 lines long. In Pythonny pseudo code:

computer_play = random play
while True:
    get_human_play
    if human wins:
        next_play = human_play + 1
    else if computer wins:
        next_play = human_play - 1
    else:
        next_play = random play
In the end I was able to do it thanks to what I was looking for through the dictionary of victory made
This is a working version:
import random

plays = ("Rock", "Paper", "Scissors")
results = ("Rock smashes scissors", "Paper covers rock", "Scissors cuts paper")

def get_player_choice():
    while True:
        try:
            return "RPS".index(input("Select (R)ock, (P)aper, (S)cissors: ").upper()[0])
        except (ValueError, IndexError):
            print("That is not a valid selection.")

computer_choice = random.randint(0,2)
while True:
    player_choice = get_player_choice()
    print(f"Computer picks {plays[computer_choice]}")

    if (computer_choice + 1) % 3 == player_choice:
        print(f"{results[player_choice]}.  Player wins!")
        computer_choice = (player_choice + 1) % 3
    elif (player_choice + 1) % 3 == computer_choice:
        print(f"{results[computer_choice]}.  Computer wins!")
        computer_choice = (player_choice - 1) % 3
    else:
        print("Game is a draw.")
        computer_choice = random.randint(0,2)
In the end I was able to do it thanks to what I was looking for through the dictionary of victory made
I am confused. You didn't write any of this code and all you need to provide is a function that tells you who the winner is and another that randomly selects Rock, Paper or Scissors?
I have written the first code following a documentation, but now they have given me this new one and this code that I have to implement, from this last code I have to create get_winner_action and a get_random_computer_action() because it is the only new thing.
I'm still a little confused because you already have this.
def get_computer_action():
    computer_selection = random.randint(0, len(GameAction) - 1)
    computer_action = GameAction(computer_selection)
    print(f"Computer picked {computer_action.name}.")
How would "get_random_computer_action()" differ? At the very least this should be a very good start.

And get_winner_acction() is going to look a lot like the code the computer uses to pick its next move when the computer wins.
computer_action = GameAction((user_actions_history[-1].value + 1) %
        len(GameAction))
In the end I was able to do it thanks to what I was looking for through the dictionary of victory made
That makes more sense than the previous AI. Your history list now makes sense as you will have to count recent player choices. I would use a Counter dictionary from the Collections library.
import random
from collections import Counter
 
plays = ("Rock", "Paper", "Scissors")
results = ("Rock smashes scissors", "Paper covers rock", "Scissors cuts paper")
history = []

def get_player_choice():
    while True:
        try:
            return "RPS".index(input("Select (R)ock, (P)aper, (S)cissors: ").upper()[0])
        except (ValueError, IndexError):
            print("That is not a valid selection.")
 
while True:
    player_choice = get_player_choice()

    if history:
        # Select a move that beats the most frequent player choice from the history list
        choice_counts = Counter(history).most_common()  # Get counts for each choice
        most_common = choice_counts[0][0]  # Get choice with the highest count
        computer_choice = (most_common+1) % len(plays)
    else:
        computer_choice = random.randint(0,2)
    print(f"Computer picks {plays[computer_choice]}")
 
    if (computer_choice + 1) % 3 == player_choice:
        print(f"{results[player_choice]}.  Player wins!")
    elif (player_choice + 1) % 3 == computer_choice:
        print(f"{results[computer_choice]}.  Computer wins!")
    else:
        print("Game is a draw.")
    
    # Keep record of the last 5 player choices
    history.append(player_choice)
    history = history[-5:]
I think the AI is going to be boring to play against. I think basing the computer choice on the player history makes sense, but adding in some randomness will make it less "robotic". It is very easy to do a weighted random choice. The code is actually simpler.
import random
 
plays = ("Rock", "Paper", "Scissors")
results = ("Rock smashes scissors", "Paper covers rock", "Scissors cuts paper")
history = []

def get_player_choice():
    while True:
        try:
            return "RPS".index(input("Select (R)ock, (P)aper, (S)cissors: ").upper()[0])
        except (ValueError, IndexError):
            print("That is not a valid selection.")
 
while True:
    player_choice = get_player_choice()

    # Use history to predict what the player might do.
    # User choices add "weight" to which play is randomly selected by the computer
    weighted_choice = random.choice(history + [0, 1, 2])  # What the player is likely to do
    computer_choice = (weighted_choice+1) % len(plays)  # How I can beat that
    print(f"Computer picks {plays[computer_choice]}")
 
    if (computer_choice + 1) % 3 == player_choice:
        print(f"{results[player_choice]}.  Player wins!")
    elif (player_choice + 1) % 3 == computer_choice:
        print(f"{results[computer_choice]}.  Computer wins!")
    else:
        print("Game is a draw.")
    
    # Keep record of the last 5 player choices
    history.append(player_choice)
    history = history[-5:]
Randomly choosing a play from the player history gives you a weighted random choice. The more often a choice appears in the history list the more likely it is picked, but there is still the possibility of randomly choosing something else. To make anything possible I add [0, 1, 2] to the history values so the computer can select anything. This has a nice side-benefit of not needing special code for the case where history is empty.
Pages: 1 2 3