add actual action space
This commit is contained in:
@@ -128,12 +128,21 @@ class ActualActionMixin():
|
||||
"""
|
||||
pass
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def is_doable(self) -> bool:
|
||||
"""
|
||||
判断动作是否可以执行
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Move(DefineAction, ChunkActionMixin):
|
||||
"""
|
||||
最基础的移动动作,在tile之间进行切换。
|
||||
"""
|
||||
COMMENT = "移动到某个相对位置"
|
||||
PARAMS = {"delta_x": "int", "delta_y": "int"}
|
||||
def _execute(self, delta_x: int, delta_y: int) -> None:
|
||||
"""
|
||||
移动到某个tile
|
||||
@@ -157,6 +166,7 @@ class MoveToRegion(DefineAction, ActualActionMixin):
|
||||
移动到某个region
|
||||
"""
|
||||
COMMENT = "移动到某个区域"
|
||||
PARAMS = {"region": "region_name"}
|
||||
def _execute(self, region: Region|str) -> None:
|
||||
"""
|
||||
移动到某个region
|
||||
@@ -194,12 +204,20 @@ class MoveToRegion(DefineAction, ActualActionMixin):
|
||||
region_name = str(region)
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始移动向 {region_name}")
|
||||
|
||||
@property
|
||||
def is_doable(self) -> bool:
|
||||
"""
|
||||
判断移动到区域动作是否可以执行
|
||||
"""
|
||||
return True
|
||||
|
||||
@long_action(step_month=10)
|
||||
class Cultivate(DefineAction, ActualActionMixin):
|
||||
"""
|
||||
修炼动作,可以增加修仙进度。
|
||||
"""
|
||||
COMMENT = "修炼,增进修为"
|
||||
PARAMS = {}
|
||||
def _execute(self) -> None:
|
||||
"""
|
||||
修炼
|
||||
@@ -226,6 +244,13 @@ class Cultivate(DefineAction, ActualActionMixin):
|
||||
"""
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在 {self.avatar.tile.region.name} 开始修炼")
|
||||
|
||||
@property
|
||||
def is_doable(self) -> bool:
|
||||
"""
|
||||
判断修炼动作是否可以执行
|
||||
"""
|
||||
return self.avatar.cultivation_progress.can_cultivate()
|
||||
|
||||
|
||||
# 突破境界class
|
||||
@long_action(step_month=1)
|
||||
@@ -234,6 +259,7 @@ class Breakthrough(DefineAction, ActualActionMixin):
|
||||
突破境界
|
||||
"""
|
||||
COMMENT = "尝试突破境界"
|
||||
PARAMS = {}
|
||||
def calc_success_rate(self) -> float:
|
||||
"""
|
||||
计算突破境界的成功率
|
||||
@@ -255,12 +281,20 @@ class Breakthrough(DefineAction, ActualActionMixin):
|
||||
"""
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始尝试突破境界")
|
||||
|
||||
@property
|
||||
def is_doable(self) -> bool:
|
||||
"""
|
||||
判断突破动作是否可以执行
|
||||
"""
|
||||
return self.avatar.cultivation_progress.can_break_through()
|
||||
|
||||
@long_action(step_month=6)
|
||||
class Play(DefineAction, ActualActionMixin):
|
||||
"""
|
||||
游戏娱乐动作,持续半年时间
|
||||
"""
|
||||
COMMENT = "游戏娱乐,放松身心"
|
||||
PARAMS = {}
|
||||
|
||||
def _execute(self) -> None:
|
||||
"""
|
||||
@@ -276,12 +310,11 @@ class Play(DefineAction, ActualActionMixin):
|
||||
"""
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 开始玩耍")
|
||||
|
||||
@property
|
||||
def is_doable(self) -> bool:
|
||||
return True
|
||||
|
||||
ALL_ACTION_CLASSES = [Move, Cultivate, Breakthrough, MoveToRegion, Play]
|
||||
ACTION_SPACE = [
|
||||
# {"action": "Move", "params": {"delta_x": int, "delta_y": int}, "comment": Move.COMMENT},
|
||||
{"action": "Cultivate", "params": {}, "comment": Cultivate.COMMENT},
|
||||
{"action": "Breakthrough", "params": {}, "comment": Breakthrough.COMMENT},
|
||||
{"action": "MoveToRegion", "params": {"region": "region_name"}, "comment": MoveToRegion.COMMENT},
|
||||
{"action": "Play", "params": {}, "comment": Play.COMMENT},
|
||||
]
|
||||
ACTION_SPACE_STR = json.dumps(ACTION_SPACE, ensure_ascii=False)
|
||||
ALL_ACTUAL_ACTION_CLASSES = [Cultivate, Breakthrough, MoveToRegion, Play]
|
||||
ALL_ACTION_NAMES = ["Move", "Cultivate", "Breakthrough", "MoveToRegion", "Play"]
|
||||
ALL_ACTUAL_ACTION_NAMES = ["Cultivate", "Breakthrough", "MoveToRegion", "Play"]
|
||||
@@ -11,7 +11,6 @@ import random
|
||||
from src.classes.world import World
|
||||
from src.classes.tile import Region
|
||||
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_async
|
||||
from src.classes.typings import ACTION_NAME, ACTION_PARAMS, ACTION_PAIR
|
||||
@@ -84,9 +83,7 @@ class RuleAI(AI):
|
||||
class LLMAI(AI):
|
||||
"""
|
||||
LLM AI
|
||||
"""
|
||||
# TODO:动作链
|
||||
"""
|
||||
一些思考:
|
||||
AI动作应该分两类:
|
||||
1. 动作链,一定时间内的长期规划,动作按照这个动作链来执行(以及何时终止并执行下一个动作)
|
||||
2. 突发情况,比如突然有人要攻击NPC,这个时候的反应
|
||||
@@ -97,7 +94,7 @@ class LLMAI(AI):
|
||||
"""
|
||||
异步决策逻辑:通过LLM决定执行什么动作和参数
|
||||
"""
|
||||
action_space_str = ACTION_SPACE_STR
|
||||
action_space_str = self.avatar.get_action_space_str()
|
||||
avatar_infos_str = str(self.avatar)
|
||||
regions_str = "\n".join([str(region) for region in world.map.regions.values()])
|
||||
avatar_persona = self.avatar.persona.prompt
|
||||
|
||||
@@ -2,9 +2,10 @@ import random
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
import json
|
||||
|
||||
from src.classes.calendar import MonthStamp
|
||||
from src.classes.action import Action, ALL_ACTION_CLASSES
|
||||
from src.classes.action import Action, ALL_ACTUAL_ACTION_CLASSES, ALL_ACTION_CLASSES, ALL_ACTUAL_ACTION_NAMES
|
||||
from src.classes.world import World
|
||||
from src.classes.tile import Tile, Region
|
||||
from src.classes.cultivation import CultivationProgress
|
||||
@@ -190,6 +191,20 @@ class Avatar:
|
||||
"""
|
||||
return "\n".join([f"{action.__class__.__name__}: {action_params}" for action, action_params in self.history_action_pairs])
|
||||
|
||||
def get_action_space_str(self) -> str:
|
||||
action_space = self.get_action_space()
|
||||
action_space_str = json.dumps(action_space, ensure_ascii=False)
|
||||
return action_space_str
|
||||
|
||||
def get_action_space(self) -> list[dict]:
|
||||
"""
|
||||
获取动作空间
|
||||
"""
|
||||
actual_actions = [self.create_action(action_cls_name) for action_cls_name in ALL_ACTUAL_ACTION_NAMES]
|
||||
doable_actions = [action for action in actual_actions if action.is_doable]
|
||||
action_space = [{"action": action.__class__.__name__, "params": action.PARAMS, "comment": action.COMMENT} for action in doable_actions]
|
||||
return action_space
|
||||
|
||||
def get_new_avatar_from_ordinary(world: World, current_month_stamp: MonthStamp, name: str, age: Age):
|
||||
"""
|
||||
从凡人中来的新修士
|
||||
|
||||
Reference in New Issue
Block a user