Python Forum
Rock paper scissors in python with "algorithm" - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Rock paper scissors in python with "algorithm" (/thread-36505.html)

Pages: 1 2 3


Rock paper scissors in python with "algorithm" - Agat0 - Feb-26-2022

In the end I was able to do it thanks to what I was looking for through the dictionary of victory made


RE: Rock paper scissors in python with "algorithm" - deanhystad - Feb-26-2022

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



RE: Rock paper scissors in python with "algorithm" - Agat0 - Feb-26-2022

In the end I was able to do it thanks to what I was looking for through the dictionary of victory made


RE: Rock paper scissors in python with "algorithm" - deanhystad - Feb-26-2022

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)



RE: Rock paper scissors in python with "algorithm" - Agat0 - Feb-26-2022

In the end I was able to do it thanks to what I was looking for through the dictionary of victory made


RE: Rock paper scissors in python with "algorithm" - deanhystad - Feb-26-2022

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?


RE: Rock paper scissors in python with "algorithm" - Agat0 - Feb-26-2022

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.


RE: Rock paper scissors in python with "algorithm" - deanhystad - Feb-26-2022

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))



RE: Rock paper scissors in python with "algorithm" - Agat0 - Feb-26-2022

In the end I was able to do it thanks to what I was looking for through the dictionary of victory made


RE: Rock paper scissors in python with "algorithm" - deanhystad - Feb-27-2022

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.