56 lines
1.6 KiB
Python
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
|
|
|
|
|