Part 10: The Grand Mission — Capstone Project
The Adventures of Ava the Astronaut: Learning Python One Planet at a Time
Part 10: The Grand Mission — Capstone Project
The Adventures of Ava the Astronaut: Learning Python One Planet at a Time
The Final Challenge
Ava has come a long way. From sending her first “Hello, Universe!” to building an unbreakable console, she has mastered the core language of the cosmos: Python. Her star map, once dark, now blazes with the light of every system she has visited and every skill she has gained.
For her final mission, Py has a special challenge.
“Commander, it is time for you to combine everything you have learned. Your grand mission is to create a program that simulates an entire space adventure. It will require all your skills: variables, decisions, loops, functions, lists, dictionaries, file saving, and error handling. You will build Ava’s Space Adventure: A Text-Based Game.”
A text-based adventure game is a program where the player reads descriptions of locations and types commands to interact with the world. There are no graphics — just your imagination and the power of code. These games were some of the very first computer games ever made, and they are a fantastic way to practice programming!
What We Are Building
Our game will have the following features, each one drawing on a concept from a previous part of this series:
| Feature | Python Concept Used | Part |
|---|---|---|
| Player name and game state | Variables and Data Types | Part 2 |
| Choosing actions and paths | Conditional Statements (if/elif/else) | Part 3 |
| The main game loop | while Loop | Part 4 |
| Organized, reusable code | Functions | Part 5 |
| Player inventory | Lists | Part 6 |
| Game world and room data | Dictionaries | Part 7 |
| Saving and loading progress | File I/O | Part 8 |
| Handling bad player input | Error Handling (try/except) | Part 9 |
The Full Game Code
Here is the complete, working code for the game. It may look long, but every single piece uses something you have already learned. After the code, we will walk through it section by section.
# ============================================================# Ava's Space Adventure: A Text-Based Game# The Grand Mission - Capstone Project# ============================================================
import json # For saving/loading game data to a fileimport os # For checking if a save file exists
# --- FUNCTIONS (Part 5) ---
def show_title_screen(): """Displays the main title screen for the game.""" print("\n" + "=" * 50) print(" AVA'S SPACE ADVENTURE") print(" A Text-Based Game in Python") print("=" * 50) print(" Type 'help' at any time for a list of commands.") print("=" * 50 + "\n")
def save_game(player): """Saves the player's data to a JSON file (Part 8: File I/O).""" try: with open("savegame.json", "w") as f: json.dump(player, f, indent=2) print("\n[Game Saved Successfully!]\n") except IOError: print("\n[Error: Could not save the game.]\n")
def load_game(): """Loads the player's data from a JSON file (Part 8 & 9).""" if not os.path.exists("savegame.json"): return None try: with open("savegame.json", "r") as f: player = json.load(f) print("\n[Game Loaded Successfully!]\n") return player except (IOError, json.JSONDecodeError): print("\n[Error: Save file is corrupted. Starting new game.]\n") return None
def show_status(player, game_map): """Displays the player's current location, description, and inventory.""" room = game_map[player["location"]] print("\n" + "-" * 50) print(f" Location: {player['location']}") print(f" Inventory: {player['inventory'] if player['inventory'] else 'Empty'}") print("-" * 50) print(f"\n{room['description']}")
# Show available items in the room if room["item"] and room["item"] not in player["inventory"]: print(f"\nYou notice something on the ground: a **{room['item']}**.")
# Show available exits exits = ", ".join(room["exits"].keys()) print(f"\nExits: [{exits}]")
def show_help(): """Displays the list of available commands.""" print("\n--- Available Commands ---") print(" go [direction] - Move to a new location (e.g., 'go engine')") print(" get [item] - Pick up an item (e.g., 'get wrench')") print(" inventory - View your inventory") print(" look - Look around the current room again") print(" save - Save your progress") print(" help - Show this help message") print(" quit - Save and quit the game") print("--------------------------\n")
# --- GAME WORLD (Part 7: Dictionaries) ---
def create_game_map(): """Returns the game world as a dictionary of dictionaries.""" return { "Bridge": { "description": "You are on the Bridge of the Starship Explorer. Stars glitter\n" "outside the massive viewport. The captain's chair sits in the center.\n" "A door leads to the ENGINE room, and a corridor goes to the CARGO bay.", "exits": {"engine": "Engine Room", "cargo": "Cargo Bay"}, "item": None }, "Engine Room": { "description": "You are in the humming Engine Room. The ship's warp core glows\n" "with a brilliant blue light. Pipes and conduits line the walls.\n" "The door back to the BRIDGE is behind you.", "exits": {"bridge": "Bridge"}, "item": "wrench" }, "Cargo Bay": { "description": "You are in the vast Cargo Bay. Crates of supplies are stacked\n" "high against the walls. A faint humming comes from a locked door\n" "to the south. The corridor back to the BRIDGE is to the north.\n" "There is also a path to the LAB.", "exits": {"bridge": "Bridge", "lab": "Science Lab"}, "item": "keycard" }, "Science Lab": { "description": "You are in the Science Lab. Holographic displays show star charts\n" "and alien biology data. Beakers and strange instruments cover the\n" "tables. The CARGO bay is back the way you came.", "exits": {"cargo": "Cargo Bay"}, "item": "star map" } }
# --- MAIN GAME LOOP (Part 4: Loops) ---
def main(): """The main function that runs the entire game.""" game_map = create_game_map()
# Default player data (Part 2: Variables) player = { "name": "", "location": "Bridge", "inventory": [] }
show_title_screen()
# --- Start or Load Game --- choice = input("Would you like to (1) Start New Game or (2) Load Game? ")
if choice == "2": loaded = load_game() if loaded: player = loaded print(f"Welcome back, Commander {player['name']}!") else: player["name"] = input("No save found. What is your name, Commander? ") print(f"\nWelcome aboard, Commander {player['name']}! Your adventure begins.\n") else: player["name"] = input("What is your name, Commander? ") print(f"\nWelcome aboard, Commander {player['name']}! Your adventure begins.\n")
# --- The Game Loop (Part 4: while loop) --- while True: show_status(player, game_map) current_room = game_map[player["location"]]
# Get player input (Part 9: Error Handling for bad input) try: raw_input = input("\n> ").lower().strip() if not raw_input: continue command = raw_input.split() action = command[0] except (EOFError, KeyboardInterrupt): print("\n") save_game(player) break
# --- Process Commands (Part 3: Conditionals) --- if action == "quit": save_game(player) print(f"Goodbye, Commander {player['name']}! See you among the stars.") break
elif action == "help": show_help()
elif action == "save": save_game(player)
elif action == "look": pass # The loop will re-display the room description
elif action == "inventory": if player["inventory"]: print("\n--- Your Inventory ---") for i, item in enumerate(player["inventory"], 1): print(f" {i}. {item}") print("----------------------") else: print("\nYour inventory is empty.")
elif action == "go": if len(command) < 2: print("Go where? Please specify a direction (e.g., 'go engine').") elif command[1] in current_room["exits"]: player["location"] = current_room["exits"][command[1]] print(f"\nYou move to the {player['location']}...") else: print(f"You can't go '{command[1]}' from here.")
elif action == "get": if len(command) < 2: print("Get what? Please specify an item (e.g., 'get wrench').") elif current_room["item"] and command[1] == current_room["item"].split()[0].lower(): item_name = current_room["item"] player["inventory"].append(item_name) current_room["item"] = None # Remove item from room print(f"\nYou picked up the **{item_name}**!") elif command[1] in [item.split()[0].lower() for item in player["inventory"]]: print("You already have that item.") else: print(f"There is no '{command[1]}' here to pick up.")
else: print(f"Unknown command: '{action}'. Type 'help' for a list of commands.")
# --- Start the Game ---if __name__ == "__main__": main()Code Walkthrough: Connecting the Concepts
Let’s walk through the major sections of this game and see how they connect back to every part of our adventure.
Functions Keep Everything Organized (Part 5)
The entire game is broken into clear, reusable functions: show_title_screen(), save_game(), load_game(), show_status(), show_help(), create_game_map(), and main(). Each function has a single, clear job. This makes the code easy to read, easy to debug, and easy to expand.
The Game World is a Dictionary of Dictionaries (Part 7)
The create_game_map() function returns a nested dictionary. Each key is a room name (like "Bridge"), and each value is another dictionary containing the room’s description, exits, and item. This is the most elegant way to represent a game world in Python.
The Main Loop Keeps the Game Running (Part 4)
The while True: loop inside main() is the heartbeat of the game. It runs forever, displaying the current room, waiting for the player’s command, processing it, and then looping back to the top. The only way out is the break statement, which is triggered when the player types quit.
Conditionals Drive Every Decision (Part 3)
The large if-elif-else chain inside the main loop is where all the magic happens. It checks the player’s command (go, get, help, save, quit, etc.) and executes the corresponding code. This is the decision-making brain of the game.
Lists Track the Inventory (Part 6)
The player’s inventory is a list. When the player picks up an item with get, we use append() to add it. When we display the inventory, we use a for loop with enumerate() to print each item with a number.
File I/O Saves and Loads Progress (Part 8)
The save_game() and load_game() functions use with open(...) to safely write to and read from a file named savegame.json. We use the json library to easily convert our Python dictionary into a text format that can be stored in a file and read back later.
Error Handling Prevents Crashes (Part 9)
The file operations in save_game() and load_game() are wrapped in try...except blocks. If the save file is missing or corrupted, the game handles it gracefully instead of crashing. We also handle EOFError and KeyboardInterrupt in the main loop to catch unexpected input signals.
Your Turn: Expand the Game!
Now that you have a working game, here are some ideas to make it even better:
- Add more rooms. Create a “Medical Bay,” a “Crew Quarters,” or even an “Alien Planet” to explore.
- Add puzzles. For example, the player needs the
keycardfrom the Cargo Bay to unlock a secret room. - Add a win condition. Maybe the player needs to collect all items and return to the Bridge to complete the mission.
- Add an alien encounter. Use a dictionary to create an alien character that the player can talk to.
- Add a health or fuel system. Track the player’s health as a variable and decrease it when they make bad choices.
Your Journey is Just Beginning
Congratulations, Commander! You have completed your Grand Mission. You have built a complete, working game from scratch, applying every concept from your training. You are no longer a beginner — you are a programmer.
Here is a summary of the incredible journey you have taken:
| Part | Planet/Mission | Concept Learned |
|---|---|---|
| 1 | Welcome to Planet Python | print(), Comments |
| 2 | The Planet of Memory Vaults | Variables, Data Types, input() |
| 3 | The Crossroads of the Cosmos | if, elif, else, Comparison & Logical Operators |
| 4 | The Looping Nebula | for Loops, while Loops, break, continue |
| 5 | Mission Control Functions | def, Parameters, return, Default Values |
| 6 | The Treasure Chest | Lists, Tuples, String Methods |
| 7 | The Alien Encyclopedia | Dictionaries, Nested Dictionaries |
| 8 | The Captain’s Log | File Reading, Writing, Appending |
| 9 | Space Shields Up | try, except, else, finally |
| 10 | The Grand Mission | Capstone Project: A Text-Based Game |
The universe of programming is vast, and there is so much more to explore. Here are some exciting paths you can take next:
Object-Oriented Programming (OOP): Learn to create your own custom data types with “classes.” You could turn the player, rooms, and items into objects with their own properties and behaviors.
Web Development: Use frameworks like Flask or Django to build interactive websites and web applications powered by Python.
Data Science and AI: Use libraries like Pandas, NumPy, and Matplotlib to analyze data, create visualizations, and even build machine learning models.
Game Development: Use a library like Pygame to add graphics, sound, and animation to your games.
This is not the end. It is the beginning of a new, even more exciting adventure. The skills you have learned are the foundation for anything you want to build.
Ava and Py wave from the bridge of the Starship Explorer as they warp towards a new galaxy. The journey continues — and yours does too.
Keep exploring. Keep learning. Keep coding.
This is Part 10 of a 10-part series: “The Adventures of Ava the Astronaut: Learning Python One Planet at a Time.”