Simple Rock, Paper, Scissors Game
Introduction:
The Rock Paper Scissors game is a classic hand-based strategy game traditionally
played between two participants. This Python implementation transforms the
physical game into a digital, interactive experience, where the player competes
against a computer opponent in a best-of-five match format.
Key Features
Interactive Terminal-Based Gameplay – Simple text interface for ease of
use.
Randomized Computer Opponent – Uses Python’s random module for fair
play.
Score Tracking System – First player to 5 wins claims victory.
Input Validation – Ensures only valid moves (rock, paper, scissors) are
accepted.
Play-Again Option – Allows replaying full matches without restarting the
program.
Game Rules & Logic
2.1 Traditional Rules
The game follows the standard rules:
- Rock crushes Scissors (Rock wins)
- Scissors cut Paper (Scissors win)
- Paper covers Rock (Paper wins)
- Tie occurs if both players choose the same move.
2.2 Digital Implementation
- This version enhances the game with:
- Best-of-5 Matches: The first to win 5 rounds wins the match.
- Dynamic Score Updates: Displays real-time scores after each round.
- Quit Option ('q'): Allows players to exit mid-game.
3. Technical Implementation
3.1 Core Mechanics
Component Description
User Input Handling Validates player moves and prevents crashes.
Computer AI Uses random.choice() for unbiased decisions.
Win Condition Checker Compares moves and updates scores.
Match Loop Runs until a player reaches 5 wins.
3.2 Code Structure
The game is built using modular functions:
- get_user_choice() – Gets and validates player input.
- get_computer_choice() – Generates a random move for the computer.
- determine_winner() – Decides the winner of each round.
- play_match() – Manages the full best-of-5 match.
- main() – Controls the game loop and restart option.
1. Core Python Components
1.1 Functions
Definition: Reusable blocks of code that perform specific tasks
Usage in Game:
def get_user_choice():
# Gets and validates user input
while True:
user_choice = input("Choose rock, paper, or scissors: ").lower()
if user_choice in ['rock', 'paper', 'scissors']:
return user_choice
print("Invalid choice. Please try again.")
- Purpose: Encapsulate game logic into modular units
- Advantages: Improves code readability and reusability
1.2 Conditional Statements
- Types Used:
if
elif
else
- Game Implementation:
if user_choice == computer_choice:
return "tie"
elif (user_choice == 'rock' and computer_choice == 'scissors') or \
(user_choice == 'paper' and computer_choice == 'rock') or \
(user_choice == 'scissors' and computer_choice == 'paper'):
return "user"
else:
return "computer"
- Purpose: Determine game outcomes based on rules
- Logic Flow: Compares user and computer choices
1.3 Loops
While Loops:
while user_score < 5 and computer_score < 5:
# Game round logic
- Purpose: Continue game until win condition met
- Exit Condition: Either player reaches 5 points
Infinite Loop with Break:
while True:
# Main game loop
play_again = input("Play again? (y/n): ")
if play_again != 'y':
break
2. Python Standard Library Modules
2.1 random Module
Import Statement:
python
Copy
import random
Key Function Used:
python
Copy
random.choice(['rock', 'paper', 'scissors'])
- Purpose: Generate computer's random move
- Behavior: Selects uniformly from options
2.2 Built-in Functions
input():
python
Copy
user_choice = input("Choose rock, paper, or scissors: ")
Purpose: Get player input
String Handling: .lower() for case normalization
print():
print(f"You chose: {user_choice}")
Purpose: Display game information
Formatting: f-strings for variable interpolation
3. Data Structures
3.1 Lists
Usage Examples:
['rock', 'paper', 'scissors'] # Valid choices
Purpose: Store collections of related items
Operations: Membership testing with in keyword
3.2 Dictionaries (Potential Enhancement)
Suggested Use:
win_conditions = {
'rock': 'scissors',
'paper': 'rock',
'scissors': 'paper'
}
Advantage: More maintainable win logic
4. Program Control Flow
4.1 Main Game Loop
def main():
while True: # Outer loop for multiple matches
play_match()
if not play_again():
break
Components:
- Match Loop: play_match() handles individual matches
- Restart Logic: play_again() prompts for continuation
4.2 Function Chaining
mermaid
graph TD
A[main()] --> B[play_match()]
B --> C[get_user_choice()]
B --> D[get_computer_choice()]
B --> E[determine_winner()]
B --> F[update_score()]
- Flow: Hierarchical function calls
- Benefit: Separation of concerns
5. Error Handling
5.1 Input Validation
while True:
choice = input("Your choice: ").lower()
if choice in valid_options:
return choice
print("Invalid input!")
- Mechanism: Infinite loop until valid input
- Robustness: Prevents program crashes
5.2 Potential Enhancements
try:
user_choice = input("Choice: ")
except KeyboardInterrupt:
print("\nGame exited by user")
sys.exit(0)
- Suggested Improvement: Handle forced exits
6. Variable Types and Scope
6.1 Variable Types Used
Strings: Store text data ('rock', 'paper')
- Integers: Track scores (user_score = 0)
- Booleans: Control flow (play_again == 'y')
6.2 Scope Management
Local Variables: Confined to functions
def play_match():
user_score = 0 # Local to function
- Global Avoidance: Prevents side effects
7. String Manipulation
7.1 Key Operations
Case Conversion:
user_choice.lower()
String Formatting:
print(f"Score: {user_score}-{computer_score}")
8. Program Structure Best Practices
8.1 Modular Design
Separation of:
- User input handling
- Game logic
- Display/output
- Benefits:
- Easier debugging
- Simple enhancements
8.2 Entry Point Convention
if __name__ == "__main__":
main()
- Purpose: Prevent execution when imported
- Pythonic Practice: Standard script structure
Code:
import random
def get_user_choice():
"""Get and validate user input"""
while True:
user_choice = input("Choose rock, paper, or scissors (or 'q' to quit): ").lower()
if user_choice in ['rock', 'paper', 'scissors', 'q']:
return user_choice
print("Invalid choice. Please try again.")
def get_computer_choice():
"""Generate random computer choice"""
return random.choice(['rock', 'paper', 'scissors'])
def determine_winner(user, computer):
"""Determine the round winner"""
if user == computer:
return "tie"
elif (user == 'rock' and computer == 'scissors') or \
(user == 'paper' and computer == 'rock') or \
(user == 'scissors' and computer == 'paper'):
return "user"
else:
return "computer"
def play_match():
"""Play a best-of-5 match"""
user_score = 0
computer_score = 0
round_num = 1
print("\n=== New Match (First to 5 wins) ===")
while user_score < 5 and computer_score < 5:
print(f"\n--- Round {round_num} ---")
print(f"Current Score - You: {user_score} | Computer: {computer_score}")
user_choice = get_user_choice()
if user_choice == 'q':
return None
computer_choice = get_computer_choice()
print(f"\nYou chose: {user_choice}")
print(f"Computer chose: {computer_choice}")
result = determine_winner(user_choice, computer_choice)
if result == "tie":
print("It's a tie! No points awarded.")
elif result == "user":
print("You win this round!")
user_score += 1
else:
print("Computer wins this round!")
computer_score += 1
round_num += 1
# Match conclusion
print("\n=== Match Result ===")
print(f"Final Score - You: {user_score} | Computer: {computer_score}")
if user_score == 5:
print("Congratulations! You won the match!")
else:
print("Computer won the match. Better luck next time!")
return True
def main():
"""Main game function"""
print("Welcome to Rock, Paper, Scissors - Best of 5!")
print("--------------------------------------------")
while True:
match_result = play_match()
if match_result is None: # User quit mid-match
print("\nMatch abandoned. Thanks for playing!")
break
play_again = input("\nPlay another full match? (y/n): ").lower()
if play_again != 'y':
print("\nThanks for playing!")
break
if __name__ == "__main__":
main()
OUTPUT:
Conclusion:
This implementation demonstrates proper use of:
- Fundamental Python syntax
- Control structures
- Standard library features
- Program design principles
The game serves as an excellent example of how basic Python components can
combine to create interactive applications while following software engineering
best practices. Each element has been carefully selected to fulfill specific game
requirements while maintaining code clarity and extensibility.