update prompt
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
28
src/classes/avatar_manager.py
Normal file
28
src/classes/avatar_manager.py
Normal 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
|
||||
|
||||
|
||||
@@ -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:
|
||||
"""
|
||||
计算升级到指定等级需要的经验值
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ FEMALE_GIVEN_NAMES = [
|
||||
"如雪", "若梦", "凝香", "紫霞", "月华", "清音", "蝶舞", "花颜", "雅韵", "诗涵",
|
||||
"静雯", "慕蓉", "婉儿", "柔情", "倾城", "红颜", "如烟", "妙音", "冰心", "玉颜",
|
||||
"如玉", "清影", "梦瑶", "紫嫣", "霜华", "若水", "青莲", "雪儿", "慧心", "素手",
|
||||
"如意", "诗雨", "梦蝶", "紫萱", "冰蓮", "若兰", "清雅", "雪梅", "慕雪", "天音",
|
||||
"如意", "诗雨", "梦蝶", "紫萱", "冰莲", "若兰", "清雅", "雪梅", "慕雪", "天音",
|
||||
"如风", "诗韵", "梦云", "紫烟", "冰雪", "若霜", "清秋", "雪莲", "慕凝", "天香",
|
||||
# 新增的50个平凡仙侠名字
|
||||
"小雨", "春花", "夏草", "秋叶", "冬梅", "东篱", "西园", "南风", "北雁", "中庭",
|
||||
|
||||
Reference in New Issue
Block a user