Day 003 of the 100 Days of Python challenge is a command-line Rock Paper Scissors game. The player selects rock, paper, or scissors, and Python randomly chooses an opponent move.
This project introduces two ideas that show up constantly in real programs: the random module for generating unpredictable values, and lists for storing related pieces of data — in this case, three blocks of ASCII art — so they can be looked up by number instead of duplicated in a long chain of if statements.
This guide walks through the complete Day 003 source code, explains how the win/lose/draw logic works, and highlights why the input validation here matters more than it might first appear.
Project Overview
The game maps the three choices to numbers:
0for rock1for paper2for scissors
A list stores the ASCII illustrations for those choices, indexed in the same order. After converting valid input to an integer, the program displays both selections and compares them.
Source Code
The Day 003 project is contained in day003/main.py in the 100daysofpython repository:
import random
def main():
rock = """
______
---' ___)
(____)
(____)
(____)
---._(___)
"""
paper = """
__
/ )
---'' /_______
_________)
__________)
_________)
---.___________)
"""
scissors = """
______
---' ____)___
______)
__________)
(____)
---.__(___)
"""
game_images = [rock, paper, scissors]
print("Welcome to the Rock, Paper, Scissors Game!\n")
print("Type a number to play the game. If you type an invalid number or character, you lose!\n")
print("Rock = 0\nPaper = 1\nScissors = 2\n")
user_choice = input("What do you choose? ")
if user_choice.isdigit() and int(user_choice) in [0, 1, 2]:
user_choice = int(user_choice)
print(game_images[int(user_choice)])
computer_choice = random.randint(0, 2)
print(f"Computer chose: {game_images[computer_choice]}")
if user_choice == 0 and computer_choice == 2:
print("You win!")
elif user_choice == 1 and computer_choice == 0:
print("You win!")
elif user_choice == 2 and computer_choice == 1:
print("You win!")
elif user_choice == computer_choice:
print("It's a draw!")
else:
print("You lose!")
else:
print("You typed an invalid number or character. You lose!")
if __name__ == "__main__":
main()
How the Program Works
Storing Related Data in a List
game_images = [rock, paper, scissors]
Because rock, paper, and scissors are stored in a list in the same order as their number mapping, the program can look up the right ASCII art with game_images[user_choice] instead of writing a separate if statement for each option. This is one of the simplest, most useful patterns in Python: when data lines up with a set of numbered options, a list plus indexing is usually cleaner than a long chain of conditionals.
Validating Input Before Using It
if user_choice.isdigit() and int(user_choice) in [0, 1, 2]:
This line does two checks at once:
user_choice.isdigit()confirms the input contains only digits, so converting it withint()won’t crash the program.int(user_choice) in [0, 1, 2]confirms the number is actually one of the valid choices.
Without this check, typing a letter would crash int(user_choice) with a ValueError, and typing a number like 9 would crash game_images[9] with an IndexError — the list only has three items, indexed 0 through 2. Validating input before using it is exactly what prevents both of those crashes.
Generating the Computer’s Move
computer_choice = random.randint(0, 2)
random.randint(0, 2) returns a random whole number between 0 and 2, inclusive — matching the same 0/1/2 mapping used for the player’s choice, so both sides of the comparison use identical values.
Comparing the Two Choices
if user_choice == 0 and computer_choice == 2:
print("You win!")
elif user_choice == 1 and computer_choice == 0:
print("You win!")
elif user_choice == 2 and computer_choice == 1:
print("You win!")
elif user_choice == computer_choice:
print("It's a draw!")
else:
print("You lose!")
Each winning condition checks one specific matchup: rock (0) beats scissors (2), paper (1) beats rock (0), and scissors (2) beats paper (1). Because a draw is checked explicitly before the final else, every other remaining combination safely falls through to “You lose!” without needing to spell out each losing matchup individually.
What This Project Teaches
Day 003 provides practice with:
- Importing and using the
randommodule - Storing related data in a list and accessing it by index
- Validating user input before converting or using it
- Expressing game rules with a chain of
if/elif/elseconditions - Using ASCII art to improve a terminal program’s feedback
Running the Project
git clone https://github.com/victorhugo81/100daysofpython.git
cd 100daysofpython/day003
python main.py
Possible Next Steps
Once you understand the existing code, try extending it:
- Track and print a running score across multiple rounds instead of exiting after one
- Let the player type
rock,paper, orscissorsinstead of only accepting numbers - Refactor the winning conditions into a single rule, such as checking
(user_choice - computer_choice) % 3 == 1 - Add a “best of 5” mode using a loop
Conclusion
Day 003 of the 100 Days of Python challenge combines the random module, list indexing, and input validation into a small but complete game. The input validation is easy to overlook, but it’s exactly what keeps the program from crashing on bad input — a habit worth carrying into every project from here on.
View the Day 003 source code on GitHub, then continue through the repository’s project index as you build more Python programs, one day and one small project at a time.
