Files
ages/agame/game.py

114 lines
3.1 KiB
Python
Raw Normal View History

import dataclasses
import textwrap
from typing import Any, MutableMapping, Match, Optional, Sequence
from agame.action import Action
from agame.color import colorize
from agame.item import Item, ItemInst
from agame.room import Room
from agame.trigger import *
__all__ = (
"Database",
"Game",
)
@dataclasses.dataclass
class Database:
# All items available to the game.
items: MutableMapping[str, Item] = dataclasses.field(default_factory=dict)
# All rooms available to the game.
rooms: MutableMapping[str, Room] = dataclasses.field(default_factory=dict)
def add_item(self, item: Item):
self.items[item.id] = item
def add_items(self, *items: Item):
for item in items:
self.add_item(item)
def add_room(self, room: Room):
self.rooms[room.id] = room
def add_rooms(self, *rooms: Room):
for room in rooms:
self.add_room(room)
@dataclasses.dataclass
class Game:
# Game room/items database
database: Database
# Current room.
room: Room
# Player inventory.
inventory: MutableMapping[str, ItemInst] = dataclasses.field(default_factory=dict)
# Variables.
vars: MutableMapping[str, Any] = dataclasses.field(default_factory=dict)
def run_command(self, line: str):
line = line.strip()
if not line:
return
triggers: Sequence[Trigger] = [
GetTrigger(),
UseTrigger(),
PutTrigger(),
LookTrigger(),
OpenTrigger(),
CloseTrigger(),
GoTrigger(),
]
trigger = None
match: Optional[Match] = None
for t in triggers:
match = t.pattern().fullmatch(line)
if match:
trigger = t
break
if not trigger:
self.say("I'm not sure what you mean.")
return
assert match, "why were no patterns matched?"
trigger.trigger(self, match)
def do_actions(self, actions: Sequence[Action]):
"Executes the supplied actions."
for action in actions:
action.act(self)
def print_room(self):
"Prints this room's description."
self.say(self.room.name)
self.say()
self.say(self.room.desc)
# Look at revealed text
for item in self.room.items.values():
if not item.revealed or item.room_desc is None:
continue
if item.room_desc == "":
# TODO - pluralization, 'a' vs 'an'
self.say(f"You see a (({item.name})).")
else:
self.say(item.room_desc)
def say(self, message: Optional[str] = None):
"Format, colorize, wrap, and print the message."
message = message or ""
message = textwrap.fill(message)
print(colorize(message))
@property
def rooms(self):
"Shortcut property for `game.database.rooms`."
return self.database.rooms
@property
def items(self):
"Shortcut property for `game.database.items`."
return self.database.items