Spaces:
Runtime error
Runtime error
| from __future__ import annotations | |
| from collections.abc import Iterable | |
| VALID_ROLES = ("citizen", "gatherer", "guard", "builder") | |
| _ROLE_ALIASES = { | |
| "farmer": "gatherer", | |
| "forager": "gatherer", | |
| "scribe": "gatherer", | |
| } | |
| _ACTION_ALIASES = { | |
| "eat": "consume", | |
| "talk": "communicate", | |
| "call_for_help": "communicate", | |
| "request_trade": "communicate", | |
| "trade": "transfer", | |
| "wander": "move_to", | |
| } | |
| _ACTION_ORDER = [ | |
| "move_to_resource", | |
| "gather", | |
| "transfer", | |
| "consume", | |
| "heal", | |
| "flee", | |
| "communicate", | |
| "go_home", | |
| "move_to", | |
| "steal", | |
| "attack", | |
| "defend", | |
| "patrol", | |
| "build", | |
| "idle", | |
| ] | |
| _SHARED_ACTIONS = { | |
| "move_to_resource", | |
| "consume", | |
| "heal", | |
| "flee", | |
| "communicate", | |
| "transfer", | |
| "go_home", | |
| "move_to", | |
| "idle", | |
| } | |
| # A citizen has no fixed job: it can do everything (gather, build, fight, steal). | |
| _CITIZEN_ACTIONS = _SHARED_ACTIONS | { | |
| "gather", | |
| "steal", | |
| "attack", | |
| "defend", | |
| "patrol", | |
| "build", | |
| } | |
| _ROLE_ACTIONS = { | |
| "citizen": _CITIZEN_ACTIONS, | |
| "gatherer": _SHARED_ACTIONS | {"gather", "steal"}, | |
| "guard": (_SHARED_ACTIONS | {"attack", "defend", "patrol"}) - {"move_to_resource"}, | |
| "builder": _SHARED_ACTIONS | {"build", "gather"}, | |
| } | |
| def normalize_role(role: str) -> str: | |
| normalized = _ROLE_ALIASES.get(role, role) | |
| return normalized if normalized in VALID_ROLES else "citizen" | |
| def canonical_action(action: str) -> str: | |
| return _ACTION_ALIASES.get(action, action) | |
| def actions_for_role(role: str) -> list[str]: | |
| normalized = normalize_role(role) | |
| allowed = _ROLE_ACTIONS[normalized] | |
| return [action for action in _ACTION_ORDER if action in allowed] | |
| def filter_actions_for_role(actions: Iterable[str], role: str) -> list[str]: | |
| role_actions = set(actions_for_role(role)) | |
| filtered: list[str] = [] | |
| for action in actions: | |
| canonical = canonical_action(action) | |
| if canonical in role_actions and canonical not in filtered: | |
| filtered.append(canonical) | |
| return filtered | |
| def action_allowed_for_role( | |
| role: str, | |
| action: str, | |
| *, | |
| resource_type: str | None = None, | |
| self_defense: bool = False, | |
| ) -> bool: | |
| normalized_role = normalize_role(role) | |
| canonical = canonical_action(action) | |
| if canonical == "attack" and normalized_role == "gatherer" and self_defense: | |
| return True | |
| if canonical not in _ROLE_ACTIONS[normalized_role]: | |
| return False | |
| if canonical == "gather" and normalized_role == "builder": | |
| return resource_type in (None, "wood") | |
| return True | |