1 The Problem
We want to play rock-paper-scissors against the computer: you pick, the computer picks randomly, and the program decides who won — keeping score across rounds. It teaches how to encode the rules of a game as code and compare two choices.
2 How to Think About It
Think about how to decide a winner, before any code:
3 The Build — explained part by part
Here is the complete game. Each part is explained below.
import random
choices = ["rock", "paper", "scissors"]
# What each choice beats.
beats = {"rock": "scissors", "scissors": "paper", "paper": "rock"}
player_score = 0
computer_score = 0
while True:
player = input("rock, paper, scissors (or quit): ").lower()
if player == "quit":
break
if player not in choices:
print("Please choose rock, paper, or scissors.")
continue
computer = random.choice(choices)
print(f"Computer chose {computer}.")
if player == computer:
print("Tie!")
elif beats[player] == computer:
print("You win!")
player_score += 1
else:
print("Computer wins!")
computer_score += 1
print(f"Score - You: {player_score}, Computer: {computer_score}")
player = input(...).lower() — read the player’s choice and lowercase it so “Rock” and “rock” both work.
if player not in choices: continue — if they typed something invalid, skip the rest and ask again.
computer = random.choice(choices) — the computer picks one of the three at random.
elif beats[player] == computer: — the heart of it: look up what the player’s choice beats; if that equals the computer’s choice, the player wins. Otherwise (not a tie, not a win) the computer wins.
beats) and compare — far cleaner..lower() — then “Rock” is treated as invalid.if player not in choices and ask again.4 Test & Prove Each Part
We test the winner logic for every combination — the rules must be exactly right.
BEATS = {"rock": "scissors", "scissors": "paper", "paper": "rock"}
def winner(player, computer):
"""Return 'player', 'computer', or 'tie'."""
if player == computer:
return "tie"
if BEATS[player] == computer:
return "player"
return "computer"
def test_rock_beats_scissors():
"""Rock beats scissors."""
assert winner("rock", "scissors") == "player"
def test_tie():
"""Same choice is a tie."""
assert winner("paper", "paper") == "tie"
def test_paper_loses_to_scissors():
"""Paper loses to scissors."""
assert winner("paper", "scissors") == "computer"
Run with pytest -v. Because the rules live in the BEATS dictionary and one winner function, we can test every outcome cleanly and trust the game is fair.
5 The Interface
What it expects
rock, paper, scissors (or quit): rockWhat it returns
Computer chose scissors.
You win!
Score - You: 1, Computer: 06 Run It & Automate It
python3 rps.pyType your choice each round; type quit to stop.
Jenkins runs the tests automatically — each line explained below.
rock, paper, scissors (or quit): rock
Computer chose scissors.
You win!
Score - You: 1, Computer: 0KeyError when you type your choice..lower().beats dictionary maps each choice to what it DEFEATS, not what beats it.// Jenkinsfile — automated tests on every change.
pipeline {
agent any
stages {
stage('Get the code') { steps { checkout scm } } // download the code
stage('Install') { steps { sh 'python3 -m venv venv && . venv/bin/activate && pip install pytest' } } // test tool
stage('Test') { steps { sh '. venv/bin/activate && pytest -v' } } // run every test
}
post {
success { echo 'All tests passed.' }
failure { echo 'A test failed — look above.' }
}
}
- Best of five. End the game when someone reaches 3 wins. (Teaches: a win condition.)
- Add lizard and Spock. Extend the rules dictionary. (Teaches: scaling data-driven rules.)
- Track stats. Show win percentage at the end. (Teaches: maths on results.)
continue, and track score across rounds. Encoding rules cleanly is what keeps game and business logic maintainable. Related: random, Control Flow.