Files
cultivation-world-simulator/src/classes/observe.py
2025-10-04 22:08:10 +08:00

56 lines
1.6 KiB
Python

from __future__ import annotations
from typing import Iterable, List, TYPE_CHECKING
from src.classes.cultivation import Realm
from src.classes.tile import get_avatar_distance
if TYPE_CHECKING:
from src.classes.avatar import Avatar
_OBSERVATION_RADIUS_BY_REALM: dict[Realm, int] = {
Realm.Qi_Refinement: 2, # 练气
Realm.Foundation_Establishment: 3, # 筑基
Realm.Core_Formation: 4, # 金丹
Realm.Nascent_Soul: 5, # 元婴
}
def get_observation_radius_by_realm(realm: Realm) -> int:
"""
根据境界返回感知半径(基于曼哈顿距离)。
"""
return _OBSERVATION_RADIUS_BY_REALM.get(realm, 2)
def get_avatar_observation_radius(avatar: "Avatar") -> int:
"""
获取角色的感知半径。
"""
return get_observation_radius_by_realm(avatar.cultivation_progress.realm)
def is_within_observation(initiator: "Avatar", other: "Avatar") -> bool:
"""
判断 other 是否处于 initiator 的感知范围内:
汉明距离(曼哈顿距离) <= initiator 的感知半径。
"""
return get_avatar_distance(initiator, other) <= get_avatar_observation_radius(initiator)
def get_observable_avatars(initiator: "Avatar", avatars: Iterable["Avatar"]) -> List["Avatar"]:
"""
从给定集合中过滤出处于 initiator 感知范围内的角色(不包含 initiator 本人)。
算法:线性扫描 O(N),与现有管理器遍历复杂度一致。
"""
result: list["Avatar"] = []
for v in avatars:
if v is initiator:
continue
if is_within_observation(initiator, v):
result.append(v)
return result