Robert Johns | 06 Feb, 2025
Fact checked by Jim Markus

Build a Rock Paper Scissors Game in Python (Step-by-Step Guide)

Want to improve your Python skills while building a fun project? This tutorial will guide you through creating a Rock Paper Scissors game using Python!

By the end, you’ll have a working game where the user plays against the computer in an interactive, score-tracking version of Rock Paper Scissors.

This beginner-friendly project covers essential programming concepts, including:

- Using the random module to simulate a computer opponent
- Handling user input validation using regular expressions
- Working with loops and conditional statements
- Keeping track of the score and allowing replay

Let’s dive in!

Step 1: Setting Up the Project

Before we start coding, let’s set up our Python project:

1. Make sure Python is installed on your computer. If not, download it from the official Python website.
2. Open your favorite code editor or IDE.
3. Create a new Python file, for example, rock_paper_scissors.py.

Great, now, let's dive head first into our Python editor to get this build started.

Step 2: Understanding How the Game Works

The Rock Paper Scissors game follows these rules:

  • The user chooses Rock (R), Paper (P), or Scissors (S).
  • The computer randomly selects one of the three options.
  • The game determines the winner based on these conditions:
    • Rock beats Scissors 🪨✂️
    • Scissors beats Paper ✂️📄
    • Paper beats Rock 📄🪨
  • The game tracks the score and asks if the user wants to play again.

Now, let’s start coding in Python!

Step 3: Importing Required Modules

We need three Python modules for this project:

import random  # For generating random choices
import os  # To clear the screen between rounds
import re  # For validating user input

Why Do We Use These Modules?

  • random: Python random allows the computer to randomly select Rock, Paper, or Scissors.
  • os: Clears the terminal screen after each round for better readability.
  • re: Helps us validate user input using regular expressions (regex).

Step 4: Asking the User If They Want to Play Again

At the end of each round, we’ll ask the user if they want to continue playing.

def check_play_status():
    valid_responses = ['yes', 'no', 'y']
    while True:
        try:
            response = input('Do you wish to play again? (Yes or No): ')
            if response.lower() not in valid_responses:
                raise ValueError('Yes or No only')

            if response.lower() in ['yes', 'y']:
                return True
            else:
                os.system('cls' if os.name == 'nt' else 'clear')
                print('Thanks for playing!')
                exit()

        except ValueError as err:
            print(err)

How It Works

  • A list of valid responses (yes, no, y) ensures proper input validation.
  • If the user enters "yes" or "y", the game continues.
  • If they type "no", we clear the screen, display a thank-you message, and exit using exit().
  • If they enter anything else, the function keeps asking until they provide a valid response.

Step 5: Writing the Core Game Logic

Now, let’s write the function that runs the Rock Paper Scissors game.

def play_rps():
    user_score = 0
    computer_score = 0
    play = True

    while play:
        os.system('cls' if os.name == 'nt' else 'clear')
        print('')
        print('Rock, Paper, Scissors - Shoot!')

        user_choice = input('Choose your weapon [R]ock, [P]aper, or [S]cissors: ')

        # Validate input using regex
        if not re.match("^[RrPpSs]$", user_choice):
            print('Invalid choice! Please choose: [R]ock, [P]aper, or [S]cissors.')
            continue

        print(f'You chose: {user_choice.upper()}')

        choices = ['R', 'P', 'S']
        opp_choice = random.choice(choices)

        print(f'I chose: {opp_choice}')

        # Determine the winner
        if opp_choice == user_choice.upper():
            print('It\'s a Tie!')
        elif (opp_choice == 'R' and user_choice.upper() == 'S') or \
             (opp_choice == 'S' and user_choice.upper() == 'P') or \
             (opp_choice == 'P' and user_choice.upper() == 'R'):
            print(f'{opp_choice} beats {user_choice.upper()}, I win!')
            computer_score += 1
        else:
            print(f'{user_choice.upper()} beats {opp_choice}, You win!')
            user_score += 1

        print(f'Score - You: {user_score}, Computer: {computer_score}')
        play = check_play_status()

How It Works

  • The game runs in a loop (while play:) until the player decides to stop.
  • The screen clears at the beginning of each round for a clean look.
  • Regular expressions (re.match()) ensure valid input (only R, P, or S).
  • The computer randomly picks Rock, Paper, or Scissors.
  • The game uses if-elif-else conditions to determine the winner and update scores.
  • The user can play again or exit after each round.

The core functionality of our Rock Paper Scissors game is handled in the play_rps() function.

It does three main things:
- Takes user input and validates it.
- Uses the random module to let the computer make a choice.
- Compares choices using if-elif-else statements to determine the winner.

Using a while Loop for Continuous Gameplay

The game runs in a while loop to let the user play multiple rounds until they choose to quit.

while play:

Why Use a while Loop?

- Keeps the game running until the player exits.
- Allows us to reset the game variables and restart fresh for a new round.
- Improves user experience by making the game interactive.

When the user decides to quit, we set play = False, breaking out of the loop.

Clearing the Screen for a Better User Experience

os.system('cls' if os.name == 'nt' else 'clear')

Why Do We Use This?

  • This command clears the terminal screen between rounds, so old outputs don’t clutter the interface.
  • cls is used for Windows, while clear is used for Linux/macOS.
  • The os.name check ensures that the correct command is used based on the operating system.

Taking and Validating User Input with input() and re.match()

user_choice = input('Choose your weapon [R]ock, [P]aper, or [S]cissors: ')

if not re.match("^[RrPpSs]$", user_choice):
    print('Invalid choice! Please choose: [R]ock, [P]aper, or [S]cissors.')
    continue

Why Use re.match()?

- Ensures the user input is valid (only "R", "P", or "S").
- Uses regular expressions (regex) to check if the input is a single character and belongs to the allowed choices.
- If the user enters anything invalid, the game displays an error message and asks them to try again.

Using random.choice() for Computer’s Move

choices = ['R', 'P', 'S']
opp_choice = random.choice(choices)

Why Use random.choice()?

- Generates a truly random selection between Rock, Paper, and Scissors.
- Eliminates predictability, making the game more realistic.

Instead of writing multiple conditions, random.choice() simplifies the code by picking from a list.

Using if-elif-else to Determine the Winner

if opp_choice == user_choice.upper():
    print('It\'s a Tie!')
elif (opp_choice == 'R' and user_choice.upper() == 'S') or \
     (opp_choice == 'S' and user_choice.upper() == 'P') or \
     (opp_choice == 'P' and user_choice.upper() == 'R'):
    print(f'{opp_choice} beats {user_choice.upper()}, I win!')
    computer_score += 1
else:
    print(f'{user_choice.upper()} beats {opp_choice}, You win!')
    user_score += 1

How Does This Work?

First, we check for a tie:

  • If both choices are the same (opp_choice == user_choice.upper()), we print "It's a Tie!".

Then, we check for a computer win:

  • We list out all losing conditions for the player using logical OR (or).

Else, the player wins:

  • If neither of the above conditions are met, the user wins by default.

Why Use or Statements?

- Easier to read and modify instead of multiple if conditions.
- Explicitly states all losing conditions in one line.

Keeping Score Between Rounds

print(f'Score - You: {user_score}, Computer: {computer_score}')

Each time a player wins, we increment their score.

  • computer_score += 1 → Adds 1 to the computer’s score if the player loses.
  • user_score += 1 → Adds 1 to the user’s score if they win.

This f-string ensures that the score is updated correctly between rounds.

Step 6: Running the Game

Finally, we use this simple but powerful line to control when the game starts:

if __name__ == '__main__':
    play_rps()

Why Is This Needed?

Python sets a special variable called __name__ when a script is run.

  • If the script is executed directly, __name__ is set to "__main__", so play_rps() runs.
  • If the script is imported as a module, __name__ is set to the module’s name, and play_rps() does not run automatically.

Why Is This Best Practice?

- Allows the game to run only when intended.
- Prevents automatic execution if imported into another script.
- Makes the code modular and reusable for future projects.

Final Code: Rock Paper Scissors Game

import random
import os
import re

def check_play_status():
    valid_responses = ['yes', 'no', 'y']
    while True:
        try:
            response = input('Do you wish to play again? (Yes or No): ')
            if response.lower() not in valid_responses:
                raise ValueError('Yes or No only')

            if response.lower() in ['yes', 'y']:
                return True
            else:
                os.system('cls' if os.name == 'nt' else 'clear')
                print('Thanks for playing!')
                exit()

        except ValueError as err:
            print(err)

def play_rps():
    user_score = 0
    computer_score = 0
    play = True

    while play:
        os.system('cls' if os.name == 'nt' else 'clear')
        print('\nRock, Paper, Scissors - Shoot!')

        user_choice = input('Choose your weapon [R]ock, [P]aper, or [S]cissors: ')

        if not re.match("^[RrPpSs]$", user_choice):
            print('Invalid choice! Try again.')
            continue

        print(f'You chose: {user_choice.upper()}')
        choices = ['R', 'P', 'S']
        opp_choice = random.choice(choices)
        print(f'I chose: {opp_choice}')

        if opp_choice == user_choice.upper():
            print('It\'s a Tie!')
        elif (opp_choice == 'R' and user_choice.upper() == 'S') or \
             (opp_choice == 'S' and user_choice.upper() == 'P') or \
             (opp_choice == 'P' and user_choice.upper() == 'R'):
            print(f'{opp_choice} beats {user_choice.upper()}, I win!')
            computer_score += 1
        else:
            print(f'{user_choice.upper()} beats {opp_choice}, You win!')
            user_score += 1

        print(f'Score - You: {user_score}, Computer: {computer_score}')
        play = check_play_status()

if __name__ == '__main__':
    play_rps()

Wrapping Up

Congratulations! You’ve built a complete Rock Paper Scissors game in Python!

This project helped you practice:
- Using Python’s random module to make decisions
- Loops (while) to keep the game running
- Handling user input validation (re.match())
- Using if-elif-else conditions to determine winners
- Keeping track of scores dynamically
- Following best practices (if __name__ == '__main__')

Next Steps: Enhance Your Game!

- Add an extended best-of-5 mode.
- Include a difficulty setting where the computer picks based on player history.
- Make a graphical version using Tkinter or PyQt.

The best way to learn Python is by building fun projects—so keep experimenting!

By Robert Johns

Technical Editor for Hackr.io | 15+ Years in Python, Java, SQL, C++, C#, JavaScript, Ruby, PHP, .NET, MATLAB, HTML & CSS, and more... 10+ Years in Networking, Cloud, APIs, Linux | 5+ Years in Data Science | 2x PhDs in Structural & Blast Engineering

View all post by the author

Subscribe to our Newsletter for Articles, News, & Jobs.

I accept the Terms and Conditions.

Disclosure: Hackr.io is supported by its audience. When you purchase through links on our site, we may earn an affiliate commission.

In this article

Learn More

Please login to leave comments