diff --git a/src/classes/avatar.py b/src/classes/avatar.py index 3d162ab..f759da9 100644 --- a/src/classes/avatar.py +++ b/src/classes/avatar.py @@ -1,10 +1,11 @@ import random +import uuid from dataclasses import dataclass, field from enum import Enum from typing import Optional from src.classes.calendar import Month, Year -from src.classes.action import Action +from src.classes.action import Action, Move, Cultivate from src.classes.world import World from src.classes.tile import Tile from src.classes.cultivation import CultivationProgress, Realm @@ -32,7 +33,7 @@ class Avatar: """ world: World name: str - id: int + id: str birth_month: Month birth_year: Year age: Age @@ -44,6 +45,19 @@ class Avatar: actions: dict[str, Action] = field(default_factory=dict) root: Root = field(default_factory=lambda: random.choice(list(Root))) + def __post_init__(self): + """ + 在Avatar创建后自动绑定基础动作 + """ + self._bind_basic_actions() + + def _bind_basic_actions(self): + """ + 绑定基础动作,如移动等 + """ + self.bind_action(Move) + self.bind_action(Cultivate) + def bind_action(self, action_class: type[Action]): """ @@ -120,4 +134,32 @@ class Avatar: "is_elderly": self.age.is_elderly(), "death_probability": round(death_probability, 4), "realm": self.cultivation_progress.realm.value - } \ No newline at end of file + } + +def get_new_avatar_from_ordinary(world: World, current_year: Year, name: str, age: Age): + """ + 从凡人中来的新修士 + 这代表其境界为最低 + """ + # 利用uuid功能生成id + avatar_id = str(uuid.uuid4()) + + birth_year = current_year - age.age + birth_month = random.choice(list(Month)) + cultivation_progress = CultivationProgress(0) + pos_x = random.randint(0, 100) + pos_y = random.randint(0, 100) + gender = random.choice(list(Gender)) + + return Avatar( + world=world, + name=name, + id=avatar_id, + birth_month=birth_month, + birth_year=birth_year, + age=age, + gender=gender, + cultivation_progress=cultivation_progress, + pos_x=pos_x, + pos_y=pos_y, + ) \ No newline at end of file diff --git a/src/front/front.py b/src/front/front.py index 5fb4d3e..40d4cf9 100644 --- a/src/front/front.py +++ b/src/front/front.py @@ -26,7 +26,6 @@ class Front: def __init__( self, - world: World, simulator: Simulator, *, tile_size: int = 32, @@ -36,7 +35,7 @@ class Front: font_path: Optional[str] = None, sidebar_width: int = 300, # 新增:侧边栏宽度 ): - self.world = world + self.world = simulator.world self.simulator = simulator self.tile_size = tile_size self.margin = margin @@ -57,8 +56,8 @@ class Front: pygame.font.init() # 计算窗口大小(包含侧边栏) - width_px = world.map.width * tile_size + margin * 2 + sidebar_width - height_px = world.map.height * tile_size + margin * 2 + width_px = self.world.map.width * tile_size + margin * 2 + sidebar_width + height_px = self.world.map.height * tile_size + margin * 2 self.screen = pygame.display.set_mode((width_px, height_px)) pygame.display.set_caption(window_title) diff --git a/src/sim/simulator.py b/src/sim/simulator.py index 409cb1b..badcae2 100644 --- a/src/sim/simulator.py +++ b/src/sim/simulator.py @@ -1,12 +1,19 @@ +import random + from src.classes.calendar import Month, Year, next_month -from src.classes.avatar import Avatar +from src.classes.avatar import Avatar, get_new_avatar_from_ordinary +from src.classes.age import Age +from src.classes.avatar import Gender +from src.classes.world import World from src.sim.event import Event class Simulator: - def __init__(self): - self.avatars = {} # dict of int -> Avatar + def __init__(self, world: World): + self.avatars = {} # dict of str -> Avatar self.year = Year(1) self.month = Month.JANUARY + self.world = world + self.brith_rate = 0.01 def step(self): """ @@ -17,7 +24,7 @@ class Simulator: 再去结算单个角色的事件。 """ events = [] # list of Event - death_avatar_ids = [] # list of int + death_avatar_ids = [] # list of str # 结算角色行为 for avatar_id, avatar in self.avatars.items(): @@ -28,9 +35,19 @@ class Simulator: events.append(event) avatar.update_age(self.month, self.year) + # 删除死亡的角色 for avatar_id in death_avatar_ids: self.avatars.pop(avatar_id) + # 新角色 + if random.random() < self.brith_rate: + name = f"无名" + age = random.randint(16, 60) + new_avatar = get_new_avatar_from_ordinary(self.world, self.year, name, Age(age)) + self.avatars[new_avatar.id] = new_avatar + event = Event(self.year, self.month, f"{new_avatar.name}晋升为修士了。") + events.append(event) + # 最后结算年月 self.month, self.year = next_month(self.month, self.year) diff --git a/tests/run_front.py b/tests/run_front.py index fe037a4..c147ed3 100644 --- a/tests/run_front.py +++ b/tests/run_front.py @@ -1,6 +1,7 @@ import os import sys import random +import uuid from typing import List, Tuple, Dict, Any # 将项目根目录加入 Python 路径,确保可以导入 `src` 包 @@ -710,8 +711,8 @@ def random_gender() -> Gender: return Gender.MALE if random.random() < 0.5 else Gender.FEMALE -def make_avatars(world: World, count: int = 12, current_year: Year = Year(100)) -> dict[int, Avatar]: - avatars: dict[int, Avatar] = {} +def make_avatars(world: World, count: int = 12, current_year: Year = Year(100)) -> dict[str, Avatar]: + avatars: dict[str, Avatar] = {} width, height = world.map.width, world.map.height for i in range(count): name = f"NPC{i+1:03d}" @@ -742,7 +743,7 @@ def make_avatars(world: World, count: int = 12, current_year: Year = Year(100)) avatar = Avatar( world=world, name=name, - id=i + 1, + id=str(uuid.uuid4()), birth_month=birth_month, birth_year=birth_year, age=age, @@ -753,8 +754,7 @@ def make_avatars(world: World, count: int = 12, current_year: Year = Year(100)) root=random.choice(list(Root)), # 随机选择灵根 ) avatar.tile = world.map.get_tile(x, y) - avatar.bind_action(Move) - avatars[i] = avatar + avatars[avatar.id] = avatar return avatars @@ -767,7 +767,7 @@ def main(): world = World(map=game_map) # 设置模拟器从第100年开始 - sim = Simulator() + sim = Simulator(world) sim.year = Year(100) # 设置初始年份为100年 sim.month = Month.JANUARY # 设置初始月份为1月 @@ -775,7 +775,6 @@ def main(): sim.avatars.update(make_avatars(world, count=14, current_year=sim.year)) front = Front( - world=world, simulator=sim, tile_size=24, # 稍微减小tile大小以适应更大的地图 margin=8, diff --git a/tests/test_basic.py b/tests/test_basic.py index bfc8887..8bb93d4 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -1,7 +1,9 @@ +import uuid from src.classes.avatar import Avatar, Gender from src.classes.calendar import Month, Year from src.classes.world import World from src.classes.tile import Map, TileType +from src.classes.age import Age def test_basic(): """ @@ -17,10 +19,10 @@ def test_basic(): avatar = Avatar( world=world, name="John Doe", - id=1, + id=str(uuid.uuid4()), birth_month=Month.JANUARY, birth_year=Year(2000), - age=20, + age=Age(20), gender=Gender.MALE ) diff --git a/tests/test_simulator.py b/tests/test_simulator.py index aa5bbb9..75db76e 100644 --- a/tests/test_simulator.py +++ b/tests/test_simulator.py @@ -33,8 +33,6 @@ def test_simulator_step_moves_avatar_and_sets_tile(): pos_y=1, ) - # 绑定移动动作 - avatar.bind_action(Move) sim = Simulator() sim.avatars.append(avatar)