Pokédex Game Script: Comprehensive Project Documentation
1. Introduction
This document provides an in-depth analysis and comprehensive documentation
of a text-based Pokémon catching game implemented in Python. The game
allows users to simulate the experience of encountering and catching Pokémon,
managing their collection, and saving progress. This documentation covers the
project’s aim, design, implementation, challenges, and future work, providing
code snippets and detailed explanations throughout.
The game is built as a command-line interface program, leveraging Python's
standard libraries to handle randomness, timing, file input/output, and program
control. It serves both as an educational tool for beginners to programming and
as an engaging, interactive experience for Pokémon enthusiasts.
2. Project Aim and Real-World Relevance
Project Aim
The primary aim of this project is to create an interactive and educational
Pokémon simulation that introduces users to core programming concepts such
as:
Random number generation and probability
File handling for data persistence
User input handling and validation
Basic game loop and state management
By simulating Pokémon encounters and catch attempts, the project also fosters
logical thinking and decision-making skills.
Real-World Relevance
While the game is simple, its principles are applicable to many real-world
software development scenarios:
Game Development: The project introduces fundamental game
mechanics such as random events and user interaction loops.
Data Persistence: Managing save files mirrors real-world applications
where user data must be saved and loaded.
Probability and Statistics: The catch mechanics demonstrate practical
use of probability in user-facing applications.
User Experience Design: Designing clear prompts and feedback
enhances usability, a crucial aspect in software development.
Such a project also offers a hands-on approach for beginners to grasp
fundamental programming concepts before moving to more complex systems.
3. Team Collaboration and Project Timeline
This project was designed as an individual endeavor, ideal for self-study or
educational coursework. However, if expanded into a team project, the
following collaboration approach is recommended:
Planning Phase (Week 1):
o Define project scope and requirements.
o Assign roles such as lead developer, UI designer, and tester.
Development Phase (Weeks 2-4):
o Implement core functionalities (loading Pokémon data, catching
mechanics).
o Develop user interface and input handling.
o Create saving/loading mechanisms.
Testing and Debugging (Week 5):
o Conduct unit and integration testing.
o Fix bugs and improve usability.
Documentation and Presentation (Week 6):
o Prepare detailed documentation.
o Present and demonstrate the project.
Using version control systems (e.g., Git) would facilitate code sharing and
collaboration.
4. Project Requirements and Scope
Functional Requirements
Load Pokémon Data: Load a complete list of Pokémon from a file.
Save/Load Player Progress: Ability to save and load caught Pokémon.
Catch Pokémon: Encounter random wild Pokémon and attempt to catch
them with limited attempts.
Display Owned Pokémon: Show the player's caught Pokémon.
Display Pokédex: Show unique Pokémon caught and progress.
Save Progress: Write the current state to files.
Non-Functional Requirements
Usability: Clear prompts and input validation.
Reliability: Proper error handling for file operations.
Performance: Responsive input and game flow without unnecessary
delays.
Portability: Runs on any system with Python installed.
Scope Limitations
The game is text-based; no graphical interface.
Catch probability is fixed at 33%.
Pokémon data is static and loaded from a file.
No multiplayer or networking features.
5. Software and Tools Used
Python 3.x: Chosen for its readability and ease of use for beginners.
Standard Python Libraries:
o random: To simulate randomness in Pokémon encounters and catch
attempts.
o time: To manage delays between encounters for pacing.
o sys: To handle graceful program exits.
Text Editor / IDE: Any Python-supporting editor (e.g., VSCode,
PyCharm).
Operating System: Cross-platform (Windows, macOS, Linux).
6. System Design and Architecture
The system architecture follows a procedural programming paradigm, with
clearly defined functions handling discrete tasks. The main components are:
Data Layer: File operations for loading and saving Pokémon data.
Game Logic Layer: Catching mechanics, Pokémon selection,
probability.
User Interface Layer: Command-line prompts and menu navigation.
Control Flow: The main game loop orchestrating encounters and user
choices.
Component Diagram (Conceptual)
+----------------------+
| User Interface |
| (Input/Output Prompts)|
+----------+-----------+
+----------------------+
| Game Logic Layer |
| (Catch Mechanics, |
| Encounter Handling) |
+----------+-----------+
+----------------------+
| Data Layer |
| (Load/Save Files) |
+----------------------+
7. Implementation Details
The project is implemented in a single Python script with modular functions.
Loading Pokémon Data
def load_all_pokemon(filename='[Link]'):
try:
with open(filename, 'r') as file:
return [[Link]().upper() for pokemon in [Link]()]
except FileNotFoundError:
print("Pokemon data file missing!")
[Link]()
Reads the file [Link].
Converts all Pokémon names to uppercase to maintain consistency.
Exits if the file is not found, ensuring the game cannot start without data.
Loading Owned Pokémon
def load_owned_pokemon():
while True:
oldsave = input('Do you have a save file? (y/n): ').lower().strip()
if oldsave == 'n':
print('\nWelcome, new trainer!')
return []
elif oldsave == 'y':
file_path = input('\nEnter your owned_pokemon.txt file path: ').strip()
try:
with open(file_path, 'r') as f:
print('\nWelcome back! Save loaded.\n')
return [[Link]().upper() for line in [Link]()]
except FileNotFoundError:
print('File not found. Try again or start a new game.')
else:
print('Please enter "y" or "n".')
Interactively asks the player if they have a saved game.
Loads the saved Pokémon list or creates a new empty list.
Includes input validation to handle invalid responses.
Catching Pokémon
def catch_pokemon(pokemon, owned_pokemon):
print(f"\nIt's a {pokemon}!\n")
catches_left = 3
while catches_left > 0:
decision = input('Would you like to catch it? (y/n): ').lower().strip()
if decision in ['y', 'yes']:
if [Link](1, 100) <= 33:
if pokemon not in owned_pokemon:
print(f'\n🎉 You caught a NEW Pokémon: {pokemon}!\nAdding it
to the Pokédex...')
else:
print(f'\n✨ You caught another {pokemon}, but it’s already in your
Pokédex.')
owned_pokemon.append(pokemon)
return
else:
catches_left -= 1
print(f'\nIt escaped! {catches_left} Pokéballs left.')
elif decision in ['n', 'no']:
print(f'\nYou let {pokemon} go.')
return
else:
print('\nInvalid input. Please enter "y" or "n".')
print(f'\n{pokemon} got away!')
Player has 3 attempts to catch each Pokémon.
Each attempt has a 33% chance of success.
Provides feedback on success, duplicate catches, or failure.
Input validation ensures only valid responses are accepted.
Viewing Owned Pokémon and Pokédex
def view_owned(owned_pokemon):
if not owned_pokemon:
print("\nYou haven't caught any Pokémon yet.")
else:
print("\n🎒 Owned Pokémon:")
for poke in owned_pokemon:
print('-', poke)
def view_pokedex(owned_pokemon):
pokedex = set(owned_pokemon)
if not pokedex:
print("\nYour Pokédex is empty.")
else:
print(f"\n📘 Pokédex: {len(pokedex)}/721 Pokémon caught")
for poke in sorted(pokedex):
print('-', poke)
view_owned displays all Pokémon caught (including duplicates).
view_pokedex displays unique Pokémon caught with a progress count out
of 721.
Uses Python sets to extract unique entries.
Saving Progress
def update_files(owned_pokemon):
try:
with open('owned_pokemon.txt', 'w') as f:
for p in owned_pokemon:
[Link](p + '\n')
with open('[Link]', 'w') as f:
for p in sorted(set(owned_pokemon)):
[Link](p + '\n')
print("\n✅ Progress saved to 'owned_pokemon.txt' and '[Link]'")
except Exception as e:
print("❌ Error saving files:", e)
Saves all caught Pokémon (including duplicates) in owned_pokemon.txt.
Saves unique Pokémon sorted alphabetically in [Link].
Includes exception handling to catch possible I/O errors.
Main Game Loop
def main():
all_pokemon = load_all_pokemon()
owned_pokemon = load_owned_pokemon()
print("\n🔁 Entering encounter loop...\n")
while True:
print('\nA wild Pokémon has appeared!')
current_pokemon = [Link](all_pokemon)
catch_pokemon(current_pokemon, owned_pokemon)
while True:
print('\nWhat would you like to do next?')
print('[O] View Owned Pokémon')
print('[P] View Pokédex')
print('[U] Update & Save Files')
print('[N] Skip to Next Pokémon')
print('[S] Save & Exit Game\n')
choice = input('Enter your choice: ').lower().strip()
if choice == 'o':
view_owned(owned_pokemon)
elif choice == 'p':
view_pokedex(owned_pokemon)
elif choice == 'u':
update_files(owned_pokemon)
elif choice == 'n':
print('\n...Waiting for the next Pokémon...')
[Link]([Link](3, 6))
break
elif choice == 's':
update_files(owned_pokemon)
print('\n👋 Thanks for playing, trainer!')
[Link]()
else:
print('\nInvalid input. Try again.')
Controls the main gameplay cycle.
Randomly selects Pokémon for encounters.
Offers a menu for managing collection and saving.
Uses delays to simulate natural pacing between encounters.
Allows graceful exit with saving.
8. Game Mechanics and Probability Logic
Random Pokémon Encounter
The game randomly selects a Pokémon from the complete list using:
current_pokemon = [Link](all_pokemon)
This ensures equal probability for all Pokémon, simulating a random encounter.
Catch Probability
Each catch attempt has a fixed 33% chance to succeed, implemented as:
if [Link](1, 100) <= 33:
[Link](1, 100) generates an integer between 1 and 100.
If the result is 33 or less, the catch is successful.
This simple probability model introduces luck and challenge.
Limited Attempts
Players have exactly 3 attempts to catch each Pokémon. This is managed by a
counter:
catches_left = 3
Each failed attempt decrements this count, adding tension and urgency.
Duplicate Catches
Caught Pokémon are always added to the player's collection, including
duplicates:
owned_pokemon.append(pokemon)
However, the Pokédex only counts unique entries using sets.
9. Data Persistence and File Handling
Pokémon Data File
[Link] contains one Pokémon name per line.
The program expects this file in the same directory or a provided path.
Save File Handling
The player’s caught Pokémon are saved in owned_pokemon.txt.
Unique Pokémon for the Pokédex are saved in [Link].
File Operations
Reading uses with open(filename, 'r') as file for safe handling.
Writing uses with open(filename, 'w') as file to overwrite existing files.
Exception handling is implemented to manage missing files or write
errors.
Input Validation
When loading saved data, the program prompts until a valid file path is
provided or the player opts to start a new game.
10. User Interface and User Experience
Command-Line Interface
Text-based prompts guide the player through the game.
Menus are clearly presented with options labeled for easy input.
Feedback messages use emojis and concise language to enhance
engagement.
Input Validation
All user inputs are converted to lowercase and stripped of whitespace.
Invalid inputs trigger friendly error messages and reprompting.
Pacing
Random delays between encounters ([Link]([Link](3, 6)))
simulate natural game flow.
Informative messages keep the player engaged during wait times.
Accessibility
All Pokémon names are displayed in uppercase for clarity.
Menus and prompts are straightforward, suitable for all ages.
11. Challenges Faced and Solutions
Challenge: Handling Missing or Invalid Files
Issue: The game depends on external files; missing files cause crashes.
Solution: Implement try-except blocks to catch FileNotFoundError and
prompt the user accordingly. The game exits gracefully if the main
Pokémon data file is missing.
Challenge: Input Validation
Issue: User inputs can be unpredictable and cause errors.
Solution: Use input normalization ([Link](), [Link]()) and validate
inputs against expected options. Reprompt on invalid entries.
Challenge: Managing Duplicate Pokémon
Issue: Players can catch duplicates, which complicates display and
saving.
Solution: Store all catches but use Python sets to display unique entries
in the Pokédex.
Challenge: Balancing Catch Probability
Issue: Making the game neither too easy nor too frustrating.
Solution: Fixed 33% catch chance with 3 attempts balances luck and
challenge.
12. Learning Outcomes and Skill Development
Through this project, the following skills were developed:
Python Programming: Mastery of functions, loops, conditionals, and
exception handling.
File I/O: Reading from and writing to text files safely.
Randomness and Probability: Implementing chance-based mechanics.
User Interaction: Designing intuitive CLI interfaces and validating
input.
Problem-Solving: Handling errors and edge cases gracefully.
Project Organization: Structuring code into modular, reusable functions.
Patience and Debugging: Iterative testing and fixing issues.
This project serves as a foundation for more complex game development and
software engineering tasks.
13. Ethical Considerations and Academic Integrity
The project is an original work developed for educational purposes.
All Pokémon names used are from the publicly available Pokémon
franchise.
No copyrighted assets (images, sounds) are included.
Proper attribution to the Pokémon franchise is advised if distributed.
Users should respect intellectual property rights when extending or
sharing the project.
Academic integrity is maintained by not plagiarizing code and citing
sources if applicable.
14. Future Work and Possible Enhancements
The current version is a solid foundation with potential for many improvements:
Gameplay Enhancements
Variable Catch Rates: Different Pokémon could have unique catch
probabilities.
Pokéballs and Items: Introduce inventory items to improve catch
chances.
Levels and Experience: Add RPG elements for progression.
Battle Mechanics: Implement battling wild Pokémon or trainers.
Multiple Save Slots: Allow multiple player profiles.
User Interface
Graphical Interface: Use libraries like pygame or tkinter for visuals.
Sound Effects: Add audio feedback for actions.
Improved Menus: More intuitive navigation and help screens.
Data Management
Database Integration: Store data in SQLite or JSON for better structure.
Cloud Saving: Enable online save/load for portability.
Code Refactoring
Object-Oriented Design: Use classes for Pokémon, Player, and Game.
Unit Testing: Add automated tests to ensure reliability.
Modularization: Split code into multiple files for better maintainability.
15. Conclusion
This project successfully creates a simple, interactive Pokémon catching game
that demonstrates important programming concepts. It combines randomness,
user interaction, file handling, and game logic into a cohesive whole.
The code is structured, understandable, and extensible, making it an excellent
learning tool for beginners. While limited in scope, it lays the groundwork for
more advanced game development projects.
By engaging with this project, users gain practical experience and a deeper
appreciation for the considerations involved in software design, user experience,
and data management.
16. References
Python Official Documentation: [Link]
Pokémon Franchise Information: [Link]
Python Random Module: [Link]
Python File Handling:
[Link]
files
PEP 8 — Python Style Guide: [Link]
0008/
Appendix: Key Code Snippets
Loading All Pokémon
def load_all_pokemon(filename='[Link]'):
try:
with open(filename, 'r') as file:
return [[Link]().upper() for pokemon in [Link]()]
except FileNotFoundError:
print("Pokemon data file missing!")
[Link]()
Catching a Pokémon
def catch_pokemon(pokemon, owned_pokemon):
print(f"\nIt's a {pokemon}!\n")
catches_left = 3
while catches_left > 0:
decision = input('Would you like to catch it? (y/n): ').lower().strip()
if decision in ['y', 'yes']:
if [Link](1, 100) <= 33:
if pokemon not in owned_pokemon:
print(f'\n🎉 You caught a NEW Pokémon: {pokemon}!\nAdding it
to the Pokédex...')
else:
print(f'\n✨ You caught another {pokemon}, but it’s already in your
Pokédex.')
owned_pokemon.append(pokemon)
return
else:
catches_left -= 1
print(f'\nIt escaped! {catches_left} Pokéballs left.')
elif decision in ['n', 'no']:
print(f'\nYou let {pokemon} go.')
return
else:
print('\nInvalid input. Please enter "y" or "n".')
print(f'\n{pokemon} got away!')
Main Game Loop
def main():
all_pokemon = load_all_pokemon()
owned_pokemon = load_owned_pokemon()
print("\n🔁 Entering encounter loop...\n")
while True:
print('\nA wild Pokémon has appeared!')
current_pokemon = [Link](all_pokemon)
catch_pokemon(current_pokemon, owned_pokemon)
while True:
print('\nWhat would you like to do next?')
print('[O] View Owned Pokémon')
print('[P] View Pokédex')
print('[U] Update & Save Files')
print('[N] Skip to Next Pokémon')
print('[S] Save & Exit Game\n')
choice = input('Enter your choice: ').lower().strip()
if choice == 'o':
view_owned(owned_pokemon)
elif choice == 'p':
view_pokedex(owned_pokemon)
elif choice == 'u':
update_files(owned_pokemon)
elif choice == 'n':
print('\n...Waiting for the next Pokémon...')
[Link]([Link](3, 6))
break
elif choice == 's':
update_files(owned_pokemon)
print('\n👋 Thanks for playing, trainer!')
[Link]()
else:
print('\nInvalid input. Try again.')
This concludes the comprehensive project documentation for the Pokédex
Game Script.