update readme
This commit is contained in:
@@ -14,6 +14,7 @@ from src.classes.root import corres_essence_type
|
||||
from src.classes.action import ACTION_SPACE_STR
|
||||
from src.classes.event import Event, NULL_EVENT
|
||||
from src.utils.llm import get_ai_prompt_and_call_llm
|
||||
from src.classes.typings import ACTION_NAME, ACTION_PARAMS, ACTION_PAIR
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.classes.avatar import Avatar
|
||||
@@ -25,7 +26,7 @@ class AI(ABC):
|
||||
def __init__(self, avatar: Avatar):
|
||||
self.avatar = avatar
|
||||
|
||||
def decide(self, world: World) -> tuple[str, dict, Event]:
|
||||
def decide(self, world: World) -> tuple[ACTION_NAME, ACTION_PARAMS, Event]:
|
||||
"""
|
||||
决定做什么,同时生成对应的事件
|
||||
"""
|
||||
@@ -39,7 +40,7 @@ class AI(ABC):
|
||||
return action_name, action_params, event
|
||||
|
||||
@abstractmethod
|
||||
def _decide(self, world: World) -> tuple[str, dict]:
|
||||
def _decide(self, world: World) -> ACTION_PAIR:
|
||||
"""
|
||||
决策逻辑:决定执行什么动作和参数
|
||||
由子类实现具体的决策逻辑
|
||||
@@ -50,7 +51,7 @@ class RuleAI(AI):
|
||||
"""
|
||||
规则AI
|
||||
"""
|
||||
def _decide(self, world: World) -> tuple[str, dict]:
|
||||
def _decide(self, world: World) -> ACTION_PAIR:
|
||||
"""
|
||||
决策逻辑:决定执行什么动作和参数
|
||||
先做一个简单的:
|
||||
@@ -92,7 +93,7 @@ class LLMAI(AI):
|
||||
不能每个单步step都调用一次LLM来决定下一步做什么。这样子一方面动作一直乱变,另一方面也太费token了。
|
||||
decide的作用是,拉取既有的动作链(如果没有了就call_llm),再根据动作链决定动作,以及动作之间的衔接。
|
||||
"""
|
||||
def _decide(self, world: World) -> tuple[str, dict]:
|
||||
def _decide(self, world: World) -> ACTION_PAIR:
|
||||
"""
|
||||
决策逻辑:通过LLM决定执行什么动作和参数
|
||||
"""
|
||||
|
||||
@@ -3,14 +3,15 @@ from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
|
||||
from src.classes.calendar import Month, Year, MonthStamp
|
||||
from src.classes.calendar import MonthStamp
|
||||
from src.classes.action import Action, ALL_ACTION_CLASSES
|
||||
from src.classes.world import World
|
||||
from src.classes.tile import Tile, Region
|
||||
from src.classes.cultivation import CultivationProgress, Realm
|
||||
from src.classes.cultivation import CultivationProgress
|
||||
from src.classes.root import Root
|
||||
from src.classes.age import Age
|
||||
from src.classes.event import NULL_EVENT
|
||||
from src.classes.typings import ACTION_NAME, ACTION_PARAMS, ACTION_PAIR
|
||||
|
||||
from src.classes.ai import AI, RuleAI, LLMAI
|
||||
from src.classes.persona import Persona, personas_by_id
|
||||
@@ -28,6 +29,9 @@ gender_strs = {
|
||||
Gender.FEMALE: "女",
|
||||
}
|
||||
|
||||
# 历史动作对的最大数量
|
||||
MAX_HISTORY_ACTIONS = 3
|
||||
|
||||
@dataclass
|
||||
class Avatar:
|
||||
"""
|
||||
@@ -48,8 +52,8 @@ class Avatar:
|
||||
root: Root = field(default_factory=lambda: random.choice(list(Root)))
|
||||
persona: Persona = field(default_factory=lambda: random.choice(list(personas_by_id.values())))
|
||||
ai: AI = None
|
||||
action_be_executed: Optional[Action] = None
|
||||
action_parmas_be_executed: Optional[dict] = None
|
||||
cur_action_pair: Optional[ACTION_PAIR] = None
|
||||
history_action_pairs: list[ACTION_PAIR] = field(default_factory=list)
|
||||
|
||||
def __post_init__(self):
|
||||
"""
|
||||
@@ -66,7 +70,7 @@ class Avatar:
|
||||
"""
|
||||
return f"Avatar(id={self.id}, 性别={self.gender}, 年龄={self.age}, name={self.name}, 区域={self.tile.region.name}, 灵根={self.root.value}, 境界={self.cultivation_progress})"
|
||||
|
||||
def create_action(self, action_name: str) -> Action:
|
||||
def create_action(self, action_name: ACTION_NAME) -> Action:
|
||||
"""
|
||||
根据动作名称创建新的action实例
|
||||
|
||||
@@ -95,21 +99,41 @@ class Avatar:
|
||||
"""
|
||||
event = NULL_EVENT
|
||||
|
||||
if self.action_be_executed is None:
|
||||
if self.cur_action_pair is None:
|
||||
# 决定动作时生成事件
|
||||
action_name, action_args, event = self.ai.decide(self.world)
|
||||
self.action_be_executed = self.create_action(action_name)
|
||||
self.action_parmas_be_executed = action_args
|
||||
action = self.create_action(action_name)
|
||||
self.cur_action_pair = (action, action_args)
|
||||
|
||||
# 纯粹执行动作,不产生事件
|
||||
self.action_be_executed.execute(**self.action_parmas_be_executed)
|
||||
action, action_params = self.cur_action_pair
|
||||
action.execute(**action_params)
|
||||
|
||||
if self.action_be_executed.is_finished(**self.action_parmas_be_executed):
|
||||
self.action_be_executed = None
|
||||
self.action_parmas_be_executed = None
|
||||
if action.is_finished(**action_params):
|
||||
# 将完成的动作对添加到历史记录中
|
||||
self._add_to_history(self.cur_action_pair)
|
||||
|
||||
return event
|
||||
|
||||
def _add_to_history(self, action_pair: ACTION_PAIR) -> None:
|
||||
"""
|
||||
将完成的动作对添加到历史记录中
|
||||
|
||||
Args:
|
||||
action_pair: 要添加的动作对
|
||||
|
||||
注意:
|
||||
- 如果历史记录达到上限,会丢弃最老的记录
|
||||
- 新的记录会被添加到列表末尾
|
||||
"""
|
||||
# 添加新的动作对到历史记录
|
||||
self.history_action_pairs.append(action_pair)
|
||||
self.cur_action_pair = None
|
||||
|
||||
# 如果超过上限,移除最老的记录
|
||||
if len(self.history_action_pairs) > MAX_HISTORY_ACTIONS:
|
||||
self.history_action_pairs.pop(0)
|
||||
|
||||
def update_cultivation(self, new_level: int):
|
||||
"""
|
||||
更新修仙进度,并在境界提升时更新寿命
|
||||
|
||||
5
src/classes/typings.py
Normal file
5
src/classes/typings.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from src.classes.action import Action
|
||||
|
||||
ACTION_NAME = str
|
||||
ACTION_PARAMS = dict
|
||||
ACTION_PAIR = tuple[Action, ACTION_PARAMS]
|
||||
@@ -419,6 +419,14 @@ class Front:
|
||||
f"个性: {avatar.persona.name}",
|
||||
f"位置: ({avatar.pos_x}, {avatar.pos_y})",
|
||||
]
|
||||
|
||||
# 添加历史动作信息
|
||||
lines.append("") # 空行分隔
|
||||
lines.append("历史动作:")
|
||||
for i, (action, params) in enumerate(avatar.history_action_pairs):
|
||||
action_name = action.__class__.__name__
|
||||
lines.append(f" {i+1}. {action_name}")
|
||||
|
||||
self._draw_tooltip(lines, *self.pygame.mouse.get_pos(), self.tooltip_font)
|
||||
|
||||
def _draw_tooltip_for_region(self, region, mouse_x: int, mouse_y: int):
|
||||
|
||||
Reference in New Issue
Block a user