From cc3ac7ef1b94ed8a88191ea2e86ed3d97800d224 Mon Sep 17 00:00:00 2001 From: status102 Date: Mon, 27 Nov 2023 16:22:44 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84BattleHelper?= =?UTF-8?q?=E7=9A=84m=5Fcur=5Fdeployment=5Fopers=E4=B8=BAvector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MaaCore/Task/BattleHelper.cpp | 15 ++++--- src/MaaCore/Task/BattleHelper.h | 2 +- .../Task/Miscellaneous/BattleProcessTask.cpp | 13 +++--- .../Roguelike/RoguelikeBattleTaskPlugin.cpp | 42 +++++++++---------- src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp | 16 +++---- 5 files changed, 48 insertions(+), 40 deletions(-) diff --git a/src/MaaCore/Task/BattleHelper.cpp b/src/MaaCore/Task/BattleHelper.cpp index 235bd69964..adc69b22f3 100644 --- a/src/MaaCore/Task/BattleHelper.cpp +++ b/src/MaaCore/Task/BattleHelper.cpp @@ -106,6 +106,7 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) } m_cur_deployment_opers.clear(); + // 从场上干员和已占用格子中移除冷却中的干员 auto remove_cooling_from_battlefield = [&](const DeploymentOper& oper) { if (!oper.cooling) { return; @@ -151,13 +152,13 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) } if (avatar_analyzer.analyze()) { set_oper_name(oper, avatar_analyzer.get_result().templ_info.name); - m_cur_deployment_opers.insert_or_assign(oper.name, oper); remove_cooling_from_battlefield(oper); } else { Log.info("unknown oper", oper.index); unknown_opers.emplace_back(oper); } + m_cur_deployment_opers.emplace_back(oper); if (oper.cooling) { Log.trace("stop matching cooling", oper.index); @@ -222,7 +223,11 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) set_oper_name(oper, name); remove_cooling_from_battlefield(oper); - m_cur_deployment_opers.insert_or_assign(name, oper); + auto oper_it = ranges::find_if(m_cur_deployment_opers, + [&](const auto& oper_in_list) { return oper_in_list.index == oper.index; }); + if (oper_it != m_cur_deployment_opers.end()) { + *oper_it = oper; + } AvatarCache.set_avatar(name, oper.role, oper.avatar); } pause(); @@ -756,11 +761,11 @@ std::optional asst::BattleHelper::get_oper_rect_on_deployment(const { LogTraceFunction; - auto oper_iter = m_cur_deployment_opers.find(name); - if (oper_iter == m_cur_deployment_opers.cend()) { + auto oper_iter = ranges::find_if(m_cur_deployment_opers, [&](const auto& oper) { return oper.name == name; }); + if (oper_iter == m_cur_deployment_opers.end()) { Log.error("No oper", name); return std::nullopt; } - return oper_iter->second.rect; + return oper_iter->rect; } diff --git a/src/MaaCore/Task/BattleHelper.h b/src/MaaCore/Task/BattleHelper.h index 3b7d1d721e..7e1efffc6a 100644 --- a/src/MaaCore/Task/BattleHelper.h +++ b/src/MaaCore/Task/BattleHelper.h @@ -84,7 +84,7 @@ namespace asst int m_total_kills = 0; int m_cost = 0; - std::map m_cur_deployment_opers; + std::vector m_cur_deployment_opers; std::map m_battlefield_opers; std::map m_used_tiles; diff --git a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp index cc92c9dafe..99ffa3a1a7 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp @@ -94,7 +94,7 @@ bool asst::BattleProcessTask::to_group() } std::unordered_set char_set; - for (const auto& oper : m_cur_deployment_opers | views::values) { + for (const auto& oper : m_cur_deployment_opers) { char_set.emplace(oper.name); } @@ -323,8 +323,8 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) if (!update_deployment(false, image)) { return false; } - size_t cooling_count = ranges::count_if(m_cur_deployment_opers | views::values, - [](const auto& oper) -> bool { return oper.cooling; }); + size_t cooling_count = + ranges::count_if(m_cur_deployment_opers, [](const auto& oper) -> bool { return oper.cooling; }); if (cooling_count == static_cast(action.cooling)) { break; } @@ -342,9 +342,10 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) } else if (!update_deployment(false, image)) { return false; - } - if (auto iter = m_cur_deployment_opers.find(name); - iter != m_cur_deployment_opers.cend() && iter->second.available) { + }; + if (auto iter = + ranges::find_if(m_cur_deployment_opers, [&](const auto& oper) { return oper.name == name; }); + iter != m_cur_deployment_opers.end() && iter->available) { break; } do_strategy_and_update_image(); diff --git a/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp index 217be8623f..53e1076bc7 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp @@ -251,8 +251,8 @@ asst::battle::OperPosition asst::RoguelikeBattleTaskPlugin::get_role_position(co void asst::RoguelikeBattleTaskPlugin::cache_oper_elite_status() { const auto& oper_list = m_config->get_oper(); - for (const std::string& name : m_cur_deployment_opers | views::keys) { - m_oper_elite.emplace(name, oper_list.contains(name) ? oper_list.at(name).elite : 0); + for (const auto& oper : m_cur_deployment_opers) { + m_oper_elite.emplace(oper.name, oper_list.contains(oper.name) ? oper_list.at(oper.name).elite : 0); } } @@ -335,7 +335,7 @@ bool asst::RoguelikeBattleTaskPlugin::do_best_deploy() const auto& groups = RoguelikeRecruit.get_group_info(m_config->get_theme()); // 获取当前肉鸽的分组内排名信息 // const auto& group_rank = RoguelikeRecruit.get_group_rank(rogue_theme); - for (const auto& [name, oper] : m_cur_deployment_opers) { + for (const auto& oper : m_cur_deployment_opers) { // 干员冷却中 if (oper.cooling) { Log.debug("operator", oper.name, "is cooling now."); @@ -383,9 +383,11 @@ bool asst::RoguelikeBattleTaskPlugin::do_best_deploy() std::sort(deploy_plan_list.begin(), deploy_plan_list.end()); for (const auto& deploy_plan : deploy_plan_list) { if (!m_used_tiles.contains(deploy_plan.placed) && - !m_blacklist_location.contains(deploy_plan.placed)) { // 判断该位置是否已被占据 - auto& oper = m_cur_deployment_opers[deploy_plan.oper_name]; - if (!oper.available) { // 等费 + !m_blacklist_location.contains(deploy_plan.placed) /* 判断该位置是否已被占据 */) { + + if (auto oper_it = ranges::find_if(m_cur_deployment_opers, + [&](const auto& oper) { return oper.name == deploy_plan.oper_name; }); + oper_it == m_cur_deployment_opers.end() || !oper_it->available) { // 等费 Log.trace(" best deploy is", deploy_plan.oper_name, "with rank", deploy_plan.rank, "but now waiting for cost."); return true; @@ -415,10 +417,10 @@ bool asst::RoguelikeBattleTaskPlugin::do_once() } std::unordered_set pre_cooling; - for (const auto& [name, oper] : m_cur_deployment_opers) { + for (const auto& oper : m_cur_deployment_opers) { if (oper.cooling) { - pre_cooling.emplace(name); - m_deployed_time.erase(name); + pre_cooling.emplace(oper.name); + m_deployed_time.erase(oper.name); } } @@ -446,13 +448,13 @@ bool asst::RoguelikeBattleTaskPlugin::do_once() std::unordered_set cur_cooling; size_t cur_available_count = 0; // without drones size_t cur_deployments_count = 0; // without drones - for (const auto& [name, oper] : m_cur_deployment_opers) { + for (const auto& oper : m_cur_deployment_opers) { if (oper.role == Role::Drone) continue; ++cur_deployments_count; if (oper.cooling) { - cur_cooling.emplace(name); - m_deployed_time.erase(name); + cur_cooling.emplace(oper.name); + m_deployed_time.erase(oper.name); } if (oper.available) ++cur_available_count; } @@ -483,11 +485,11 @@ bool asst::RoguelikeBattleTaskPlugin::do_once() m_cur_home_index = *urgent_home_opt; if (m_allow_to_use_dice) { - auto deployment_key_views = m_cur_deployment_opers | views::keys; - auto dice_key_iter = ranges::find_first_of(deployment_key_views, DiceSet); - if (dice_key_iter != deployment_key_views.end()) { + auto dice_key_iter = ranges::find_if(m_cur_deployment_opers, + [&](const auto& oper) { return DiceSet.contains(oper.name); }); + if (dice_key_iter != m_cur_deployment_opers.end()) { best_oper_is_dice = true; - best_oper = m_cur_deployment_opers[*dice_key_iter]; + best_oper = *dice_key_iter; } } } @@ -659,7 +661,7 @@ std::optional asst::RoguelikeBattleTaskPlugin::cal bool has_medic = false; bool has_blocking = false; bool has_air_defense = false; - for (const auto& oper : m_cur_deployment_opers | views::values) { + for (const auto& oper : m_cur_deployment_opers) { const auto& role = oper.role; switch (role) { case Role::Medic: @@ -695,13 +697,11 @@ std::optional asst::RoguelikeBattleTaskPlugin::cal Log.trace("use_air_defense", use_air_defense, ", use_blocking", use_blocking, ", use_medic", use_medic); std::vector cur_available; - for (const auto& oper : m_cur_deployment_opers | views::values) { + for (const auto& oper : m_cur_deployment_opers) { if (oper.available) cur_available.emplace_back(oper); } // 费用高的优先用,放前面 - ranges::sort(cur_available, [&](const auto& lhs, const auto& rhs) { - return m_cur_deployment_opers.at(lhs.name).cost > m_cur_deployment_opers.at(rhs.name).cost; - }); + ranges::sort(cur_available, [](const auto& lhs, const auto& rhs) { return lhs.cost > rhs.cost; }); DeploymentOper best_oper; diff --git a/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp b/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp index 1dc10aef83..5eff7d4987 100644 --- a/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp +++ b/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp @@ -92,7 +92,7 @@ bool asst::SSSBattleProcessTask::wait_until_start(bool weak) update_deployment(); ProcessTask(*this, { "SSSFightStart-PreSelect-Clear" }).run(); - auto m_cur_deployment_opers_value = m_cur_deployment_opers | views::values; + auto m_cur_deployment_opers_value = m_cur_deployment_opers; std::vector opers(m_cur_deployment_opers_value.begin(), m_cur_deployment_opers_value.end()); ranges::sort(opers, [](const DeploymentOper& a, const DeploymentOper& b) { return a.cost > b.cost; }); @@ -142,14 +142,14 @@ bool asst::SSSBattleProcessTask::check_and_do_strategy(const cv::Mat& reusable) std::unordered_map exist_core; std::vector tool_men; - for (const auto& [name, oper] : m_cur_deployment_opers) { - if (m_all_cores.contains(name)) { - exist_core.emplace(name, oper); + for (const auto& oper : m_cur_deployment_opers) { + if (m_all_cores.contains(oper.name)) { + exist_core.emplace(oper.name, oper); } else if (oper.is_unusual_location && !m_all_action_opers.contains(oper.name)) { tool_men.emplace_back(oper); // 工具人的技能一概好了就用 - m_skill_usage.try_emplace(name, SkillUsage::Possibly); + m_skill_usage.try_emplace(oper.name, SkillUsage::Possibly); } } @@ -209,13 +209,15 @@ bool asst::SSSBattleProcessTask::check_if_start_over(const battle::copilot::Acti update_deployment(); bool to_abandon = false; - if (!action.name.empty() && !m_cur_deployment_opers.contains(action.name) && + + if (!action.name.empty() && + !ranges::any_of(m_cur_deployment_opers, [&](const auto& oper) { return oper.name == action.name; }) && !m_battlefield_opers.contains(action.name)) { to_abandon = true; } else if (!action.role_counts.empty()) { std::unordered_map cur_counts; - for (const auto& oper : m_cur_deployment_opers | views::values) { + for (const auto& oper : m_cur_deployment_opers) { cur_counts[oper.role] += 1; } for (const auto& [role, number] : action.role_counts) {