update new avatar

This commit is contained in:
bridge
2025-08-25 00:08:52 +08:00
parent cc9ffc3557
commit e504969c1f
6 changed files with 79 additions and 22 deletions

View File

@@ -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
}
}
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,
)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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,

View File

@@ -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
)

View File

@@ -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)