update normalized name resolving logic
This commit is contained in:
@@ -4,6 +4,7 @@ from src.classes.action import InstantAction
|
||||
from src.classes.event import Event
|
||||
from src.classes.battle import decide_battle, get_effective_strength_pair
|
||||
from src.classes.story_teller import StoryTeller
|
||||
from src.classes.normalize import normalize_avatar_name
|
||||
|
||||
|
||||
class Battle(InstantAction):
|
||||
@@ -16,8 +17,13 @@ class Battle(InstantAction):
|
||||
)
|
||||
|
||||
def _get_target(self, avatar_name: str):
|
||||
"""
|
||||
根据名字查找目标角色;找不到返回 None。
|
||||
会自动规范化名字(去除括号等附加信息)以提高容错性。
|
||||
"""
|
||||
normalized_name = normalize_avatar_name(avatar_name)
|
||||
for v in self.world.avatar_manager.avatars.values():
|
||||
if v.name == avatar_name:
|
||||
if v.name == normalized_name:
|
||||
return v
|
||||
return None
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from src.classes.action import InstantAction
|
||||
from src.classes.event import Event
|
||||
from src.classes.battle import get_escape_success_rate
|
||||
from src.classes.action.event_helper import EventHelper
|
||||
from src.classes.normalize import normalize_avatar_name
|
||||
|
||||
|
||||
class Escape(InstantAction):
|
||||
@@ -18,8 +19,13 @@ class Escape(InstantAction):
|
||||
PARAMS = {"avatar_name": "AvatarName"}
|
||||
|
||||
def _find_avatar_by_name(self, name: str) -> "Avatar|None":
|
||||
"""
|
||||
根据名字查找角色;找不到返回 None。
|
||||
会自动规范化名字(去除括号等附加信息)以提高容错性。
|
||||
"""
|
||||
normalized_name = normalize_avatar_name(name)
|
||||
for v in self.world.avatar_manager.avatars.values():
|
||||
if v.name == name:
|
||||
if v.name == normalized_name:
|
||||
return v
|
||||
return None
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
from src.classes.action import TimedAction, Move
|
||||
from src.classes.event import Event
|
||||
from src.classes.action.move_helper import clamp_manhattan_with_diagonal_priority
|
||||
from src.classes.normalize import normalize_avatar_name
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -21,8 +22,13 @@ class MoveAwayFromAvatar(TimedAction):
|
||||
PARAMS = {"avatar_name": "AvatarName"}
|
||||
|
||||
def _find_avatar_by_name(self, name: str) -> "Avatar | None":
|
||||
"""
|
||||
根据名字查找角色;找不到返回 None。
|
||||
会自动规范化名字(去除括号等附加信息)以提高容错性。
|
||||
"""
|
||||
normalized_name = normalize_avatar_name(name)
|
||||
for v in self.world.avatar_manager.avatars.values():
|
||||
if v.name == name:
|
||||
if v.name == normalized_name:
|
||||
return v
|
||||
return None
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from src.classes.event import Event
|
||||
from src.classes.action import Move
|
||||
from src.classes.action_runtime import ActionResult, ActionStatus
|
||||
from src.classes.action.move_helper import clamp_manhattan_with_diagonal_priority
|
||||
from src.classes.normalize import normalize_avatar_name
|
||||
|
||||
|
||||
class MoveToAvatar(DefineAction, ActualActionMixin):
|
||||
@@ -19,9 +20,11 @@ class MoveToAvatar(DefineAction, ActualActionMixin):
|
||||
def _get_target(self, avatar_name: str):
|
||||
"""
|
||||
根据名字查找目标角色;找不到返回 None。
|
||||
会自动规范化名字(去除括号等附加信息)以提高容错性。
|
||||
"""
|
||||
normalized_name = normalize_avatar_name(avatar_name)
|
||||
for v in self.world.avatar_manager.avatars.values():
|
||||
if v.name == avatar_name:
|
||||
if v.name == normalized_name:
|
||||
return v
|
||||
return None
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from src.classes.event import Event
|
||||
from src.classes.region import CityRegion
|
||||
from src.classes.item import items_by_name
|
||||
from src.classes.prices import prices
|
||||
from src.classes.normalize import normalize_item_name
|
||||
|
||||
|
||||
class SellItems(InstantAction):
|
||||
@@ -22,8 +23,11 @@ class SellItems(InstantAction):
|
||||
if not isinstance(region, CityRegion):
|
||||
return
|
||||
|
||||
# 规范化物品名称(去除境界等附加信息)
|
||||
normalized_name = normalize_item_name(item_name)
|
||||
|
||||
# 找到物品
|
||||
item = items_by_name.get(item_name)
|
||||
item = items_by_name.get(normalized_name)
|
||||
if item is None:
|
||||
return
|
||||
|
||||
@@ -51,14 +55,22 @@ class SellItems(InstantAction):
|
||||
# 用于动作空间:只要背包非空即可
|
||||
ok = bool(self.avatar.items)
|
||||
return (ok, "" if ok else "背包为空,无可出售物品")
|
||||
item = items_by_name.get(item_name)
|
||||
|
||||
# 规范化物品名称
|
||||
normalized_name = normalize_item_name(item_name)
|
||||
item = items_by_name.get(normalized_name)
|
||||
if item is None:
|
||||
return False, f"未知物品: {item_name}"
|
||||
ok = self.avatar.get_item_quantity(item) > 0
|
||||
return (ok, "" if ok else "该物品数量为0")
|
||||
|
||||
def start(self, item_name: str) -> Event:
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在城镇出售 {item_name}", related_avatars=[self.avatar.id])
|
||||
# 规范化物品名称用于显示(与执行逻辑一致)
|
||||
normalized_name = normalize_item_name(item_name)
|
||||
# 尝试获取标准物品名(如果存在)
|
||||
item = items_by_name.get(normalized_name)
|
||||
display_name = item.name if item is not None else normalized_name
|
||||
return Event(self.world.month_stamp, f"{self.avatar.name} 在城镇出售 {display_name}", related_avatars=[self.avatar.id])
|
||||
|
||||
# InstantAction 已实现 step 完成
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from typing import Optional, Iterable
|
||||
|
||||
from src.classes.tile import get_avatar_distance
|
||||
from src.classes.observe import get_observable_avatars
|
||||
from src.classes.normalize import normalize_avatar_name
|
||||
|
||||
|
||||
class TargetingMixin:
|
||||
@@ -13,8 +14,15 @@ class TargetingMixin:
|
||||
注意:不做异常吞噬,失败路径返回 None 或 False,由调用方决策。
|
||||
"""
|
||||
def find_avatar_by_name(self, name: str) -> "Avatar|None":
|
||||
"""
|
||||
根据名字查找角色。
|
||||
会自动规范化名字(去除括号等附加信息)以提高容错性。
|
||||
|
||||
例如:查找 "张三(元婴)" 会自动匹配到名为 "张三" 的角色
|
||||
"""
|
||||
normalized_name = normalize_avatar_name(name)
|
||||
for v in self.world.avatar_manager.avatars.values():
|
||||
if v.name == name:
|
||||
if v.name == normalized_name:
|
||||
return v
|
||||
return None
|
||||
|
||||
|
||||
@@ -516,7 +516,7 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin):
|
||||
observed: list[str] = []
|
||||
if co_region_avatars:
|
||||
for other in co_region_avatars[:8]:
|
||||
observed.append(f"{other.name}(境界:{other.cultivation_progress.get_info()})")
|
||||
observed.append(f"{other.name},境界:{other.cultivation_progress.get_info()}")
|
||||
|
||||
# 历史事件改为从全局事件管理器查询
|
||||
n = CONFIG.social.event_context_num
|
||||
|
||||
132
src/classes/normalize.py
Normal file
132
src/classes/normalize.py
Normal file
@@ -0,0 +1,132 @@
|
||||
"""
|
||||
名称规范化工具模块
|
||||
|
||||
提供统一的名称规范化函数,用于处理各类名称中的括号和附加信息。
|
||||
适用于:角色名、地区名、物品名等。
|
||||
"""
|
||||
|
||||
|
||||
def _remove_parentheses(name: str) -> str:
|
||||
"""
|
||||
通用的括号移除函数:去除字符串中首个括号及其内容。
|
||||
|
||||
支持的括号类型:() () [] 【】 「」 『』 <> 《》
|
||||
|
||||
Args:
|
||||
name: 原始字符串
|
||||
|
||||
Returns:
|
||||
去除首个括号后的字符串(去除前后空格)
|
||||
|
||||
Examples:
|
||||
>>> _remove_parentheses("张三(元婴)")
|
||||
'张三'
|
||||
>>> _remove_parentheses("青云林海(千年古松(金丹))")
|
||||
'青云林海'
|
||||
>>> _remove_parentheses("青云鹿角 -(练气)")
|
||||
'青云鹿角 -'
|
||||
"""
|
||||
s = str(name).strip()
|
||||
brackets = [
|
||||
("(", ")"), ("(", ")"),
|
||||
("[", "]"), ("【", "】"),
|
||||
("「", "」"), ("『", "』"),
|
||||
("<", ">"), ("《", "》")
|
||||
]
|
||||
|
||||
for left, right in brackets:
|
||||
idx = s.find(left)
|
||||
if idx != -1:
|
||||
# 找到左括号,去除从此开始到字符串末尾的内容
|
||||
s = s[:idx].strip()
|
||||
break
|
||||
|
||||
return s
|
||||
|
||||
|
||||
def normalize_avatar_name(name: str) -> str:
|
||||
"""
|
||||
规范化角色名字:去除括号及其中的附加信息(如境界)。
|
||||
|
||||
Args:
|
||||
name: 原始角色名字,可能包含境界等附加信息
|
||||
|
||||
Returns:
|
||||
规范化后的角色名字
|
||||
|
||||
Examples:
|
||||
>>> normalize_avatar_name("张三(元婴)")
|
||||
'张三'
|
||||
>>> normalize_avatar_name("张三,境界:元婴")
|
||||
'张三,境界:元婴'
|
||||
"""
|
||||
return _remove_parentheses(name)
|
||||
|
||||
|
||||
def normalize_region_name(name: str) -> str:
|
||||
"""
|
||||
规范化地区名称:去除括号及其中的附加信息(如灵气密度、动植物等)。
|
||||
|
||||
处理多层括号:递归去除所有括号及其内容。
|
||||
|
||||
Args:
|
||||
name: 原始地区名称,可能包含资源等附加信息
|
||||
|
||||
Returns:
|
||||
规范化后的地区名称
|
||||
|
||||
Examples:
|
||||
>>> normalize_region_name("太白金府(金行灵气:10)")
|
||||
'太白金府'
|
||||
>>> normalize_region_name("青云林海(千年古松(金丹))")
|
||||
'青云林海'
|
||||
"""
|
||||
s = str(name).strip()
|
||||
brackets = [
|
||||
("(", ")"), ("(", ")"),
|
||||
("[", "]"), ("【", "】"),
|
||||
("「", "」"), ("『", "』"),
|
||||
("<", ">"), ("《", "》")
|
||||
]
|
||||
|
||||
# 递归去除所有括号(用于处理嵌套括号)
|
||||
while True:
|
||||
found = False
|
||||
for left, right in brackets:
|
||||
start = s.find(left)
|
||||
end = s.rfind(right)
|
||||
if start != -1 and end != -1 and end > start:
|
||||
s = (s[:start] + s[end + 1:]).strip()
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
break
|
||||
|
||||
return s
|
||||
|
||||
|
||||
def normalize_item_name(name: str) -> str:
|
||||
"""
|
||||
规范化物品名称:去除境界标识等附加信息。
|
||||
|
||||
处理格式:
|
||||
- "青云鹿角 -(练气)" -> "青云鹿角"
|
||||
- "风速马皮(筑基)" -> "风速马皮"
|
||||
|
||||
Args:
|
||||
name: 原始物品名称,可能包含境界等附加信息
|
||||
|
||||
Returns:
|
||||
规范化后的物品名称
|
||||
|
||||
Examples:
|
||||
>>> normalize_item_name("青云鹿角 -(练气)")
|
||||
'青云鹿角'
|
||||
>>> normalize_item_name("风速马皮(筑基)")
|
||||
'风速马皮'
|
||||
"""
|
||||
s = _remove_parentheses(name)
|
||||
# 额外处理:去除尾部的 " -" 标记
|
||||
s = s.rstrip(" -").strip()
|
||||
return s
|
||||
|
||||
Reference in New Issue
Block a user