import abc from typing import Optional, Sequence, Tuple, TYPE_CHECKING from agame.action import Action from agame.dialog import DialogOption if TYPE_CHECKING: from agame.game import Game class Display(metaclass=abc.ABCMeta): """ Displays are an abstraction over printing things to the screen. Use a specific implementation based on the kind of display you want to use. """ @abc.abstractmethod def line(self, line: str = ""): "Print a single line to the display." @abc.abstractmethod def input(self, prompt: Optional[str] = None) -> str: "Get player input." @abc.abstractmethod def wait_for_ack(self, prompt: Optional[str] = None): """ Wait for the user to press a key. The behavior is up to the implementor. This could be something like "press any key to continue", "press enter to continue", or "click OK to continue". This method should block until input is acknowleged by the user. """ def dialog_options(self, options: Sequence[DialogOption]) -> DialogOption: """ Displays, and gets, an answer from a list of dialog options. Returns the selected DialogOption.next value and actions. """ valid_opts = range(1, len(options) + 1) def print_opts(): for i, opt in enumerate(options): self.line(f"{i}. {opt.text}") print_opts() while True: got = self.input("? ") try: choice = int(got) except ValueError: print_opts() continue if choice in valid_opts: break index = choice - 1 selection = options[index] return selection def finish(self): "Final cleanup code for this display."