Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| from config import load_settings | |
| from .models import LegalMove | |
| from .storage import read_json | |
| def load_game_graph() -> dict: | |
| settings = load_settings() | |
| return read_json(settings.game_graph_path) | |
| def all_junction_ids() -> list[int]: | |
| graph = load_game_graph() | |
| return sorted(int(node["id"]) for node in graph.get("nodes", [])) | |
| def adjacent_junctions(junction_id: int) -> list[int]: | |
| graph = load_game_graph() | |
| adjacency = graph.get("adjacency", {}).get(str(junction_id), []) | |
| return sorted({int(item["destination"]) for item in adjacency}) | |
| def legal_moves_from(junction_id: int, blocked_edges: list[dict] | None = None) -> list[LegalMove]: | |
| graph = load_game_graph() | |
| blocked_edges = blocked_edges or [] | |
| moves: list[LegalMove] = [] | |
| for edge in graph.get("edges", []): | |
| source = int(edge["source"]) | |
| target = int(edge["target"]) | |
| if junction_id not in (source, target): | |
| continue | |
| destination = target if source == junction_id else source | |
| for mode in edge.get("modes", []): | |
| blocked = _is_blocked(junction_id, destination, mode, blocked_edges) | |
| moves.append(LegalMove(destination=destination, via=(junction_id, destination), mode=mode, blocked=blocked)) | |
| return sorted(moves, key=lambda move: (move.destination, move.mode)) | |
| def _is_blocked(source: int, target: int, mode: str, blocks: list[dict]) -> bool: | |
| for block in blocks: | |
| block_type = block.get("block_type") | |
| if block_type == "mode_block" and block.get("mode") == mode: | |
| return True | |
| if block_type == "junction_block" and block.get("junction_id") in (source, target): | |
| return True | |
| if block_type == "edge_block": | |
| same_edge = {block.get("from_junction"), block.get("to_junction")} == {source, target} | |
| same_mode = block.get("mode") in (None, mode) | |
| if same_edge and same_mode: | |
| return True | |
| return False | |