Files
cultivation-world-simulator/src/classes/effect.py
2025-10-16 00:43:31 +08:00

65 lines
1.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
import json
import ast
from typing import Any
def load_effect_from_str(value: object) -> dict[str, Any]:
"""
解析 effects 字符串为 dict
- 支持 JSON 格式(双引号)
- 支持 Python 字面量(单引号,如 {'k': ['v']})
- value 为 None/空字符串/'nan' 时返回 {}
- 解析非 dict 则返回 {}
"""
if value is None:
return {}
if isinstance(value, dict):
return value
s = str(value).strip()
if not s or s == "nan":
return {}
try:
obj = json.loads(s)
return obj if isinstance(obj, dict) else {}
except Exception:
try:
obj = ast.literal_eval(s)
return obj if isinstance(obj, dict) else {}
except Exception:
return {}
def _merge_effects(base: dict[str, object], addition: dict[str, object]) -> dict[str, object]:
"""
合并两个 effects 字典:
- list 型(如 legal_actions做去重并集
- 数值型:相加
- 其他:后者覆盖前者
返回新字典,不修改原对象。
"""
if not base and not addition:
return {}
merged: dict[str, object] = dict(base) if base else {}
for key, val in (addition or {}).items():
if key in merged:
old = merged[key]
if isinstance(old, list) and isinstance(val, list):
# 去重并集,保持相对顺序
seen: set[object] = set()
result: list[object] = []
for x in old + val:
if x in seen:
continue
seen.add(x)
result.append(x)
merged[key] = result
elif isinstance(old, (int, float)) and isinstance(val, (int, float)):
merged[key] = old + val
else:
merged[key] = val
else:
merged[key] = val
return merged