Merge pull request #15 from xzhseh/xzhseh/fix-age-exceeds-lifespan
fix: prevent character age from exceeding realm lifespan on creation
This commit is contained in:
@@ -507,6 +507,15 @@ class AvatarFactory:
|
||||
if levels[a] < levels[b] + MASTER_LEVEL_MIN_DIFF:
|
||||
levels[a] = min(LEVEL_MAX, levels[b] + MASTER_LEVEL_MIN_DIFF + random.randint(0, MASTER_LEVEL_EXTRA_MAX))
|
||||
|
||||
# 确保年龄不超过境界寿命上限,避免角色一出生就老死
|
||||
# 放在所有关系调整之后,因为关系调整可能会修改年龄和等级
|
||||
for i in range(n):
|
||||
realm = CultivationProgress(levels[i]).realm
|
||||
max_lifespan = Age.REALM_LIFESPAN.get(realm, 100)
|
||||
if ages[i] >= max_lifespan:
|
||||
# 将年龄限制为寿命上限的 80%-95%,保留一定的生存空间
|
||||
ages[i] = int(max_lifespan * random.uniform(0.8, 0.95))
|
||||
|
||||
avatars_by_index: list[Avatar] = [None] * n # type: ignore
|
||||
avatars_by_id: dict[str, Avatar] = {}
|
||||
|
||||
|
||||
84
tests/test_new_avatar.py
Normal file
84
tests/test_new_avatar.py
Normal file
@@ -0,0 +1,84 @@
|
||||
"""测试 new_avatar 模块的角色创建逻辑."""
|
||||
import pytest
|
||||
from src.sim.new_avatar import make_avatars, AvatarFactory, PopulationPlanner
|
||||
from src.classes.age import Age
|
||||
from src.classes.cultivation import CultivationProgress
|
||||
|
||||
|
||||
class TestAgeLifespanConstraint:
|
||||
"""测试角色创建时年龄不超过寿命上限的约束."""
|
||||
|
||||
def test_batch_creation_age_within_lifespan(self, base_world):
|
||||
"""批量创建角色时,年龄应不超过境界寿命上限.
|
||||
|
||||
注意:只有当随机生成的年龄 >= 寿命上限时才会触发调整,
|
||||
调整后的年龄会在 80%-95% 区间内。正常随机生成的年龄
|
||||
(如 77 岁 / 80 寿命)不会被调整,所以可能接近但不超过上限。
|
||||
"""
|
||||
# 创建大量角色以增加覆盖率
|
||||
avatars = make_avatars(base_world, count=100)
|
||||
|
||||
for avatar in avatars.values():
|
||||
max_lifespan = Age.REALM_LIFESPAN.get(
|
||||
avatar.cultivation_progress.realm, 100
|
||||
)
|
||||
assert avatar.age.age < max_lifespan, (
|
||||
f"角色 {avatar.name} 年龄 {avatar.age.age} 超过了"
|
||||
f"境界 {avatar.cultivation_progress.realm} 的寿命上限 {max_lifespan}"
|
||||
)
|
||||
|
||||
def test_batch_creation_no_immediate_death(self, base_world):
|
||||
"""批量创建的角色不应该一出生就处于老死状态."""
|
||||
avatars = make_avatars(base_world, count=100)
|
||||
|
||||
for avatar in avatars.values():
|
||||
# 不应该有老死概率
|
||||
death_prob = avatar.age.get_death_probability()
|
||||
assert death_prob == 0.0, (
|
||||
f"角色 {avatar.name} 年龄 {avatar.age.age}/"
|
||||
f"{avatar.age.max_lifespan} 有老死概率 {death_prob}"
|
||||
)
|
||||
|
||||
def test_multiple_batch_creations_consistent(self, base_world):
|
||||
"""多次批量创建应该都满足年龄约束."""
|
||||
for _ in range(5):
|
||||
avatars = make_avatars(base_world, count=50)
|
||||
for avatar in avatars.values():
|
||||
max_lifespan = Age.REALM_LIFESPAN.get(
|
||||
avatar.cultivation_progress.realm, 100
|
||||
)
|
||||
assert avatar.age.age < max_lifespan
|
||||
|
||||
|
||||
class TestRealmLifespanMapping:
|
||||
"""测试各境界的寿命上限映射."""
|
||||
|
||||
def test_qi_refinement_lifespan(self, base_world):
|
||||
"""练气期角色年龄应不超过80岁."""
|
||||
from src.classes.cultivation import Realm
|
||||
|
||||
avatars = make_avatars(base_world, count=100)
|
||||
qi_refinement_avatars = [
|
||||
av for av in avatars.values()
|
||||
if av.cultivation_progress.realm == Realm.Qi_Refinement
|
||||
]
|
||||
|
||||
for avatar in qi_refinement_avatars:
|
||||
assert avatar.age.age < 80, (
|
||||
f"练气期角色 {avatar.name} 年龄 {avatar.age.age} 超过 80"
|
||||
)
|
||||
|
||||
def test_foundation_establishment_lifespan(self, base_world):
|
||||
"""筑基期角色年龄应不超过120岁."""
|
||||
from src.classes.cultivation import Realm
|
||||
|
||||
avatars = make_avatars(base_world, count=100)
|
||||
fe_avatars = [
|
||||
av for av in avatars.values()
|
||||
if av.cultivation_progress.realm == Realm.Foundation_Establishment
|
||||
]
|
||||
|
||||
for avatar in fe_avatars:
|
||||
assert avatar.age.age < 120, (
|
||||
f"筑基期角色 {avatar.name} 年龄 {avatar.age.age} 超过 120"
|
||||
)
|
||||
Reference in New Issue
Block a user