Created
June 11, 2023 17:55
-
-
Save deadpixi/856816f0a776d20bb7b210eba48e1930 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/usr/bin/env python3 | |
import sys | |
from typing import Dict, List, Optional | |
class Game: | |
def __init__(self, initial_location: "Room") -> None: | |
self.location: Room = initial_location | |
self.inventory: Dict[str, Item] = {} | |
self.has_won: bool = False | |
class Item: | |
def __init__(self, name: str, description: str) -> None: | |
self.name = name | |
self.description = description | |
def __str__(self) -> str: | |
return self.description | |
def use(self, game: Game) -> None: | |
print("Nothing happens.") | |
class Room: | |
def __init__( | |
self, | |
name: str, | |
description: str, | |
exits: Optional[Dict[str, "Room"]] = None, | |
contents: Optional[List[Item]] = None, | |
) -> None: | |
self.exits: Dict[str, Room] = {} | |
if exits is not None: | |
self.exits = exits.copy() | |
self.contents: Dict[str, Item] = {} | |
if contents: | |
self.contents = {item.name: item for item in contents} | |
self.name = name | |
self.description = description | |
self.visited_before: bool = False | |
def enter(self) -> None: | |
if self.visited_before: | |
print(f"You are back in {self.name}") | |
return | |
self.visited_before = True | |
print(self) | |
def add_exit(self, name: str, target: "Room") -> None: | |
self.exits[name] = target | |
def add_item(self, item: "Item") -> None: | |
self.contents[item.name] = item | |
def __str__(self) -> str: | |
pieces: List[str] = [self.description] | |
if self.contents: | |
pieces.append("\n") | |
pieces.append("You see here: " + ", ".join(map(str, self.contents))) | |
if self.exits: | |
pieces.append("\n") | |
pieces.append("You can go to: " + ", ".join(self.exits)) | |
return "\n".join(pieces) | |
def get_command() -> str: | |
return input("Command: ").strip() | |
def main() -> None: | |
game.location.enter() | |
while not game.has_won: | |
try: | |
command = get_command().lower().strip() | |
if command.startswith("look"): | |
print(game.location) | |
elif command.startswith("go"): | |
target = command[2:].strip() | |
if target not in game.location.exits: | |
print("You can't go that way.") | |
else: | |
game.location = game.location.exits[target] | |
game.location.enter() | |
elif command.startswith("use"): | |
name = command[4:] | |
if name not in game.inventory: | |
print(f"You don't have the {name}!") | |
else: | |
game.inventory[name].use(game) | |
elif command.startswith("i"): | |
if game.inventory: | |
print("You are carrying: " + ", ".join(map(str, game.inventory))) | |
else: | |
print("You are carrying nothing") | |
elif command.startswith("drop"): | |
name = command[5:] | |
if name not in game.inventory: | |
print(f"You don't have the {name}!") | |
else: | |
item = game.inventory[name] | |
del game.inventory[name] | |
game.location.add_item(item) | |
print(f"You dropped the {name}.") | |
elif command.startswith("get"): | |
name = command[4:] | |
if name not in game.location.contents: | |
print(f"I don't see the {name} here!") | |
else: | |
item = game.location.contents[name] | |
del game.location.contents[name] | |
game.inventory[name] = item | |
print(f"You picked up the {name}.") | |
elif command.startswith("q"): | |
sys.exit("You have quit!") | |
elif command.startswith("h") or command.startswith("?"): | |
print( | |
"Commands I understand: help, quit, get, drop, inventory, use, go, look" | |
) | |
else: | |
print(f"I don't know how to {command}") | |
except Exception as exp: | |
sys.exit(f"Unknown error {exp}") | |
print("You place the gem into the altar. A bright flash, a thunderous sound!") | |
print("You find yourself standing in the bright sun, outside. You have escaped!") | |
print("YOU WON!") | |
class Gem(Item): | |
def __init__(self) -> None: | |
Item.__init__(self, "gem", "The ancient and mysterious Gem of Yendor") | |
def use(self, game: Game) -> None: | |
if game.location != altar: | |
print("I'm not sure how to use the gem here.") | |
else: | |
game.has_won = True | |
gem = Gem() | |
altar = Room( | |
"Altar of Escape", | |
"An ornate altar stands in the center of the room. " | |
"There is a gem-shaped hole in the middle.", | |
) | |
treasure_room = Room( | |
"Treasure Room", | |
"A room filled to the brim with treasure.", | |
exits={"east": altar}, | |
contents=[gem], | |
) | |
entrance = Room( | |
"Dungeon Entrance", | |
"You stand at the entrace to a dark dungeon. " | |
"To escape, you must place the Gem of Yendor into the altar of Escape.", | |
exits={ | |
"north": treasure_room, | |
}, | |
) | |
altar.add_exit("west", treasure_room) | |
treasure_room.add_exit("south", entrance) | |
game = Game(entrance) | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment