MSIT 501 - Project 4: RPG Player Inventory System¶
This notebook contains the specification and starter code for Project 4.
Read all instructions carefully before proceeding.
Also, there is a separate video which provides a walkthough of the code.
Assignment Overview¶
In this project, you will build a simple inventory system for an RPG player using object-oriented programming (OOP). You will:
- Implement a
Potionclass and aPlayerclass. - Manage potions that affect a player's health, mana, or strength.
- Display data using formatted string tables.
- Interact with a provided menu system (do not modify it).
This project emphasizes class design, method writing, and handling a list of objects.
What You Need to Do¶
- Complete all
TODOsections in thePotionandPlayerclasses. - Do not modify any functions outside the
TODOareas. - Use proper formatting and string alignment when displaying tables.
- Ensure the inventory system works with the menu interface provided in the
main()function. - Use best practices for names and comment as needed.
What to Submit¶
- Your completed notebook with all methods implemented.
- Make sure your code runs without errors.
Instructions and Hints¶
- Use
f-stringsfor all formatting. - All stat increases (health, mana, strength) are additive.
- Do not worry about stat limits or file I/O.
- Use methods like
.append()and.pop()where appropriate. - Be sure to test your implementation by running
main()at the bottom of the notebook.
Starter Code¶
Run the cell below and complete all TODO sections to finish the assignment.
In [6]:
# Project 4: RPG Player Inventory System
# MSIT 501
# Student Name: Steven Lora
# Date: 10/12/2025
"""
RPG Player Inventory System
Complete the TODO sections in the Potion and Player classes.
The main() function and menu system are provided and should not be modified.
"""
class Potion:
"""
Represents a magical potion that can boost player stats.
Attributes:
name (str): The name of the potion
potion_type (str): The type of potion ("health", "mana", or "strength")
effect_amount (int): The amount the potion increases the stat by
"""
def __init__(self, name, potion_type, effect_amount):
"""
Initialize a new Potion object.
Args:
name (str): The name of the potion (e.g., "Minor Health Potion")
potion_type (str): The type of potion - must be "health", "mana", or "strength"
effect_amount (int): The amount this potion increases the stat by (positive integer)
The method should NOT be modified.
"""
self.name = name
self.potion_type = potion_type
self.effect_amount = effect_amount
def __str__(self):
"""
Return a string representation of the potion.
Returns:
str: A formatted string showing potion details
Format: "PotionName (+AmountEffect type)"
Example: "Minor Health Potion (+25 health)"
"""
# Formatted string with potion name and effect
return f"{self.name} (+{self.effect_amount} {self.potion_type})"
class Player:
"""
Represents a player character in an RPG game.
Attributes:
name (str): The player's name
health (int): Current health points
mana (int): Current mana points
strength (int): Current strength points
inventory (list): List of Potion objects the player owns
"""
def __init__(self, name, health, mana, strength):
"""
Initialize a new Player object.
Args:
name (str): The player's name
health (int): Starting health points (default: 100)
mana (int): Starting mana points (default: 50)
strength (int): Starting strength points (default: 10)
The method should NOT be modified.
"""
self.name = name
self.health = health
self.mana = mana
self.strength = strength
self.inventory = [] # Start with empty inventory - list of Potion objects
def __str__(self):
"""
Return a string representation of the player.
Returns:
str: A formatted string showing player stats
Format: "PlayerName - Health: X, Mana: Y, Strength: Z"
Example: "Alice - Health: 100, Mana: 50, Strength: 10"
"""
# Formatted string with player name and all stats
return f"{self.name} - Health: {self.health}, Mana: {self.mana}, Strength: {self.strength}"
def display_stats_table(self):
"""
Display player stats in a formatted table.
"""
# Print table header
print("=" * 39)
print(f"{'PLAYER STATS':^39}")
print("=" * 39)
# Display each stat in aligned columns
print(f"{'Name:':<15}{self.name:>15}")
print(f"{'Health:':<15}{self.health:>15}")
print(f"{'Mana:':<15}{self.mana:>15}")
print(f"{'Strength:':<15}{self.strength:>15}")
# Print footer line
print("=" * 39)
def add_potion(self, potion):
"""
Add a potion to the player's inventory.
Args:
potion (Potion): The potion object to add to inventory
"""
# Append the potion object to the inventory list
self.inventory.append(potion)
def get_inventory_count(self):
"""
Get the number of potions in the player's inventory.
Returns:
int: The number of potions in inventory
"""
# Return the length of the inventory list
return len(self.inventory)
def has_potions(self):
"""
Check if the player has any potions in their inventory.
Returns:
bool: True if inventory has potions, False if empty
"""
# Check if inventory list has any items (length > 0)
return len(self.inventory) > 0
def display_inventory(self):
"""
Display all potions in the player's inventory in a formatted table.
If inventory is empty, display an appropriate message in table format.
Otherwise, display a table with columns for #, Potion Name, Type, and Effect.
"""
# If the inventory is empty, display a centered message
if not self.inventory:
print("=" * 50)
print(f"{'INVENTORY EMPTY':^50}")
print("=" * 50)
print(f"{'No potions available!':^50}")
print("=" * 50)
return
# Otherwise, display all potions in a formatted table
print("=" * 60)
print(f"{'INVENTORY':^60}")
print("=" * 60)
print(f"{'#':<3} {'Potion Name':<25} {'Type':<10} {'Effect':<10}")
print("-" * 60)
# Loop through all potions and display their details
for i, potion in enumerate(self.inventory, start=1):
print(f"{i:<3} {potion.name:<25} {potion.potion_type:<10} +{potion.effect_amount:<10}")
# Display total count
print("=" * 60)
print(f"Total potions: {len(self.inventory)}")
print("=" * 60)
def display_potions_by_type_table(self, potion_type, filtered_potions):
"""
Display potions of a specific type in a formatted table.
Args:
potion_type (str): The type of potions being displayed
filtered_potions (list): List of potions of the specified type
"""
# If no potions found, display appropriate message
if not filtered_potions:
print("=" * 60)
print(f"{potion_type.upper()} POTIONS".center(60))
print("=" * 60)
print(f"{'No potions of this type found!':^60}")
print("=" * 60)
return
# Otherwise show table with potion details and count
print("=" * 60)
print(f"{potion_type.upper()} POTIONS".center(60))
print("=" * 60)
print(f"{'#':<3} {'Potion Name':<25} {'Type':<10} {'Effect':<10}")
print("-" * 60)
for i, potion in enumerate(filtered_potions, start=1):
print(f"{i:<3} {potion.name:<25} {potion.potion_type:<10} +{potion.effect_amount:<10}")
# Display total count at the bottom
print("=" * 60)
print(f"Total {potion_type} potions: {len(filtered_potions)}")
print("=" * 60)
def use_potion(self, potion_index):
"""
Use a potion from the inventory by its index position.
Remove the potion from inventory and apply its effect to the player's stats.
Args:
potion_index (int): The index of the potion to used (0-based)
Returns:
bool: True if potion was successfully used, False if index is invalid
"""
# Validate index
if not isinstance(potion_index, int) or potion_index < 0 or potion_index >= len(self.inventory):
return False
# Get the potion and apply its effect
potion = self.inventory[potion_index]
ptype = potion.potion_type.lower()
if ptype == "health":
self.health += potion.effect_amount
elif ptype == "mana":
self.mana += potion.effect_amount
elif ptype == "strength":
self.strength += potion.effect_amount
else:
# Unknown potion type: do not remove; signal failure
return False
# Remove the used potion from inventory
self.inventory.pop(potion_index)
return True
def get_potions_by_type(self, potion_type):
"""
Get all potions of a specific type from the inventory.
Args:
potion_type (str): The type of potion to find ("health", "mana", or "strength")
Returns:
list: A list of Potion objects of the specified type
"""
# Create empty list to store matching potions
matching_potions = []
# Loop through all potions in inventory
for potion in self.inventory:
if potion.potion_type.lower() == potion_type.lower():
matching_potions.append(potion)
# Return the list of matching potions (could be empty)
return matching_potions
# Menu system functions and main() function - all complete, DO NOT MODIFY
def display_menu():
"""
Display the main menu options to the user.
This function is complete and should not be modified.
"""
print("\n=== RPG INVENTORY MENU ===")
print("1. View Player Stats")
print("2. View Inventory")
print("3. Use Potion")
print("4. View Potions by Type")
print("5. Quit")
print("=" * 26)
def get_valid_choice(min_value, max_value):
"""
Get a valid menu choice from the user (1-5).
This function is complete and should not be modified.
Args:
min_value (int): The minimum valid choice (inclusive)
max_value (int): The maximum valid choice (inclusive)
Returns:
int: A valid menu choice between 1 and 5, inclusive.
"""
while True:
try:
choice = int(input(f"Enter your choice ({min_value} - {max_value}): "))
if min_value <= choice <= max_value:
return choice
else:
print(f"Please enter a number between {min_value} and {max_value}.")
except ValueError:
print("Please enter a valid number.")
def get_inventory_choice(player):
"""
Get the user's choice of which potion to use from inventory.
This function is complete and should not be modified.
Args:
player (Player): The player object
Returns:
int: Valid index of chosen potion (0-based), or -1 if cancelled
"""
while True:
try:
choice = int(input(f"Choose a potion (1-{player.get_inventory_count()}) or 0 to cancel: "))
if choice == 0:
return -1
elif 1 <= choice <= player.get_inventory_count():
return choice - 1 # Convert to 0-based index
else:
print(f"Please enter a number between 1 and {player.get_inventory_count()}.")
except ValueError:
print("Please enter a valid number.")
def get_potion_type():
"""
Get the user's choice of potion type to filter by.
This function is complete and should not be modified.
Returns:
str: The chosen potion type ("health", "mana", or "strength")
"""
types = ["health", "mana", "strength"]
print("\nPotion Types:")
for i, ptype in enumerate(types, 1):
print(f"{i}. {ptype.capitalize()}")
while True:
try:
num = len(types)
choice = int(input(f"Choose potion type (1-{num}): "))
if 1 <= choice <= num:
return types[choice - 1]
else:
print(f"Please enter a number between 1 and {num}.")
except ValueError:
print("Please enter a valid number.")
def setup_player_inventory(player):
"""
Give the player a starting inventory of 4 potions.
This function is complete and should not be modified.
Args:
player (Player): The player object to add potions to
"""
# Create starting potions for the player
starting_potions = [
Potion("Minor Health Potion", "health", 25),
Potion("Mana Elixir", "mana", 30),
Potion("Strength Brew", "strength", 5),
Potion("Major Health Potion", "health", 50),
Potion("Health Booster", "health", 10)
]
# Add all starting potions to player's inventory
for potion in starting_potions:
player.add_potion(potion)
def main():
"""
Main function providing a menu-driven interface for the RPG inventory system.
This function is complete and should not be modified.
"""
# CONSTANTS
MIN_MENU_CHOICE = 1
MAX_MENU_CHOICE = 5
DEFAULT_PLAYER_NAME = "Adventurer"
DEFAULT_PLAYER_HEALTH = 100
DEFAULT_PLAYER_MANA = 50
DEFAULT_PLAYER_STRENGTH = 10
print("=== Welcome to the RPG Player Inventory System ===")
# Get player name
player_name = input("Enter your character's name: ").strip()
if not player_name:
player_name = DEFAULT_PLAYER_NAME
print(f"Using default player name: {player_name}")
# Create player with default stats
player = Player(player_name, DEFAULT_PLAYER_HEALTH, DEFAULT_PLAYER_MANA, DEFAULT_PLAYER_STRENGTH)
# Give player starting inventory
setup_player_inventory(player)
print(f"\nWelcome, {player.name}! You start your adventure with some basic supplies.")
print("You have been given a starter inventory of potions.")
# Main game loop
while True:
display_menu()
choice = get_valid_choice(MIN_MENU_CHOICE, MAX_MENU_CHOICE)
if choice == 1:
# View Player Stats - Use formatted table
player.display_stats_table()
elif choice == 2:
# View Inventory - Use formatted table
player.display_inventory()
elif choice == 3:
# Use Potion
if not player.has_potions():
print("\n" + "="*50)
print(f"{'INVENTORY EMPTY':^50}")
print("="*50)
print(f"{'No potions left to use!':^50}")
print("="*50)
else:
# Display inventory in table format for selection
print(f"\n{'='*60}")
print(f"{'SELECT POTION TO USE':^60}")
print(f"{'='*60}")
print(f"{'#':<3} {'Potion Name':<25} {'Type':<10} {'Effect':<10}")
print(f"{'-'*60}")
for i, potion in enumerate(player.inventory, 1):
print(f"{i:<3} {potion.name:<25} {potion.potion_type:<10} +{potion.effect_amount}")
print(f"{'='*60}")
potion_choice = get_inventory_choice(player)
if potion_choice != -1:
potion_to_use = player.inventory[potion_choice]
# Display before/after stats in table format
print(f"\n{'='*50}")
print(f"{'USING POTION':^50}")
print(f"{'='*50}")
print(f"{'Potion:':<15} {potion_to_use.name}")
print(f"{'Effect:':<15} +{potion_to_use.effect_amount} {potion_to_use.potion_type}")
print(f"{'-'*50}")
print(f"{'BEFORE:':<15} Health: {player.health:>3} | Mana: {player.mana:>3} | Strength: {player.strength:>3}")
success = player.use_potion(potion_choice)
if success:
print(f"{'AFTER:':<15} Health: {player.health:>3} | Mana: {player.mana:>3} | Strength: {player.strength:>3}")
print(f"{'-'*50}")
print(f"{'✓ Potion used successfully!':^50}")
else:
print(f"{'✗ Failed to use potion':^50}")
print(f"{'='*50}")
else:
print(f"\n{'='*30}")
print(f"{'Potion use cancelled':^30}")
print(f"{'='*30}")
elif choice == 4:
# View Potions by Type - Use formatted table
if not player.has_potions():
print("\n" + "="*50)
print(f"{'INVENTORY EMPTY':^50}")
print("="*50)
print(f"{'No potions to filter!':^50}")
print("="*50)
else:
potion_type = get_potion_type()
filtered_potions = player.get_potions_by_type(potion_type)
player.display_potions_by_type_table(potion_type, filtered_potions)
elif choice == 5:
# Quit
print(f"\nFarewell, {player.name}! Thanks for playing!")
print("Final Stats:")
player.display_stats_table()
if player.has_potions():
print("\nRemaining Inventory:")
player.display_inventory()
break
print("Game ended.")
# Run the main program
if __name__ == "__main__":
main()
=== Welcome to the RPG Player Inventory System ===
Enter your character's name: Claude
Welcome, Claude! You start your adventure with some basic supplies.
You have been given a starter inventory of potions.
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 1
=======================================
PLAYER STATS
=======================================
Name: Claude
Health: 100
Mana: 50
Strength: 10
=======================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 2
============================================================
INVENTORY
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Minor Health Potion health +25
2 Mana Elixir mana +30
3 Strength Brew strength +5
4 Major Health Potion health +50
5 Health Booster health +10
============================================================
Total potions: 5
============================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 4
Potion Types:
1. Health
2. Mana
3. Strength
Choose potion type (1-3): 1
============================================================
HEALTH POTIONS
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Minor Health Potion health +25
2 Major Health Potion health +50
3 Health Booster health +10
============================================================
Total health potions: 3
============================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 4
Potion Types:
1. Health
2. Mana
3. Strength
Choose potion type (1-3): 2
============================================================
MANA POTIONS
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Mana Elixir mana +30
============================================================
Total mana potions: 1
============================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 4
Potion Types:
1. Health
2. Mana
3. Strength
Choose potion type (1-3): 3
============================================================
STRENGTH POTIONS
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Strength Brew strength +5
============================================================
Total strength potions: 1
============================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 3
============================================================
SELECT POTION TO USE
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Minor Health Potion health +25
2 Mana Elixir mana +30
3 Strength Brew strength +5
4 Major Health Potion health +50
5 Health Booster health +10
============================================================
Choose a potion (1-5) or 0 to cancel: 3
==================================================
USING POTION
==================================================
Potion: Strength Brew
Effect: +5 strength
--------------------------------------------------
BEFORE: Health: 100 | Mana: 50 | Strength: 10
AFTER: Health: 100 | Mana: 50 | Strength: 15
--------------------------------------------------
✓ Potion used successfully!
==================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 1
=======================================
PLAYER STATS
=======================================
Name: Claude
Health: 100
Mana: 50
Strength: 15
=======================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 2
============================================================
INVENTORY
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Minor Health Potion health +25
2 Mana Elixir mana +30
3 Major Health Potion health +50
4 Health Booster health +10
============================================================
Total potions: 4
============================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 4
Potion Types:
1. Health
2. Mana
3. Strength
Choose potion type (1-3): 3
============================================================
STRENGTH POTIONS
============================================================
No potions of this type found!
============================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 3
============================================================
SELECT POTION TO USE
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Minor Health Potion health +25
2 Mana Elixir mana +30
3 Major Health Potion health +50
4 Health Booster health +10
============================================================
Choose a potion (1-4) or 0 to cancel: 1
==================================================
USING POTION
==================================================
Potion: Minor Health Potion
Effect: +25 health
--------------------------------------------------
BEFORE: Health: 100 | Mana: 50 | Strength: 15
AFTER: Health: 125 | Mana: 50 | Strength: 15
--------------------------------------------------
✓ Potion used successfully!
==================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 4
Potion Types:
1. Health
2. Mana
3. Strength
Choose potion type (1-3): 1
============================================================
HEALTH POTIONS
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Major Health Potion health +50
2 Health Booster health +10
============================================================
Total health potions: 2
============================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 3
============================================================
SELECT POTION TO USE
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Mana Elixir mana +30
2 Major Health Potion health +50
3 Health Booster health +10
============================================================
Choose a potion (1-3) or 0 to cancel: 1
==================================================
USING POTION
==================================================
Potion: Mana Elixir
Effect: +30 mana
--------------------------------------------------
BEFORE: Health: 125 | Mana: 50 | Strength: 15
AFTER: Health: 125 | Mana: 80 | Strength: 15
--------------------------------------------------
✓ Potion used successfully!
==================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 3
============================================================
SELECT POTION TO USE
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Major Health Potion health +50
2 Health Booster health +10
============================================================
Choose a potion (1-2) or 0 to cancel: 1
==================================================
USING POTION
==================================================
Potion: Major Health Potion
Effect: +50 health
--------------------------------------------------
BEFORE: Health: 125 | Mana: 80 | Strength: 15
AFTER: Health: 175 | Mana: 80 | Strength: 15
--------------------------------------------------
✓ Potion used successfully!
==================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 3
============================================================
SELECT POTION TO USE
============================================================
# Potion Name Type Effect
------------------------------------------------------------
1 Health Booster health +10
============================================================
Choose a potion (1-1) or 0 to cancel: 1
==================================================
USING POTION
==================================================
Potion: Health Booster
Effect: +10 health
--------------------------------------------------
BEFORE: Health: 175 | Mana: 80 | Strength: 15
AFTER: Health: 185 | Mana: 80 | Strength: 15
--------------------------------------------------
✓ Potion used successfully!
==================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 1
=======================================
PLAYER STATS
=======================================
Name: Claude
Health: 185
Mana: 80
Strength: 15
=======================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 2
==================================================
INVENTORY EMPTY
==================================================
No potions available!
==================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 3
==================================================
INVENTORY EMPTY
==================================================
No potions left to use!
==================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 4
==================================================
INVENTORY EMPTY
==================================================
No potions to filter!
==================================================
=== RPG INVENTORY MENU ===
1. View Player Stats
2. View Inventory
3. Use Potion
4. View Potions by Type
5. Quit
==========================
Enter your choice (1 - 5): 5
Farewell, Claude! Thanks for playing!
Final Stats:
=======================================
PLAYER STATS
=======================================
Name: Claude
Health: 185
Mana: 80
Strength: 15
=======================================
Game ended.