-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
63: Practice Exercise: Building a Rock-Paper-Scissors Game
I've reviewed a lot of beginner code for Rock-Paper-Scissors, and almost everyone starts the same way: they build a "Wall of Ifs." They try to explicitly map out every single possible combination of choices. It looks something like this:
if user == "rock" and computer == "scissors":
print("You win!")
elif user == "rock" and computer == "paper":
print("You lose!")
elif user == "paper" and computer == "rock":
print("You win!")
# ... and so on for 9 different combinations
The "Wall of Ifs" Approach
Technically, the code above works. But as a software engineer, I can tell you that this is a dangerous habit. Why? Because it's brittle. If you decided to upgrade this to "Rock-Paper-Scissors-Lizard-Spock," you'd be writing dozens of `elif` statements. You'd likely miss one or make a typo, and suddenly your game has a bug where Paper beats Rock, but Rock somehow beats Paper too.
Simplifying the Win-Loss Logic
The trick to writing clean logic is to eliminate the obvious cases first. In this game, the most obvious case is a tie. If the user and the computer pick the same thing, nobody wins. By handling that first, we immediately cut our remaining logic in half.
From there, instead of mapping every combination, just map the conditions where the user wins. If it's not a tie, and the user didn't win, then by process of elimination, the computer must have won. I usually write it like this:
if user == computer:
print("It's a tie!")
elif (user == "rock" and computer == "scissors") or \
(user == "paper" and computer == "rock") or \
(user == "scissors" and computer == "paper"):
print("You win!")
else:
print("You lose!")
Notice how much breathe-room the code has now. We've gone from nine potential branches down to three. It's easier to read, and if I want to change the rules, I only have to look at one line of code rather than scrolling through a massive list of `elif` blocks.
Tying it Together with Randomness
To make this a real game, you'll need the random module. I recommend putting your options in a list. This allows you to use random.choice(), which is much cleaner than generating a random integer and mapping it to an index manually. I've found that using a list makes it trivial to add new options to the game later—you just add a string to the list, and the computer automatically knows how to pick it.
One last tip: always remember to .lower() your user input. There is nothing more frustrating for a player than losing a game just because they typed "Rock" with a capital R and your code was looking for "rock".
📋 Practical Task
Build the Rock-Paper-Scissors Battle Engine
Your task is to build a fully functional Rock-Paper-Scissors game. However, to make this a proper "engine," you need to implement a game loop that allows the player to play multiple rounds without restarting the script.
Requirements:
- Use
random.choice()to determine the computer's move. - Handle user input case-insensitively (e.g., "ROCK", "rock", and "Rock" should all be valid).
- Implement the simplified logic we discussed: handle the tie first, then the win conditions, then the loss.
- Wrap the game in a
whileloop. After each round, ask the user if they want to play again (y/n). - Keep a running tally of the score (User wins vs. Computer wins) and display the final score when the user chooses to quit.
There are no comments for now.