Learning Goals
3 minBy the end of this lesson you can:
- Import the
randommodule and userandom.randint()to pick a number. - Map that random number to a "move" using
if/elif/else. - Decide the winner of a round by combining the player's and the computer's moves with
and.
Warm-Up
5 minOver the last three lessons we taught Python to compare, combine, and choose. Today we put all of that together to build a game. But first — Python on its own is too predictable. If we hard-code the computer's move, the player wins every time. We need a way to make Python surprise us.
Think aloud: how could a program pick a different move each time you run it, even though the file never changes?
Python ships with a built-in module called random. A module is a small toolbox of extra helpers — you ask Python to bring the toolbox into your file with import. Once it's imported, you can call random.randint() to roll a virtual die.
New Concept · Meet the random Module
12 minPart 1 · import — bring in a toolbox
The very first line of a file that uses random numbers is:
import random
That tells Python "go fetch the random toolbox so I can use its helpers". You only write it once, at the top of the file. Forgetting import random is the #1 reason beginners get a NameError: name 'random' is not defined.
Part 2 · random.randint() — roll a virtual die
random.randint(low, high) gives back a whole number between low and high, inclusive on both ends.
import random roll = random.randint(1, 6) print(roll)
Run the program again and you'll usually get a different number — that's the point. Notice the dot: random.randint means "the randint tool that lives inside the random toolbox".
Part 3 · From a number to a "move"
For Rock, Paper, Scissors we want one of three options. Roll a 1-to-3, then map the number to a string using if / elif / else — the exact pattern from PY-L1-08.
import random n = random.randint(1, 3) if n == 1: computer = "rock" elif n == 2: computer = "paper" else: computer = "scissors" print("Computer chose:", computer)
Part 4 · The rules of the game
Rock blunts scissors. Scissors cut paper. Paper wraps rock. Anything else, and someone loses or it's a tie. That's three "you win" cases — and they each need two things to be true at once: your move and the computer's. That's our and from last lesson, doing real work.
player_wins = (player == "rock" and computer == "scissors") \ or (player == "paper" and computer == "rock") \ or (player == "scissors" and computer == "paper")
The \ at the end of a line just means "this line continues on the next one". We use it here so the Boolean reads top-to-bottom like a little rulebook. (You could also write it as one long line — both work.)
Worked Example · Build the Game
12 minWe'll grow this game in four small phases. Type each phase, run it, then bolt on the next bit. Save the file as rps.py.
Phase 1 · Ask the player
Code
# rps.py — Rock, Paper, Scissors (Phase 1 of 4) player = input("rock, paper or scissors? ") print("You chose:", player)
Run it. Type rock. The program should reply You chose: rock. Nothing clever yet — just an echo.
Phase 2 · Let the computer pick
Code
# rps.py — Rock, Paper, Scissors (Phase 2 of 4) import random player = input("rock, paper or scissors? ") n = random.randint(1, 3) if n == 1: computer = "rock" elif n == 2: computer = "paper" else: computer = "scissors" print("You chose: ", player) print("Computer chose:", computer)
Run it three times. The computer's move should change. If it doesn't, double-check that import random is at the top.
Phase 3 · Decide the result
Code (add after Phase 2's last print)
tie = player == computer player_wins = (player == "rock" and computer == "scissors") \ or (player == "paper" and computer == "rock") \ or (player == "scissors" and computer == "paper") print() if tie: print("🤝 It's a tie!") elif player_wins: print("🎉 You win!") else: print("🤖 Computer wins!")
Run it a few times. Try every move. Make sure tying with the computer prints the tie message and not "computer wins".
Phase 4 · Be a little friendlier
Finally, add a personality. The computer can taunt or congratulate the player with one extra print() depending on the result.
Full file
# rps.py — Rock, Paper, Scissors (Phase 4 of 4) import random name = input("What's your name? ") player = input("rock, paper or scissors? ") # Computer rolls a 1-2-3 and maps it to a move n = random.randint(1, 3) if n == 1: computer = "rock" elif n == 2: computer = "paper" else: computer = "scissors" # Decide the result with Booleans tie = player == computer player_wins = (player == "rock" and computer == "scissors") \ or (player == "paper" and computer == "rock") \ or (player == "scissors" and computer == "paper") # Show the moves print() print(name + " chose: ", player) print("Computer chose:", computer) print() # Pick a final message if tie: print("🤝 Same move! Try again next time,", name + ".") elif player_wins: print("🎉 Nice one,", name + " — you beat the computer!") else: print("🤖 The computer wins this round,", name + ".")
One sample run (lines you type are bold):
Output
What's your name? <strong>Aisyah</strong> rock, paper or scissors? <strong>paper</strong> Aisyah chose: paper Computer chose: rock 🎉 Nice one, Aisyah — you beat the computer!
What every earlier lesson contributed
- L1-02 ·
print— showing the moves and result. - L1-03 · variables —
player,computer,n,tie,player_wins. - L1-07 ·
input— asking for the player's move. - L1-08 ·
if/elif/else— mappingnto a move and announcing the result. - L1-09 · Booleans —
tieandplayer_winsas stored Boolean variables. - L1-10 ·
and/or— the three-line winning-rules Boolean.
Try It Yourself · Extend the Game
13 minPick at least two of these and add them to rps.py. Run after each change.
After the computer picks its move, set a second variable computer_emoji using if / elif / else: rock → "🪨", paper → "📄", scissors → "✂️". Print the emoji next to the word.
Hint
if computer == "rock": computer_emoji = "🪨" elif computer == "paper": computer_emoji = "📄" else: computer_emoji = "✂️" print("Computer chose:", computer, computer_emoji)
Right now, if the player types "banana", the game says the computer wins — which feels unfair. Add a Boolean valid_move that is true only when player is one of "rock", "paper" or "scissors". If valid_move is False, print "That's not a real move!" and skip the result block.
Hint
Use or three times:
valid_move = player == "rock" or player == "paper" or player == "scissors" if not valid_move: print("That's not a real move!") else: # ... your existing result logic ...
Some players want an "easy mode" where the computer always picks the same losing move. Ask mode = input("easy or normal? ") at the start. If mode == "easy", set computer = "scissors" directly (skip the random part). Otherwise, do the normal random roll.
Hint
mode = input("easy or normal? ") if mode == "easy": computer = "scissors" else: n = random.randint(1, 3) if n == 1: computer = "rock" elif n == 2: computer = "paper" else: computer = "scissors"
Notice we still need the random roll inside the else branch — only easy mode skips it.
Mini-Challenge · Computer Personality
8 minMake the computer feel like a real opponent by giving it a personality on each run. Add a new mechanic:
- Right after
import random, roll a second random number withrandom.randint(1, 3)and store it inmood. - Map
moodto apersonalitystring usingif/elif/else:1→"cocky"2→"friendly"3→"mysterious"
- At the end of the program, print one extra line based on both
personalityand who won. The cocky computer brags when it wins and pouts when it loses; the friendly one says "well played" either way; the mysterious one prints one line of riddle.
Try to write your tail-end personality block using and to combine the personality with the result. Example: if personality == "cocky" and player_wins:.
Stretch goal. Add a fourth personality, "poetic", that prints a two-line haiku-style closing message. Roll random.randint(1, 4) instead, and add a fourth elif.
Show one possible solution (final block only)
# ... rest of rps.py above ... # Personality roll mood = random.randint(1, 3) if mood == 1: personality = "cocky" elif mood == 2: personality = "friendly" else: personality = "mysterious" # Personality-flavoured sign-off print() if personality == "cocky" and player_wins: print("🤖: Hmph. Lucky shot.") elif personality == "cocky" and not player_wins: print("🤖: Told you I'd win.") elif personality == "friendly": print("🤖: Well played, friend.") else: print("🤖: The next round whispers your name…")
Notice not player_wins covers both "tie" and "computer wins" — that's a tidy use of not. You could also be even more specific with another elif personality == "cocky" and tie: branch if you like.
Recap
3 minOne import random at the top, one random.randint(1, 3) to pick a move, and a handful of if statements knit ten lessons into a tiny game. Every piece you've learned earned its place.
Vocabulary Card
- module
- A toolbox of extra Python helpers. You bring one in with
import. - import
- Loads a module so you can use the tools inside it.
- random.randint(a, b)
- Returns a whole number between
aandb, including both ends. - dot notation
- The pattern
module.tool(), likerandom.randint(1, 3)— "findrandintinsiderandom".
Homework
4 minCreate a new file called coin_toss.py — a one-shot virtual coin toss that lets the player call it.
Rules:
- Ask the player for their
nameand theircall("heads"or"tails"). import randomat the top.- Use
random.randint(1, 2)to roll the coin: 1 →"heads", 2 →"tails". Map it withif/else. - Compute two Booleans:
player_wins = (call == coin)andbad_call = not (call == "heads" or call == "tails"). - Print the coin's result and the appropriate ending: a win line, a lose line, or a polite "that's not a real call" line if
bad_callis true.
Bring coin_toss.py to next class — we'll play in pairs!
Sample · coin_toss.py
# coin_toss.py — call it in the air import random name = input("Your name? ") call = input("Call it — heads or tails? ") # Roll the coin n = random.randint(1, 2) if n == 1: coin = "heads" else: coin = "tails" # Booleans player_wins = call == coin bad_call = not (call == "heads" or call == "tails") # Reveal the result print() print("The coin landed on:", coin) if bad_call: print("That's not a real call,", name + " — please pick heads or tails.") elif player_wins: print("🎉 Nice call,", name + "!") else: print("So close,", name + " — better luck next time.")
Your messages and emojis can vary. The key is player_wins from one comparison, bad_call using not with a parenthesised or, and a branch order that checks bad_call first.