add observe range
This commit is contained in:
55
src/classes/observe.py
Normal file
55
src/classes/observe.py
Normal file
@@ -0,0 +1,55 @@
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user