Scrypt / scrypt /engine /run.py
IMJONEZZ's picture
SCRYPT: initial commit β€” game, sandbox, Warden, Space web layer
9fca766
Raw
History Blame Contribute Delete
2.45 kB
"""Run state: the journey between combats.
Phase 0 keeps this minimal β€” a linear node sequence and the player's
persistent resources. The branching map graph, challenges, and items
arrive in later phases.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from enum import Enum
from .cards import Card
class NodeKind(Enum):
BATTLE = "battle"
SHELL = "shell" # sandbox exploration between fights
ALTAR = "altar" # the Warden's command-for-power deal
CARD_CHOICE = "card_choice"
FORK = "fork" # the path splits; payload is a fork id
@dataclass(frozen=True)
class Node:
kind: NodeKind
payload: str = "" # encounter id for battles
@dataclass
class RunState:
deck: list[Card]
nodes: list[Node]
position: int = 0
cycles: int = 0
ttys: int = 2 # losses remaining before the run ends
over: bool = False
victorious: bool = False
@property
def current(self) -> Node | None:
return self.nodes[self.position] if self.position < len(self.nodes) else None
def advance(self) -> None:
self.position += 1
if self.current is None:
self.over = True
self.victorious = True
def lose_tty(self) -> None:
self.ttys -= 1
if self.ttys <= 0:
self.over = True
self.victorious = False
def resolve_fork(self, encounter_id: str) -> None:
"""The player chose a door: the FORK node becomes that battle."""
node = self.current
if node is None or node.kind is not NodeKind.FORK:
raise ValueError("not standing at a fork")
self.nodes[self.position] = Node(NodeKind.BATTLE, encounter_id)
def new_run(
starter_deck: list[Card],
encounter_ids: list[str],
fork_ids: frozenset[str] = frozenset(),
) -> RunState:
"""battle β†’ shell β†’ altar β†’ draft β†’ battle β†’ … β†’ final battle.
Ids in fork_ids become FORK nodes: the battle is chosen at the door.
"""
nodes: list[Node] = []
for i, enc in enumerate(encounter_ids):
kind = NodeKind.FORK if enc in fork_ids else NodeKind.BATTLE
nodes.append(Node(kind, enc))
if i < len(encounter_ids) - 1:
nodes.append(Node(NodeKind.SHELL))
nodes.append(Node(NodeKind.ALTAR))
nodes.append(Node(NodeKind.CARD_CHOICE))
return RunState(deck=list(starter_deck), nodes=nodes)