mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-17 18:01:26 +08:00
feat: 保全作战相同location以json写的策略顺序执行
This commit is contained in:
@@ -233,14 +233,24 @@ namespace asst::battle
|
||||
RoleCounts tool_men;
|
||||
Point location;
|
||||
DeployDirection direction = DeployDirection::None;
|
||||
// 以下为非json解析字段
|
||||
int index;
|
||||
bool core_deployed = false; // 全局保core,再次识别到core则同location全部重置
|
||||
bool operator==(const Strategy& other) const
|
||||
{
|
||||
return index == other.index;
|
||||
}
|
||||
};
|
||||
|
||||
using StrategyOrderLock = std::unordered_map<Point, std::vector<std::shared_ptr<Strategy>>, Point::Hash>;
|
||||
|
||||
struct CombatData : public copilot::CombatData
|
||||
{
|
||||
std::vector<Strategy> strategies;
|
||||
bool draw_as_possible = false;
|
||||
int retry_times = 0;
|
||||
std::vector<std::string> order_of_drops;
|
||||
StrategyOrderLock order;
|
||||
};
|
||||
|
||||
enum class EquipmentType
|
||||
|
||||
@@ -75,7 +75,6 @@ namespace asst
|
||||
Point& operator=(const Point&) noexcept = default;
|
||||
Point& operator=(Point&&) noexcept = default;
|
||||
Point operator-() const noexcept { return { -x, -y }; }
|
||||
bool operator==(const Point& rhs) const noexcept { return x == rhs.x && y == rhs.y; }
|
||||
std::string to_string() const { return "(" + std::to_string(x) + ", " + std::to_string(y) + ")"; }
|
||||
explicit operator std::string() const { return to_string(); }
|
||||
static constexpr Point right() { return { 1, 0 }; }
|
||||
@@ -86,10 +85,21 @@ namespace asst
|
||||
bool empty() const noexcept { return x == 0 && y == 0; }
|
||||
// for std::map
|
||||
bool operator<(const Point& rhs) const noexcept { return x < rhs.x || (x == rhs.x && y < rhs.y); }
|
||||
bool operator==(const Point& rhs) const noexcept { return x == rhs.x && y == rhs.y; }
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
struct Hash
|
||||
{
|
||||
size_t operator()(const Point& p) const noexcept
|
||||
{
|
||||
auto h1 = std::hash<int> {}(p.x);
|
||||
auto h2 = std::hash<int> {}(p.y);
|
||||
return h1 ^ (h2 << 1); // Combine hash values
|
||||
}
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
#define DEFINE_ASST_POINT_BINARY_OP_AND_ARG_ASSIGN(Op) \
|
||||
friend Point operator Op(const Point& lhs, const Point& rhs) noexcept \
|
||||
|
||||
@@ -66,6 +66,7 @@ bool asst::SSSCopilotConfig::parse(const json::value& json)
|
||||
stage_data.order_of_drops = m_data.order_of_drops;
|
||||
stage_data.retry_times = stage.get("retry_times", 0);
|
||||
|
||||
int index = 0;
|
||||
for (const auto& strategy_info : stage.at("strategies").as_array()) {
|
||||
Strategy strategy;
|
||||
strategy.core = strategy_info.get("core", std::string());
|
||||
@@ -73,6 +74,16 @@ bool asst::SSSCopilotConfig::parse(const json::value& json)
|
||||
strategy.location.x = strategy_info.at("location").at(0).as_integer();
|
||||
strategy.location.y = strategy_info.at("location").at(1).as_integer();
|
||||
strategy.direction = CopilotConfig::string_to_direction(strategy_info.get("direction", "Right"));
|
||||
// 步骤(strategy)间锁,以部署位置为key,保证core不被顶替
|
||||
strategy.index = index;
|
||||
if (auto it = stage_data.order.find(strategy.location); it != stage_data.order.cend()) {
|
||||
it->second.emplace_back(std::make_shared<Strategy>(strategy));
|
||||
}
|
||||
else {
|
||||
std::vector<std::shared_ptr<Strategy>> strategy_list { std::make_shared<Strategy>(strategy) };
|
||||
stage_data.order.emplace(strategy.location, strategy_list);
|
||||
}
|
||||
index++;
|
||||
stage_data.strategies.emplace_back(std::move(strategy));
|
||||
}
|
||||
std::string ocr_code;
|
||||
|
||||
@@ -198,6 +198,12 @@ bool asst::SSSBattleProcessTask::check_and_do_strategy(const cv::Mat& reusable)
|
||||
}
|
||||
|
||||
for (auto& strategy : m_sss_combat_data.strategies) {
|
||||
// 步骤(strategy)间锁,以部署位置为key,保证core不被顶替
|
||||
auto it = m_sss_combat_data.order.find(strategy.location);
|
||||
if (*(it->second.front()) != strategy) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool use_the_core = ranges::all_of(strategy.tool_men, [](const auto& pair) { return pair.second <= 0; }) &&
|
||||
!strategy.core.empty() && exist_core.contains(strategy.core);
|
||||
if (use_the_core) {
|
||||
@@ -224,6 +230,15 @@ bool asst::SSSBattleProcessTask::check_and_do_strategy(const cv::Mat& reusable)
|
||||
tool_men, [&](const DeploymentOper& oper) { return oper.available && oper.role == role_for_lambda; });
|
||||
if (available_iter != tool_men.cend()) {
|
||||
--quantity;
|
||||
// 每个tool_men用尽之后删除m_sss_combat_data.strategies中tool_men的当前元素
|
||||
// 重新执行该location所有策略时用m_sss_combat_data.order进行恢复
|
||||
if (quantity <= 0) {
|
||||
strategy.tool_men.erase(role);
|
||||
if (strategy.tool_men.empty() && strategy.core.empty()) {
|
||||
(it->second).emplace_back((it->second).front());
|
||||
(it->second).erase((it->second).begin());
|
||||
}
|
||||
}
|
||||
// 部署完,画面会发生变化,所以直接返回,后续逻辑交给下次循环处理
|
||||
return deploy_oper(available_iter->name, strategy.location, strategy.direction) && update_deployment();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user