"""The turn loop. GameEngine ties the pieces together: player action ─▶ build prompt from GameState ─▶ model.chat() ─▶ parser ◀─ narrative + updated state ◀────────────────────┘ It also enforces a couple of rules the model should not be trusted with: * if the model forgets to make a defeated enemy stop attacking, combat still ends when enemy HP hits 0 (handled in the parser); * a guaranteed enemy counter-attack option exists even if the model is lazy (the engine never *adds* damage on its own — it only ever clamps). """ from __future__ import annotations from .game_state import GameState from .llm import Backend from . import prompts, parser class GameEngine: def __init__(self, backend: Backend, state: GameState | None = None): self.backend = backend self.state = state or GameState() self.history: list[parser.TurnResult] = [] # ------------------------------------------------------------------ public def start(self) -> parser.TurnResult: """Generate the opening scene.""" user = prompts.build_opening_prompt(self.state.context_snapshot()) return self._turn(user) def act(self, player_action: str) -> parser.TurnResult: """Process one player action.""" if self.state.game_over: return parser.TurnResult( narrative="Your tale has ended. Start a new adventure to play again.", choices=[], applied=[], raw="", ) action = player_action.strip() or "look around" user = prompts.build_turn_prompt(self.state.context_snapshot(), action) return self._turn(user) def reset(self) -> "GameEngine": self.state = GameState() self.history.clear() return self # ----------------------------------------------------------------- internal def _turn(self, user_message: str) -> parser.TurnResult: try: raw = self.backend.chat(prompts.SYSTEM_PROMPT, user_message) except Exception as exc: # network/model errors shouldn't crash the UI return parser.TurnResult( narrative=f"(The mists swirl — the storyteller faltered: {exc})", choices=["Try again."], applied=[], raw="", ) result = parser.run_turn(self.state, raw) self.history.append(result) return result