自动战斗列表(初版)
This commit is contained in:
parent
e3e8b8b44a
commit
58356eb328
7 changed files with 141 additions and 28 deletions
71
mower/solvers/copy_works.py
Normal file
71
mower/solvers/copy_works.py
Normal file
|
@ -0,0 +1,71 @@
|
|||
import json
|
||||
|
||||
from mower.solvers.fight import FightSolver
|
||||
from mower.utils import config
|
||||
from mower.utils.path import get_path
|
||||
|
||||
|
||||
class Oper:
|
||||
def __init__(self, name, skill=1):
|
||||
self.name = name
|
||||
self.skill = skill
|
||||
|
||||
# 定义哈希函数,以便在 set 中去重
|
||||
def __hash__(self):
|
||||
return hash((self.name, self.skill))
|
||||
|
||||
# 定义相等性判断
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, Oper):
|
||||
return self.name == other.name and self.skill == other.skill
|
||||
return False
|
||||
|
||||
|
||||
class CopyWorksSolver:
|
||||
def run(self):
|
||||
self.auto_choose = True
|
||||
# if config.conf.work.try_select_all:
|
||||
# self.init_all_opers_and_groups()
|
||||
while len(config.conf.work.works):
|
||||
# if config.conf.work.try_select_all and not self.auto_choose:
|
||||
|
||||
work = config.conf.work.works[0]
|
||||
work_path = get_path(f"@app/works/{work["stage"]}.json")
|
||||
with work_path.open("r", encoding="utf-8") as f:
|
||||
work_data = json.load(f)
|
||||
if not FightSolver().run(
|
||||
work["stage"],
|
||||
work_data["opers"],
|
||||
work_data["actions"],
|
||||
work_data["groups"],
|
||||
self.auto_choose,
|
||||
work["support_oper"],
|
||||
work["retry_times"],
|
||||
):
|
||||
return
|
||||
config.conf.work.works.pop(0)
|
||||
|
||||
def init_all_opers_and_groups(self):
|
||||
all_opers = set()
|
||||
all_groups = set()
|
||||
for work in config.conf.work.works:
|
||||
work_path = get_path(f"@app/works/{work["stage"]}.json")
|
||||
with work_path.open("r", encoding="utf-8") as f:
|
||||
work_data = json.load(f)
|
||||
for oper in work_data["opers"]:
|
||||
name = oper["name"]
|
||||
skill = oper.get("skill", 1)
|
||||
all_opers.add(Oper(name, skill))
|
||||
for group in work_data["groups"]:
|
||||
all_groups.add(group)
|
||||
self.all_groups = [
|
||||
group
|
||||
for group in all_groups
|
||||
if not any(
|
||||
Oper(op["name"], op.get("skill", 1)) in all_opers
|
||||
for op in group["opers"]
|
||||
)
|
||||
]
|
||||
self.all_opers = list({"name": op.name, "skill": op.skill} for op in all_opers)
|
||||
if len(all_opers) + len(all_groups) <= 12:
|
||||
self.auto_choose = False
|
|
@ -5,13 +5,13 @@ from .battle_choose import BattleChooseSolver
|
|||
class FightSolver:
|
||||
def run(
|
||||
self,
|
||||
level_name,
|
||||
opers,
|
||||
actions,
|
||||
level_name: str,
|
||||
opers: list,
|
||||
actions: list,
|
||||
groups=[],
|
||||
auto_choose: bool = True,
|
||||
squad: int = None,
|
||||
support_oper: list = [],
|
||||
support_oper: str = "",
|
||||
retry_times: int = 5,
|
||||
):
|
||||
"""
|
||||
Args:
|
||||
|
@ -20,27 +20,41 @@ class FightSolver:
|
|||
actions: 行动列表
|
||||
groups: 干员组列表
|
||||
auto_choose: 是否自动选择干员编队
|
||||
squad: 队伍编号
|
||||
support_oper: 助战干员
|
||||
min_elite: 助战干员精英化等级的最低要求
|
||||
min_level: 助战干员等级的最低要求
|
||||
retry_times: 助战刷新次数
|
||||
retry_times: 战斗失败重试次数
|
||||
"""
|
||||
opers = self.check_opers_skill(opers)
|
||||
self.check_opers_skill(opers, groups)
|
||||
if support_oper:
|
||||
support_oper = self.find_support_oper(support_oper, opers, groups)
|
||||
if auto_choose:
|
||||
BattleChooseSolver().run(
|
||||
if not BattleChooseSolver().run(
|
||||
level_name,
|
||||
opers,
|
||||
groups,
|
||||
squad,
|
||||
support_oper,
|
||||
)
|
||||
AutoFight().run(level_name, opers, actions, groups)
|
||||
):
|
||||
return False
|
||||
while retry_times + 1:
|
||||
if AutoFight().run(level_name, opers, actions, groups):
|
||||
return True
|
||||
retry_times -= 1
|
||||
return False
|
||||
|
||||
def check_opers_skill(self, opers: list):
|
||||
def check_opers_skill(self, opers: list, groups: list):
|
||||
for oper in opers:
|
||||
if "skill" not in oper:
|
||||
oper["skill"] = 1
|
||||
if "skill_usage" not in oper:
|
||||
oper["skill_usage"] = 0
|
||||
return opers
|
||||
for group in groups:
|
||||
for oper in group["opers"]:
|
||||
if "skill" not in oper:
|
||||
oper["skill"] = 1
|
||||
if "skill_usage" not in oper:
|
||||
oper["skill_usage"] = 0
|
||||
|
||||
def find_support_oper(self, support_oper: str, opers: list, groups: list):
|
||||
for op in opers + groups:
|
||||
if op["name"] == support_oper:
|
||||
op["support"] = True
|
||||
return [op]
|
||||
|
|
|
@ -61,11 +61,6 @@ class AutoFight(SceneGraphSolver, FightMixin):
|
|||
logger.info("行动结束")
|
||||
return True
|
||||
|
||||
elif scene == Scene.CONFIRM:
|
||||
logger.warning("被顶号")
|
||||
self.success = False
|
||||
return True
|
||||
|
||||
elif scene in self.waiting_scene:
|
||||
self.waiting_solver()
|
||||
elif scene == Scene.OPERATOR_SELECT:
|
||||
|
|
|
@ -14,7 +14,6 @@ class BattleChooseSolver(SceneGraphSolver):
|
|||
level_name: str = "",
|
||||
opers: list = [],
|
||||
groups: list = [],
|
||||
squad: int = 0,
|
||||
support_oper: list = [],
|
||||
):
|
||||
"""
|
||||
|
@ -25,15 +24,18 @@ class BattleChooseSolver(SceneGraphSolver):
|
|||
squad: 队伍编号
|
||||
support_oper: 助战干员
|
||||
"""
|
||||
if squad:
|
||||
ChooseSquadSolver().run(level_name, squad)
|
||||
lack = BattleAgentChooseSolver().run(opers + groups)
|
||||
if config.conf.work.squad:
|
||||
ChooseSquadSolver().run(level_name, config.conf.work.squad)
|
||||
lack = BattleAgentChooseSolver().run(opers + groups, level_name)
|
||||
if len(lack) + len(support_oper) >= 2:
|
||||
return False
|
||||
if config.conf.choose.add_low_trust_opers:
|
||||
num = 12 - len(opers) - len(groups) + len(lack)
|
||||
BattleFillChooseSolver().run("信赖值", num)
|
||||
super().run()
|
||||
support_oper = support_oper if support_oper else lack
|
||||
ChooseSupportSolver().run(support_oper)
|
||||
return True
|
||||
|
||||
def transition(self):
|
||||
if (scene := self.scene()) == Scene.OPERATOR_AGENT_SELECT:
|
||||
|
|
|
@ -4,6 +4,7 @@ from mower.data import agent_list
|
|||
from mower.solvers.fight.battle_choose.battle_filter import BattleFilterSolver
|
||||
from mower.solvers.fight.battle_choose.battle_tag_choose import BattleTagChoose
|
||||
from mower.solvers.fight.battle_choose.choose_skill import ChooseSkillSolver
|
||||
from mower.solvers.navigation import NavigationSolver
|
||||
from mower.utils import config
|
||||
from mower.utils.character_recognize import (
|
||||
operator_team_select,
|
||||
|
@ -15,7 +16,7 @@ from mower.utils.scene import Scene
|
|||
|
||||
|
||||
class BattleAgentChooseSolver(SceneGraphSolver):
|
||||
def run(self, agents: list) -> None:
|
||||
def run(self, agents: list, level_name: str = "") -> None:
|
||||
if agents == []:
|
||||
raise ValueError("干员列表为空")
|
||||
self.agents = agents
|
||||
|
@ -29,6 +30,7 @@ class BattleAgentChooseSolver(SceneGraphSolver):
|
|||
self.lack = []
|
||||
self.tmp_data = None
|
||||
self.tag = "ALL"
|
||||
self.level_name = level_name
|
||||
super().run()
|
||||
|
||||
return self.lack
|
||||
|
@ -115,4 +117,4 @@ class BattleAgentChooseSolver(SceneGraphSolver):
|
|||
elif scene in self.waiting_scene:
|
||||
self.waiting_solver()
|
||||
else:
|
||||
return False
|
||||
NavigationSolver().run(self.level_name, mode="copy")
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
from typing import Literal
|
||||
|
||||
from pydantic import BaseModel, model_validator
|
||||
from pydantic_core import PydanticUndefined
|
||||
|
||||
from mower.utils.typealias import WorkItem
|
||||
|
||||
|
||||
class ConfModel(BaseModel):
|
||||
@model_validator(mode="before")
|
||||
|
@ -124,12 +128,30 @@ class FightPart(ConfModel):
|
|||
refresh: int = 10
|
||||
"最大刷新次数"
|
||||
|
||||
class WorkConf(ConfModel):
|
||||
work_enable: bool = False
|
||||
"是否执行自动作战列表"
|
||||
squad: int = 0
|
||||
"作战编队"
|
||||
use_medicine: bool = False
|
||||
"是否使用理智药"
|
||||
enemy_breach_strategy: Literal["overlook", "give_up", "restart_game"] = (
|
||||
"give_up"
|
||||
)
|
||||
"被敌人进入时采取的策略"
|
||||
try_select_all: bool = False
|
||||
"尝试一次性选择全部干员和干员组"
|
||||
works: list[WorkItem] = []
|
||||
"自动作战列表"
|
||||
|
||||
avatar_recog_pause: bool = False
|
||||
"作战中识别干员时暂停"
|
||||
choose: ChooseConf
|
||||
"自动选干员设置"
|
||||
support: SupportConf
|
||||
"借助战要求"
|
||||
work: WorkConf
|
||||
"自动作战列表设置"
|
||||
|
||||
|
||||
class LongTaskPart(ConfModel):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Dict, List, Tuple, Union
|
||||
from typing import Dict, List, Tuple, TypedDict, Union
|
||||
|
||||
import numpy as np
|
||||
from numpy.typing import NDArray
|
||||
|
@ -34,3 +34,10 @@ BasePlan = Dict[str, List[str]]
|
|||
|
||||
# Parameter
|
||||
ParamArgs = List[str]
|
||||
|
||||
|
||||
# Work
|
||||
class WorkItem(TypedDict):
|
||||
stage: str
|
||||
retry_times: int = 5
|
||||
support_oper: str = ""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue