-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #79 from debojit11/main
Interactive Text-Based Adventure Game(Issue no. 24)
- Loading branch information
Showing
2 changed files
with
238 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Text-Based Adventure Game | ||
|
||
Welcome to the **Text-Based Adventure Game**! This Python game is a simple interactive adventure where players explore rooms, collect items, and engage in combat with opponents like goblins and dragons. Each decision you make will affect your inventory and how you handle future challenges. | ||
|
||
## Features | ||
|
||
- **Two distinct types of doors**: Players can choose between doors, which may lead to hidden items such as swords or shields. | ||
- **Combat System**: Engage in battle with different opponents: | ||
- **Goblin**: A weak opponent that requires strategy. | ||
- **Dragon**: A formidable final boss with special attacks. | ||
- **Inventory Management**: Pick up and use items like swords and shields to aid in combat. | ||
- **Game Save & Load**: Your progress is automatically saved, so you can load it later and continue from where you left off. | ||
|
||
## Gameplay | ||
|
||
- Players start the game by entering their name. | ||
- You are presented with two doors to choose from, each leading to different experiences. | ||
- Items like swords and shields can be found to help you in combat. | ||
- Random encounters with goblins and dragons will test your decision-making skills. | ||
- The game automatically saves your progress, allowing you to resume your adventure later. | ||
|
||
## How to Play | ||
|
||
1. **Choose a door**: When prompted, choose either the left or right door. Each door may contain hidden treasures like a sword or shield. | ||
2. **Make choices**: Decide whether to pick up items or face challenges. | ||
3. **Combat**: Engage in combat with either a goblin or dragon. Use your sword and shield to protect yourself or defeat enemies. | ||
4. **Save your progress**: The game will automatically save after each major action. | ||
5. **Reload your game**: If you exit the game, you can load it from the last saved point when you return. | ||
|
||
## Setup and Installation | ||
|
||
1. Ensure you have Python 3 installed on your machine. | ||
2. Clone this repository to your local machine. | ||
3. Navigate to the project directory. | ||
4. Run the text_adventure_game.py file. | ||
|
||
|
||
## Code Overview | ||
|
||
The game is built using Python, and its logic is divided into several components: | ||
|
||
- **Opponent Class**: The base class for both weak and strong opponents. Handles basic attack logic. | ||
- **WeakOpponent Class**: A class for weaker opponents like the goblin. Overrides the attack method to reflect weaker attacks. | ||
- **FinalBoss Class**: A subclass of Opponent designed for more challenging enemies like the dragon, with special powers. | ||
- **Combat and Exploration**: Players can choose doors, explore rooms, collect items, and engage in combat. | ||
- **Saving and Loading**: The game state is saved to a file (`game_save.txt`), and players can load this file to continue their progress. | ||
|
||
## Error Handling | ||
|
||
The game is designed with basic error handling using `try-except` blocks: | ||
- If there are issues with file saving or loading, an error message is displayed. | ||
- Combat logic is wrapped in error handling to prevent crashes due to unexpected input. | ||
|
||
Enjoy your adventure! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
import random | ||
import os # Used to check if the file exists | ||
|
||
# Opponent base class | ||
class Opponent: | ||
def __init__(self, name, health, attack_strength): | ||
self.name = name | ||
self.health = health | ||
self.attack_strength = attack_strength | ||
|
||
def attack(self): | ||
"""General attack logic for opponents.""" | ||
return random.randint(1, self.attack_strength) | ||
|
||
# WeakOpponent class inheriting from Opponent | ||
class WeakOpponent(Opponent): | ||
def __init__(self, name, health, attack_strength): | ||
super().__init__(name, health, attack_strength) | ||
|
||
def attack(self): | ||
"""Overriding attack for weak opponents.""" | ||
print(f"{self.name} attacks weakly!") | ||
return random.randint(1, self.attack_strength // 2) # Weak attack is halved | ||
|
||
# FinalBoss class inheriting from Opponent | ||
class FinalBoss(Opponent): | ||
def __init__(self, name, health, attack_strength, special_power): | ||
super().__init__(name, health, attack_strength) | ||
self.special_power = special_power # New attribute for FinalBoss | ||
|
||
def attack(self): | ||
"""Overriding attack for final bosses with special power.""" | ||
if random.random() > 0.7: # 30% chance of using special power | ||
print(f"{self.name} uses {self.special_power}!") | ||
return random.randint(self.attack_strength, self.attack_strength * 2) | ||
else: | ||
print(f"{self.name} attacks normally.") | ||
return super().attack() | ||
|
||
# Additional methods for game logic | ||
|
||
def save_game(player_name, inventory, doors_chosen): | ||
"""Saves the current game state to a file.""" | ||
try: | ||
with open('game_save.txt', 'w') as file: | ||
file.write(f"{player_name}\n") | ||
file.write(",".join(inventory) + "\n") | ||
file.write(f"{doors_chosen['left']},{doors_chosen['right']}\n") | ||
except Exception as e: | ||
print(f"Error saving game: {e}") | ||
|
||
def load_game(): | ||
"""Loads the game state from a file if it exists.""" | ||
if not os.path.exists('game_save.txt'): | ||
return None, [], {"left": False, "right": False} | ||
|
||
try: | ||
with open('game_save.txt', 'r') as file: | ||
file_content = file.readlines() | ||
|
||
player_name = file_content[0].strip() | ||
inventory = file_content[1].strip().split(",") if file_content[1].strip() else [] | ||
doors_status = file_content[2].strip().split(",") | ||
doors_chosen = {"left": doors_status[0] == "True", "right": doors_status[1] == "True"} | ||
|
||
return player_name, inventory, doors_chosen | ||
except Exception as e: | ||
print(f"Error loading game: {e}") | ||
return None, [], {"left": False, "right": False} | ||
|
||
def choose_door(doors_chosen, inventory): | ||
"""Handles the player's choice of doors and updates the game state accordingly.""" | ||
available_doors = [] | ||
if not doors_chosen["left"]: | ||
available_doors.append("left") | ||
if not doors_chosen["right"]: | ||
available_doors.append("right") | ||
|
||
print(f'{"You return to the two doors.":^30}') | ||
if available_doors: | ||
print(f'{"Available doors are: " + ", ".join(available_doors):^30}') | ||
|
||
choice = "" | ||
while choice not in available_doors: | ||
choice = input(f'{"Which door do you want to choose? (left/right): ":^30}').lower() | ||
|
||
try: | ||
if choice == "left" and not doors_chosen["left"]: | ||
print(f'{"You are in a room with no doors. It is empty.":^30}') | ||
if input(f'{"Do you want to look around? (yes/no): ":^30}').lower() == "yes": | ||
print(f'{"You see a sword on the ground.":^30}') | ||
if input(f'{"Do you want to take the sword? (yes/no): ":^30}').lower() == "yes": | ||
inventory.append("sword") | ||
print(f'{"You took the sword!":^30}') | ||
else: | ||
print(f'{"You left the sword.":^30}') | ||
doors_chosen["left"] = True | ||
|
||
elif choice == "right" and not doors_chosen["right"]: | ||
print(f'{"You enter a room and find a shield!":^30}') | ||
if input(f'{"Do you want to take the shield? (yes/no): ":^30}').lower() == "yes": | ||
inventory.append("shield") | ||
print(f'{"You took the shield!":^30}') | ||
else: | ||
print(f'{"You left the shield.":^30}') | ||
doors_chosen["right"] = True | ||
except Exception as e: | ||
print(f"Error during door selection: {e}") | ||
|
||
save_game(player_name, inventory, doors_chosen) | ||
return doors_chosen, inventory | ||
|
||
def combat(choice, inventory): | ||
"""Handles combat encounters using the new Opponent system.""" | ||
try: | ||
if choice == "dragon": | ||
dragon = FinalBoss("Dragon", health=100, attack_strength=20, special_power="Fire Breath") | ||
print(f'{"You encounter a fearsome dragon!":^30}') | ||
if input(f'{"Do you want to fight the dragon? (yes/no): ":^30}').lower() == "yes": | ||
if "sword" in inventory: | ||
print(f'{"Rolling the dice to see the outcome...":^30}') | ||
player_attack = random.randint(1, 10) # Simulating player's attack | ||
dragon_attack = dragon.attack() | ||
|
||
if player_attack >= dragon_attack: | ||
print(f'{"You defeated the dragon with your sword!":^30}') | ||
else: | ||
if "shield" in inventory: | ||
print(f'{"The dragon overpowered you, but your shield saved you!":^30}') | ||
inventory.remove("shield") | ||
else: | ||
print(f'{"The dragon overpowered you and you lost the game!":^30}') | ||
inventory.clear() | ||
else: | ||
print(f'{"You were eaten by the dragon because you had no sword!":^30}') | ||
inventory.clear() | ||
|
||
elif choice == "goblin": | ||
goblin = WeakOpponent("Goblin", health=50, attack_strength=5) | ||
print(f'{"You encounter a sneaky goblin!":^30}') | ||
if input(f'{"Do you want to fight the goblin? (yes/no): ":^30}').lower() == "yes": | ||
if "sword" in inventory: | ||
print(f'{"Rolling the dice to see the outcome...":^30}') | ||
player_attack = random.randint(1, 10) # Simulating player's attack | ||
goblin_attack = goblin.attack() | ||
|
||
if player_attack >= goblin_attack: | ||
print(f'{"You defeated the goblin with your sword!":^30}') | ||
else: | ||
if "shield" in inventory: | ||
print(f'{"The goblin tricked you, but your shield protected you!":^30}') | ||
inventory.remove("shield") | ||
else: | ||
print(f'{"The goblin tricked you and you lost the game!":^30}') | ||
inventory.clear() | ||
elif "shield" in inventory: | ||
print(f'{"The goblin attacked, but your shield saved you!":^30}') | ||
inventory.remove("shield") | ||
else: | ||
print(f'{"The goblin defeated you because you had no sword or shield!":^30}') | ||
inventory.clear() | ||
except Exception as e: | ||
print(f"Error during combat: {e}") | ||
|
||
return inventory | ||
|
||
def play_game(): | ||
"""Main function that runs the game logic.""" | ||
player_name, inventory, doors_chosen = load_game() | ||
|
||
if not player_name: | ||
player_name = input("Enter your name: ") | ||
|
||
print(f'{"Welcome to the Adventure Game, " + player_name + "!":^30}') | ||
|
||
# Let player choose a door | ||
doors_chosen, inventory = choose_door(doors_chosen, inventory) | ||
|
||
# Encounter either a goblin or a dragon randomly | ||
encounter = random.choice(["goblin", "dragon"]) | ||
inventory = combat(encounter, inventory) | ||
|
||
if __name__ == "__main__": | ||
play_game() |