update prompt

This commit is contained in:
bridge
2025-09-21 17:25:27 +08:00
parent 938f85db9a
commit 40ef5b9cb6
10 changed files with 73 additions and 19 deletions

View File

@@ -122,7 +122,11 @@ class LLMAI(AI):
异步决策逻辑通过LLM决定执行什么动作和参数
"""
global_info = world.get_info()
avatar_infos = {avatar.name: avatar.get_prompt_info() for avatar in avatars_to_decide}
# 在提示中包含与该角色处于同一区域的其他角色
avatar_infos = {}
for avatar in avatars_to_decide:
co_region = world.get_avatars_in_same_region(avatar)
avatar_infos[avatar.name] = avatar.get_prompt_info(co_region)
general_action_infos = ACTION_INFOS_STR
info = {
"avatar_infos": avatar_infos,

View File

@@ -349,7 +349,7 @@ class Avatar:
action_space = [action.name for action in doable_actions]
return action_space
def get_prompt_info(self) -> str:
def get_prompt_info(self, co_region_avatars: Optional[List["Avatar"]] = None) -> str:
"""
获取角色提示词信息
"""
@@ -371,11 +371,18 @@ class Avatar:
else:
items_info = "物品持有情况:无"
# 同区域角色(可选)
co_region_info = ""
if co_region_avatars:
entries: list[str] = []
for other in co_region_avatars[:8]:
entries.append(f"{other.name}(境界:{other.cultivation_progress.get_simple_info()})")
co_region_info = "\n同区域角色:" + ("".join(entries) if entries else "")
# 关系摘要
relations_summary = self._get_relations_summary_str()
personas_count = len(self.personas)
return f"{info}\n{personas_info}\n{magic_stone_info}\n{items_info}\n关系:{relations_summary}\n决策时需参考这个角色的{personas_count}个个性特点。\n该角色的目前暂时的合法动作为:{action_space}"
return f"{info}\n{personas_info}\n{magic_stone_info}\n{items_info}\n关系:{relations_summary}\n{co_region_info}\n该角色的目前暂时的合法动作为:{action_space}"
def set_relation(self, other: "Avatar", relation: Relation) -> None:
"""
@@ -424,7 +431,7 @@ class Avatar:
"""
relation = self.get_relation(other_avatar)
relation_str = str(relation)
return f"{other_avatar.name},境界:{str(other_avatar.cultivation_progress)},关系:{relation_str}"
return f"{other_avatar.name},境界:{other_avatar.cultivation_progress.get_simple_info()},关系:{relation_str}"
@property
def move_step_length(self) -> int:

View File

@@ -0,0 +1,28 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Dict, List, TYPE_CHECKING
if TYPE_CHECKING:
from src.classes.avatar import Avatar
@dataclass
class AvatarManager:
avatars: Dict[str, "Avatar"] = field(default_factory=dict)
def get_avatars_in_same_region(self, avatar: "Avatar") -> List["Avatar"]:
"""
返回与给定 avatar 处于同一区域的其他角色列表(不含自己)。
"""
if avatar is None or getattr(avatar, "tile", None) is None or avatar.tile.region is None:
return []
region = avatar.tile.region
same_region: list["Avatar"] = []
for other in self.avatars.values():
if other is avatar or getattr(other, "tile", None) is None:
continue
if other.tile.region == region:
same_region.append(other)
return same_region

View File

@@ -89,10 +89,16 @@ class CultivationProgress:
return REALM_TO_MOVE_STEP[self.realm]
def __str__(self) -> str:
return self.get_info()
def get_info(self) -> str:
can_break_through = self.can_break_through()
can_break_through_str = "可以突破" if can_break_through else "不可以突破"
return f"{self.realm.value}{self.stage.value}({self.level}级){can_break_through_str}"
def get_simple_info(self) -> str:
return f"{self.realm.value}{self.stage.value}"
def get_exp_required(self) -> int:
"""
计算升级到指定等级需要的经验值

View File

@@ -1,15 +1,25 @@
from dataclasses import dataclass
from dataclasses import dataclass, field
from typing import TYPE_CHECKING
from src.classes.map import Map
from src.classes.calendar import Year, Month, MonthStamp
from src.classes.avatar_manager import AvatarManager
if TYPE_CHECKING:
from src.classes.avatar import Avatar
@dataclass
class World():
map: Map
month_stamp: MonthStamp
avatar_manager: AvatarManager = field(default_factory=AvatarManager)
def get_info(self) -> str:
map_intro = "世界上的区域为:"
map_info = self.map.get_info()
info = f"{map_intro}\n{map_info}"
return info
return info
def get_avatars_in_same_region(self, avatar: "Avatar"):
return self.avatar_manager.get_avatars_in_same_region(avatar)

View File

@@ -159,7 +159,7 @@ class Front:
def _assign_avatar_images(self):
import random
for avatar_id, avatar in self.simulator.avatars.items():
for avatar_id, avatar in self.world.avatar_manager.avatars.items():
if avatar_id not in self.avatar_images:
if avatar.gender == Gender.MALE and self.male_avatars:
self.avatar_images[avatar_id] = random.choice(self.male_avatars)
@@ -175,11 +175,11 @@ class Front:
ts = self.tile_size
m = self.margin
# 清理已不存在的 avatar 状态
to_del = [aid for aid in self._avatar_display_states.keys() if aid not in self.simulator.avatars]
to_del = [aid for aid in self._avatar_display_states.keys() if aid not in self.world.avatar_manager.avatars]
for aid in to_del:
self._avatar_display_states.pop(aid, None)
# 初始化/补全
for avatar_id, avatar in self.simulator.avatars.items():
for avatar_id, avatar in self.world.avatar_manager.avatars.items():
if avatar_id not in self._avatar_display_states:
cx = m + avatar.pos_x * ts + ts // 2
cy = m + avatar.pos_y * ts + ts // 2
@@ -197,7 +197,7 @@ class Front:
ts = self.tile_size
m = self.margin
self._init_avatar_display_states()
for avatar_id, avatar in self.simulator.avatars.items():
for avatar_id, avatar in self.world.avatar_manager.avatars.items():
state = self._avatar_display_states[avatar_id]
# 当前目标像素
cur_target_x = m + avatar.pos_x * ts + ts // 2

View File

@@ -87,7 +87,7 @@ def draw_avatars_and_pick_hover(
mouse_x, mouse_y = pygame_mod.mouse.get_pos()
hovered = None
min_dist = float("inf")
for avatar_id, avatar in simulator.avatars.items():
for avatar_id, avatar in simulator.world.avatar_manager.avatars.items():
if get_display_center is not None:
cx_f, cy_f = get_display_center(avatar, tile_size, margin)
cx, cy = int(cx_f), int(cy_f)

View File

@@ -117,7 +117,7 @@ async def main():
sim = Simulator(world)
# 创建角色传入当前年份确保年龄与生日匹配使用配置文件中的NPC数量
sim.avatars.update(make_avatars(world, count=CONFIG.game.init_npc_num, current_month_stamp=world.month_stamp))
world.avatar_manager.avatars.update(make_avatars(world, count=CONFIG.game.init_npc_num, current_month_stamp=world.month_stamp))
front = Front(
simulator=sim,

View File

@@ -11,7 +11,6 @@ from src.utils.config import CONFIG
class Simulator:
def __init__(self, world: World):
self.avatars = {} # dict of str -> Avatar
self.world = world
self.birth_rate = CONFIG.game.npc_birth_rate_per_month # 从配置文件读取NPC每月出生率
@@ -28,7 +27,7 @@ class Simulator:
# 决定动作行为
avatars_to_decide = []
for avatar in list(self.avatars.values()):
for avatar in list(self.world.avatar_manager.avatars.values()):
if avatar.cur_action_pair is None:
# 若有排队动作但当前不可执行:丢弃之后的所有动作
if avatar.has_next_actions():
@@ -54,7 +53,7 @@ class Simulator:
events.append(event)
# 结算角色行为
for avatar_id, avatar in self.avatars.items():
for avatar_id, avatar in self.world.avatar_manager.avatars.items():
await avatar.act()
if avatar.death_by_old_age():
death_avatar_ids.append(avatar_id)
@@ -64,7 +63,7 @@ class Simulator:
# 删除死亡的角色
for avatar_id in death_avatar_ids:
self.avatars.pop(avatar_id)
self.world.avatar_manager.avatars.pop(avatar_id)
# 新角色
if random.random() < self.birth_rate:
@@ -72,7 +71,7 @@ class Simulator:
gender = random.choice(list(Gender))
name = get_random_name(gender)
new_avatar = get_new_avatar_from_ordinary(self.world, self.world.month_stamp, name, Age(age))
self.avatars[new_avatar.id] = new_avatar
self.world.avatar_manager.avatars[new_avatar.id] = new_avatar
event = Event(self.world.month_stamp, f"{new_avatar.name}晋升为修士了。")
events.append(event)

View File

@@ -36,7 +36,7 @@ FEMALE_GIVEN_NAMES = [
"如雪", "若梦", "凝香", "紫霞", "月华", "清音", "蝶舞", "花颜", "雅韵", "诗涵",
"静雯", "慕蓉", "婉儿", "柔情", "倾城", "红颜", "如烟", "妙音", "冰心", "玉颜",
"如玉", "清影", "梦瑶", "紫嫣", "霜华", "若水", "青莲", "雪儿", "慧心", "素手",
"如意", "诗雨", "梦蝶", "紫萱", "", "若兰", "清雅", "雪梅", "慕雪", "天音",
"如意", "诗雨", "梦蝶", "紫萱", "", "若兰", "清雅", "雪梅", "慕雪", "天音",
"如风", "诗韵", "梦云", "紫烟", "冰雪", "若霜", "清秋", "雪莲", "慕凝", "天香",
# 新增的50个平凡仙侠名字
"小雨", "春花", "夏草", "秋叶", "冬梅", "东篱", "西园", "南风", "北雁", "中庭",