From 396acc47d491497b9c5ba1579f06196d91b41435 Mon Sep 17 00:00:00 2001 From: lhhxxxxx <91231470+lhhxxxxx@users.noreply.github.com> Date: Tue, 2 Aug 2022 01:48:16 +0800 Subject: [PATCH] =?UTF-8?q?perf.=20=E4=BD=BF=E7=94=A8ranges=E5=8F=8Aviews?= =?UTF-8?q?=E5=8F=8A<=3D>=E5=8F=8A=E5=85=B6=E4=BB=96=E4=B8=80=E4=BA=9Bc++2?= =?UTF-8?q?0=E4=BC=98=E5=8C=96=E5=8F=8A=E4=B8=80=E8=88=AC=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MeoAssistant/AbstractTaskPlugin.cpp | 9 +- src/MeoAssistant/AbstractTaskPlugin.h | 4 +- src/MeoAssistant/Assistant.cpp | 3 +- src/MeoAssistant/AutoRecruitTask.cpp | 82 ++++++------ src/MeoAssistant/BattleDataConfiger.cpp | 3 +- src/MeoAssistant/BattleFormationTask.cpp | 4 +- src/MeoAssistant/BattleImageAnalyzer.cpp | 14 +- src/MeoAssistant/BattleProcessTask.cpp | 13 +- src/MeoAssistant/Controller.cpp | 4 +- src/MeoAssistant/CopilotConfiger.h | 2 +- src/MeoAssistant/CreditShopImageAnalyzer.cpp | 13 +- src/MeoAssistant/DepotImageAnalyzer.cpp | 4 +- src/MeoAssistant/InfrastDormTask.cpp | 6 +- .../InfrastFacilityImageAnalyzer.cpp | 5 +- src/MeoAssistant/InfrastOfficeTask.cpp | 12 +- src/MeoAssistant/InfrastOperImageAnalyzer.cpp | 56 ++++---- src/MeoAssistant/InfrastPowerTask.cpp | 10 +- src/MeoAssistant/InfrastProductionTask.cpp | 122 +++++++++--------- src/MeoAssistant/InfrastReceptionTask.cpp | 4 +- src/MeoAssistant/ItemConfiger.cpp | 11 +- src/MeoAssistant/MultiMatchImageAnalyzer.cpp | 47 +++---- src/MeoAssistant/OcrImageAnalyzer.cpp | 72 +++++------ src/MeoAssistant/RecruitConfiger.cpp | 2 +- src/MeoAssistant/RecruitConfiger.h | 33 ++--- src/MeoAssistant/RecruitImageAnalyzer.cpp | 2 +- .../RoguelikeBattleTaskPlugin.cpp | 13 +- .../RoguelikeFormationTaskPlugin.cpp | 4 +- .../RoguelikeRecruitImageAnalyzer.cpp | 14 +- .../RoguelikeRecruitTaskPlugin.cpp | 8 +- .../RoguelikeShoppingTaskPlugin.cpp | 13 +- src/MeoAssistant/StageDropsImageAnalyzer.cpp | 20 +-- src/MeoAssistant/StageDropsTaskPlugin.cpp | 2 +- src/MeoAssistant/TaskData.cpp | 4 +- src/MeoAssistant/TemplResource.cpp | 2 +- tools/ResourceUpdater/main.cpp | 13 +- 35 files changed, 322 insertions(+), 308 deletions(-) diff --git a/src/MeoAssistant/AbstractTaskPlugin.cpp b/src/MeoAssistant/AbstractTaskPlugin.cpp index 6677579f34..0926202134 100644 --- a/src/MeoAssistant/AbstractTaskPlugin.cpp +++ b/src/MeoAssistant/AbstractTaskPlugin.cpp @@ -25,7 +25,12 @@ void asst::AbstractTaskPlugin::set_task_ptr(asst::AbstractTask* ptr) m_task_ptr = ptr; } -bool asst::AbstractTaskPlugin::operator<(const asst::AbstractTaskPlugin& rhs) const +std::strong_ordering asst::AbstractTaskPlugin::operator<=>(const asst::AbstractTaskPlugin& rhs) const { - return priority() < rhs.priority(); + return priority() <=> rhs.priority(); +} + +bool asst::AbstractTaskPlugin::operator==(const AbstractTaskPlugin& rhs) const +{ + return priority() == rhs.priority(); } diff --git a/src/MeoAssistant/AbstractTaskPlugin.h b/src/MeoAssistant/AbstractTaskPlugin.h index 613faef33d..656a32be3f 100644 --- a/src/MeoAssistant/AbstractTaskPlugin.h +++ b/src/MeoAssistant/AbstractTaskPlugin.h @@ -22,7 +22,9 @@ namespace asst virtual bool verify(AsstMsg msg, const json::value& details) const = 0; - bool operator<(const AbstractTaskPlugin& rhs) const; + std::strong_ordering operator<=>(const AbstractTaskPlugin& rhs) const; + + bool operator==(const AbstractTaskPlugin& rhs) const; protected: diff --git a/src/MeoAssistant/Assistant.cpp b/src/MeoAssistant/Assistant.cpp index a721335a64..b83e2e14f2 100644 --- a/src/MeoAssistant/Assistant.cpp +++ b/src/MeoAssistant/Assistant.cpp @@ -1,6 +1,7 @@ #include "Assistant.h" #include +#include #include @@ -179,7 +180,7 @@ std::vector asst::Assistant::get_tasks_list() const { std::vector result; std::unique_lock lock(m_mutex); - for (const auto& [id, _] : m_tasks_list) { + for (const auto& id : m_tasks_list | std::views::keys) { result.emplace_back(id); } return result; diff --git a/src/MeoAssistant/AutoRecruitTask.cpp b/src/MeoAssistant/AutoRecruitTask.cpp index 9190f22055..a3fc952609 100644 --- a/src/MeoAssistant/AutoRecruitTask.cpp +++ b/src/MeoAssistant/AutoRecruitTask.cpp @@ -17,7 +17,7 @@ namespace asst::recruit_calc { rcs_with_single_tag.reserve(tags.size()); - std::transform(tags.cbegin(), tags.cend(), std::back_inserter(rcs_with_single_tag), [](const std::string& t) + std::ranges::transform(tags, std::back_inserter(rcs_with_single_tag), [](const std::string& t) { RecruitCombs result; result.tags = { t }; @@ -43,8 +43,8 @@ namespace asst::recruit_calc for (auto& rc : rcs_with_single_tag) { rc.avg_level /= static_cast(rc.opers.size()); // intersection and union are based on sorted container - std::sort(rc.tags.begin(), rc.tags.end()); - std::sort(rc.opers.begin(), rc.opers.end()); + std::ranges::sort(rc.tags); + std::ranges::sort(rc.opers); } } @@ -164,11 +164,11 @@ std::optional asst::AutoRecruitTask::try_get_start_button(const cv:: if (!start_analyzer.analyze()) return std::nullopt; start_analyzer.sort_result_horizontal(); auto iter = - std::find_if(start_analyzer.get_result().cbegin(), start_analyzer.get_result().cend(), - [&](const TextRect& r) -> bool - { - return m_force_skipped.find(slot_index_from_rect(r.rect)) == m_force_skipped.cend(); - }); + std::ranges::find_if(std::as_const(start_analyzer.get_result()), + [&](const TextRect& r) -> bool + { + return !m_force_skipped.contains(slot_index_from_rect(r.rect)); + }); if (iter == start_analyzer.get_result().cend()) return std::nullopt; Log.info("Found slot index", slot_index_from_rect(iter->rect), "."); return iter->rect; @@ -255,7 +255,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc bool has_refresh = !image_analyzer.get_refresh_rect().empty(); std::vector tag_names; - std::transform(tags.begin(), tags.end(), std::back_inserter(tag_names), std::mem_fn(&TextRect::text)); + std::ranges::transform(tags, std::back_inserter(tag_names), std::mem_fn(&TextRect::text)); bool has_special_tag = false; bool has_robot_tag = false; @@ -264,7 +264,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc { json::value info = basic_info(); std::vector tag_json_vector; - std::transform(tags.begin(), tags.end(), std::back_inserter(tag_json_vector), std::mem_fn(&TextRect::text)); + std::ranges::transform(tags, std::back_inserter(tag_json_vector), std::mem_fn(&TextRect::text)); info["what"] = "RecruitTagsDetected"; info["details"] = json::object{{ "tags", json::array(tag_json_vector) }}; @@ -273,7 +273,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc // special tags const std::vector SpecialTags = { "高级资深干员", "资深干员" }; - auto special_iter = std::find_first_of(SpecialTags.cbegin(), SpecialTags.cend(), tag_names.cbegin(), tag_names.cend()); + auto special_iter = std::ranges::find_first_of(SpecialTags, std::as_const(tag_names)); if (special_iter != SpecialTags.cend()) { json::value info = basic_info(); info["what"] = "RecruitSpecialTag"; @@ -284,7 +284,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc // robot tags const std::vector RobotTags = { "支援机械" }; - auto robot_iter = std::find_first_of(RobotTags.cbegin(), RobotTags.cend(), tag_names.cbegin(), tag_names.cend()); + auto robot_iter = std::ranges::find_first_of(RobotTags, std::as_const(tag_names)); if (robot_iter != RobotTags.cend()) { json::value info = basic_info(); info["what"] = "RecruitRobotTag"; @@ -307,35 +307,31 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc } } - std::sort( - result_vec.begin(), result_vec.end(), - [&](const RecruitCombs& lhs, const RecruitCombs& rhs) -> bool - { - // prefer the one with special tag - // workaround for https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/1336 - if (has_special_tag) { - bool l_has = - std::find_first_of( - lhs.tags.cbegin(), lhs.tags.cend(), - SpecialTags.cbegin(), SpecialTags.cend() - ) != lhs.tags.cend(); - bool r_has = - std::find_first_of( - rhs.tags.cbegin(), rhs.tags.cend(), - SpecialTags.cbegin(), SpecialTags.cend() - ) != rhs.tags.cend(); - if (l_has != r_has) return l_has > r_has; - } + std::ranges::sort(result_vec + , + [&](const RecruitCombs& lhs, const RecruitCombs& rhs) -> bool + { + // prefer the one with special tag + // workaround for https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/1336 + if (has_special_tag) { + bool l_has = + std::ranges::find_first_of(lhs.tags, SpecialTags + ) != lhs.tags.cend(); + bool r_has = + std::ranges::find_first_of(rhs.tags, SpecialTags + ) != rhs.tags.cend(); + if (l_has != r_has) return l_has > r_has; + } - if (lhs.min_level != rhs.min_level) - return lhs.min_level > rhs.min_level; // 最小等级大的,排前面 - else if (lhs.max_level != rhs.max_level) - return lhs.max_level > rhs.max_level; // 最大等级大的,排前面 - else if (std::fabs(lhs.avg_level - rhs.avg_level) > DoubleDiff) - return lhs.avg_level > rhs.avg_level; // 平均等级高的,排前面 - else - return lhs.tags.size() < rhs.tags.size(); // Tag数量少的,排前面 - } + if (lhs.min_level != rhs.min_level) + return lhs.min_level > rhs.min_level; // 最小等级大的,排前面 + else if (lhs.max_level != rhs.max_level) + return lhs.max_level > rhs.max_level; // 最大等级大的,排前面 + else if (std::fabs(lhs.avg_level - rhs.avg_level) > DoubleDiff) + return lhs.avg_level > rhs.avg_level; // 平均等级高的,排前面 + else + return lhs.tags.size() < rhs.tags.size(); // Tag数量少的,排前面 + } ); @@ -420,7 +416,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc if (!is_calc_only_task()) { // do not confirm, force skip - if (std::none_of(m_confirm_level.cbegin(), m_confirm_level.cend(), [&](const auto& i) { return i == final_combination.min_level; })) { + if (std::ranges::none_of(std::as_const(m_confirm_level), [&](const auto& i) { return i == final_combination.min_level; })) { calc_task_result_type result; result.success = true; result.force_skip = true; @@ -443,7 +439,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc } // nothing to select, leave the selection empty - if (std::none_of(m_select_level.cbegin(), m_select_level.cend(), [&](const auto& i) { return i == final_combination.min_level; })) { + if (std::ranges::none_of(std::as_const(m_select_level), [&](const auto& i) { return i == final_combination.min_level; })) { calc_task_result_type result; result.success = true; result.force_skip = false; @@ -454,7 +450,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc // select tags for (const std::string& final_tag_name : final_combination.tags) { auto tag_rect_iter = - std::find_if(tags.cbegin(), tags.cend(), [&](const TextRect& r) { return r.text == final_tag_name; }); + std::ranges::find_if(tags, [&](const TextRect& r) { return r.text == final_tag_name; }); if (tag_rect_iter != tags.cend()) { m_ctrler->click(tag_rect_iter->rect); } diff --git a/src/MeoAssistant/BattleDataConfiger.cpp b/src/MeoAssistant/BattleDataConfiger.cpp index 586a16ca32..3a22d9d2d0 100644 --- a/src/MeoAssistant/BattleDataConfiger.cpp +++ b/src/MeoAssistant/BattleDataConfiger.cpp @@ -1,10 +1,11 @@ #include "BattleDataConfiger.h" +#include #include bool asst::BattleDataConfiger::parse(const json::value& json) { - for (const auto& [id, char_data_json] : json.at("chars").as_object()) { + for (const auto& char_data_json : json.at("chars").as_object() | std::views::values) { BattleCharData data; std::string name = char_data_json.at("name").as_string(); data.name = name; diff --git a/src/MeoAssistant/BattleFormationTask.cpp b/src/MeoAssistant/BattleFormationTask.cpp index 7aded579b6..3646378160 100644 --- a/src/MeoAssistant/BattleFormationTask.cpp +++ b/src/MeoAssistant/BattleFormationTask.cpp @@ -1,5 +1,7 @@ #include "BattleFormationTask.h" +#include + #include "Resource.h" #include "Controller.h" #include "ProcessTask.h" @@ -29,7 +31,7 @@ bool asst::BattleFormationTask::_run() json::value info = basic_info_with_what("BattleFormation"); auto& details = info["details"]; auto& formation = details["formation"]; - for (const auto& [name, oper_vec] : m_groups) { + for (const auto& name : m_groups | std::views::keys) { formation.array_emplace(name); } callback(AsstMsg::SubTaskExtraInfo, info); diff --git a/src/MeoAssistant/BattleImageAnalyzer.cpp b/src/MeoAssistant/BattleImageAnalyzer.cpp index 03742c4f08..56d699f5d4 100644 --- a/src/MeoAssistant/BattleImageAnalyzer.cpp +++ b/src/MeoAssistant/BattleImageAnalyzer.cpp @@ -116,7 +116,7 @@ void asst::BattleImageAnalyzer::clear() noexcept void asst::BattleImageAnalyzer::sort_opers_by_cost() { // 本来游戏就是按费用排的,这里倒序一下就行了 - std::reverse(m_opers.begin(), m_opers.end()); + std::ranges::reverse(m_opers); } bool asst::BattleImageAnalyzer::opers_analyze() @@ -500,8 +500,8 @@ bool asst::BattleImageAnalyzer::kills_analyze() // 例子中的"0" std::string kills_count = kills_text.substr(0, pos); if (kills_count.empty() || - !std::all_of(kills_count.cbegin(), kills_count.cend(), - [](char c) -> bool {return std::isdigit(c);})) { + !std::ranges::all_of(std::as_const(kills_count), + [](char c) -> bool {return std::isdigit(c);})) { return false; } int cur_kills = std::stoi(kills_count); @@ -511,8 +511,8 @@ bool asst::BattleImageAnalyzer::kills_analyze() std::string total_kills = kills_text.substr(pos + 1, std::string::npos); int cur_total_kills = 0; if (total_kills.empty() || - !std::all_of(total_kills.cbegin(), total_kills.cend(), - [](char c) -> bool {return std::isdigit(c);})) { + !std::ranges::all_of(std::as_const(total_kills), + [](char c) -> bool {return std::isdigit(c);})) { Log.warn("total kills recognition failed, set to", m_pre_total_kills); cur_total_kills = m_pre_total_kills; } @@ -539,8 +539,8 @@ bool asst::BattleImageAnalyzer::cost_analyze() std::string cost_str = cost_analyzer.get_result().front().text; if (cost_str.empty() || - !std::all_of(cost_str.cbegin(), cost_str.cend(), - [](char c) -> bool {return std::isdigit(c);})) { + !std::ranges::all_of(std::as_const(cost_str), + [](char c) -> bool {return std::isdigit(c);})) { return false; } m_cost = std::stoi(cost_str); diff --git a/src/MeoAssistant/BattleProcessTask.cpp b/src/MeoAssistant/BattleProcessTask.cpp index 9226c7c05a..66c398705f 100644 --- a/src/MeoAssistant/BattleProcessTask.cpp +++ b/src/MeoAssistant/BattleProcessTask.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "NoWarningCV.h" @@ -179,10 +180,10 @@ bool asst::BattleProcessTask::analyze_opers_preview() bool not_found = true; // 找出这个干员是哪个组里的,以及他的技能用法等 for (const auto& [group_name, deploy_opers] : m_copilot_data.groups) { - auto iter = std::find_if(deploy_opers.cbegin(), deploy_opers.cend(), - [&](const BattleDeployOper& deploy) -> bool { - return deploy.name == oper_name; - }); + auto iter = std::ranges::find_if(deploy_opers, + [&](const BattleDeployOper& deploy) -> bool { + return deploy.name == oper_name; + }); if (iter != deploy_opers.cend()) { m_group_to_oper_mapping.emplace(group_name, *iter); not_found = false; @@ -249,7 +250,7 @@ bool asst::BattleProcessTask::update_opers_info(const cv::Mat& image) // 干员也可能是撤退下来的,把所有已使用的都拿出来比较下 for (auto iter = m_all_opers_info.cbegin(); iter != m_all_opers_info.cend(); ++iter) { const std::string& key = iter->first; - if (pre_opers_info.find(key) == pre_opers_info.cend()) { + if (!pre_opers_info.contains(key)) { ranged_iters.emplace_back(iter); } } @@ -595,7 +596,7 @@ bool asst::BattleProcessTask::try_possible_skill(const cv::Mat& image) MatchImageAnalyzer analyzer(image); analyzer.set_task_info(task_ptr); bool used = false; - for (auto& [name, info] : m_used_opers) { + for (auto& info : m_used_opers | std::views::values) { if (info.info.skill_usage != BattleSkillUsage::Possibly && info.info.skill_usage != BattleSkillUsage::Once) { continue; diff --git a/src/MeoAssistant/Controller.cpp b/src/MeoAssistant/Controller.cpp index 61db6eb5d0..d215ef3545 100644 --- a/src/MeoAssistant/Controller.cpp +++ b/src/MeoAssistant/Controller.cpp @@ -566,7 +566,7 @@ std::optional asst::Controller::try_to_init_socket(const std::st void asst::Controller::wait(unsigned id) const noexcept { - static const auto delay = std::chrono::milliseconds(10); + static constexpr auto delay = std::chrono::milliseconds(10); while (id > m_completed_id) { std::this_thread::sleep_for(delay); } @@ -1006,7 +1006,7 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a std::string uuid_str( std::make_move_iterator(uuid_result.begin()), std::make_move_iterator(uuid_result.end())); - uuid_str.erase(std::remove(uuid_str.begin(), uuid_str.end(), ' '), uuid_str.end()); + std::erase(uuid_str, ' '); m_uuid = std::move(uuid_str); json::value info = get_info_json() | diff --git a/src/MeoAssistant/CopilotConfiger.h b/src/MeoAssistant/CopilotConfiger.h index 5542a9e52b..64d157abc7 100644 --- a/src/MeoAssistant/CopilotConfiger.h +++ b/src/MeoAssistant/CopilotConfiger.h @@ -11,7 +11,7 @@ namespace asst bool contains_actions(const std::string& stage_name) const noexcept { - return m_battle_actions.find(stage_name) != m_battle_actions.cend(); + return m_battle_actions.contains(stage_name); } auto get_actions(const std::string& stage_name) const noexcept diff --git a/src/MeoAssistant/CreditShopImageAnalyzer.cpp b/src/MeoAssistant/CreditShopImageAnalyzer.cpp index 745503e96c..17a797f7e9 100644 --- a/src/MeoAssistant/CreditShopImageAnalyzer.cpp +++ b/src/MeoAssistant/CreditShopImageAnalyzer.cpp @@ -1,5 +1,7 @@ #include "CreditShopImageAnalyzer.h" +#include + #include "NoWarningCV.h" #include "MatchImageAnalyzer.h" @@ -89,11 +91,10 @@ bool asst::CreditShopImageAnalyzer::whether_to_buy_analyze() } if (m_is_white_list) { - std::sort(m_need_to_buy.begin(), m_need_to_buy.end(), [&]( - const auto& lhs, const auto& rhs) -> bool { - return std::find(m_shopping_list.cbegin(), m_shopping_list.cend(), lhs.second) - < std::find(m_shopping_list.cbegin(), m_shopping_list.cend(), rhs.second); - }); + std::ranges::sort(m_need_to_buy, [&](const auto& lhs, const auto& rhs) -> bool { + return std::find(m_shopping_list.cbegin(), m_shopping_list.cend(), lhs.second) + < std::find(m_shopping_list.cbegin(), m_shopping_list.cend(), rhs.second); + }); } return !m_need_to_buy.empty(); @@ -105,7 +106,7 @@ bool asst::CreditShopImageAnalyzer::sold_out_analyze() MatchImageAnalyzer sold_out_analyzer(m_image); sold_out_analyzer.set_task_info("CreditShop-SoldOut"); - for (const auto& [commodity, _] : m_need_to_buy) { + for (const auto& commodity : m_need_to_buy | std::views::keys) { sold_out_analyzer.set_roi(commodity); if (sold_out_analyzer.analyze()) { #ifdef ASST_DEBUG diff --git a/src/MeoAssistant/DepotImageAnalyzer.cpp b/src/MeoAssistant/DepotImageAnalyzer.cpp index aef8d36c38..3d302e4f07 100644 --- a/src/MeoAssistant/DepotImageAnalyzer.cpp +++ b/src/MeoAssistant/DepotImageAnalyzer.cpp @@ -281,8 +281,8 @@ int asst::DepotImageAnalyzer::match_quantity(const Rect& roi) //} if (digit_str.empty() || - !std::all_of(digit_str.cbegin(), digit_str.cend(), - [](char c) -> bool {return std::isdigit(c) || c == '.';})) { + !std::ranges::all_of(std::as_const(digit_str), + [](char c) -> bool {return std::isdigit(c) || c == '.';})) { return 0; } diff --git a/src/MeoAssistant/InfrastDormTask.cpp b/src/MeoAssistant/InfrastDormTask.cpp index 292774185c..0ea3e1e5b1 100644 --- a/src/MeoAssistant/InfrastDormTask.cpp +++ b/src/MeoAssistant/InfrastDormTask.cpp @@ -37,7 +37,7 @@ bool asst::InfrastDormTask::_run() bool asst::InfrastDormTask::opers_choose() { - int num_of_selected = 0; + size_t num_of_selected = 0; while (num_of_selected < max_num_of_opers()) { if (need_exit()) { return false; @@ -45,7 +45,7 @@ bool asst::InfrastDormTask::opers_choose() const auto image = m_ctrler->get_image(); InfrastOperImageAnalyzer oper_analyzer(image); - const int without_skill = InfrastOperImageAnalyzer::All ^ InfrastOperImageAnalyzer::Skill; + constexpr int without_skill = InfrastOperImageAnalyzer::All ^ InfrastOperImageAnalyzer::Skill; oper_analyzer.set_to_be_calced(without_skill); if (!oper_analyzer.analyze()) { Log.error("mood analyze failed!"); @@ -54,7 +54,7 @@ bool asst::InfrastDormTask::opers_choose() oper_analyzer.sort_by_mood(); const auto& oper_result = oper_analyzer.get_result(); - int num_of_resting = 0; + size_t num_of_resting = 0; for (const auto& oper : oper_result) { if (need_exit()) { return false; diff --git a/src/MeoAssistant/InfrastFacilityImageAnalyzer.cpp b/src/MeoAssistant/InfrastFacilityImageAnalyzer.cpp index 4e9c789853..01bf1f98bb 100644 --- a/src/MeoAssistant/InfrastFacilityImageAnalyzer.cpp +++ b/src/MeoAssistant/InfrastFacilityImageAnalyzer.cpp @@ -57,9 +57,8 @@ bool asst::InfrastFacilityImageAnalyzer::analyze() } const auto& cur_res = mm_analyzer.get_result(); - auto cur_max_iter = std::max_element( - cur_res.cbegin(), cur_res.cend(), - [](const MatchRect& lhs, const MatchRect& rhs) -> bool { + auto cur_max_iter = + std::ranges::max_element(cur_res, [](const MatchRect& lhs, const MatchRect& rhs) -> bool { return lhs.score < rhs.score; }); if (cur_max_iter == cur_res.cend()) { diff --git a/src/MeoAssistant/InfrastOfficeTask.cpp b/src/MeoAssistant/InfrastOfficeTask.cpp index 6041c5a9ac..c11535eec1 100644 --- a/src/MeoAssistant/InfrastOfficeTask.cpp +++ b/src/MeoAssistant/InfrastOfficeTask.cpp @@ -22,11 +22,11 @@ bool asst::InfrastOfficeTask::_run() } swipe_to_the_left_of_operlist(); - auto find_iter = std::find_if( - m_all_available_opers.begin(), m_all_available_opers.end(), - [&](const infrast::Oper& info) -> bool { - return info.selected; - }); + auto find_iter = std::ranges::find_if(m_all_available_opers + , + [&](const infrast::Oper& info) -> bool { + return info.selected; + }); bool need_shift = true; if (find_iter != m_all_available_opers.end()) { @@ -63,4 +63,4 @@ bool asst::InfrastOfficeTask::_run() click_return_button(); return true; -} \ No newline at end of file +} diff --git a/src/MeoAssistant/InfrastOperImageAnalyzer.cpp b/src/MeoAssistant/InfrastOperImageAnalyzer.cpp index 7edd306a93..7f5b9a824a 100644 --- a/src/MeoAssistant/InfrastOperImageAnalyzer.cpp +++ b/src/MeoAssistant/InfrastOperImageAnalyzer.cpp @@ -1,5 +1,7 @@ #include "InfrastOperImageAnalyzer.h" +#include + #include "NoWarningCV.h" #include "InfrastSmileyImageAnalyzer.h" @@ -43,37 +45,34 @@ void asst::InfrastOperImageAnalyzer::sort_by_loc() { LogTraceFunction; - std::sort( - m_result.begin(), m_result.end(), - [](const infrast::Oper& lhs, const infrast::Oper& rhs) -> bool { - if (std::abs(lhs.rect.x - rhs.rect.x) < 5) { // x差距较小则理解为是同一排的,按y排序 - return lhs.rect.y < rhs.rect.y; - } - else { - return lhs.rect.x < rhs.rect.x; - } - }); + std::ranges::sort(m_result, [](const infrast::Oper& lhs, const infrast::Oper& rhs) -> bool { + if (std::abs(lhs.rect.x - rhs.rect.x) < 5) { + // x差距较小则理解为是同一排的,按y排序 + return lhs.rect.y < rhs.rect.y; + } + else { + return lhs.rect.x < rhs.rect.x; + } + }); } void asst::InfrastOperImageAnalyzer::sort_by_mood() { LogTraceFunction; - std::sort( - m_result.begin(), m_result.end(), - [](const infrast::Oper& lhs, const infrast::Oper& rhs) -> bool { - // 先按心情排序,心情低的放前面 - if (std::fabs(lhs.mood_ratio - rhs.mood_ratio) > DoubleDiff) { - return lhs.mood_ratio < rhs.mood_ratio; - } - // 心情一样的就按位置排序,左边的放前面 - if (std::abs(lhs.rect.x - rhs.rect.x) > 5) { - return lhs.rect.x < rhs.rect.x; - } - else { - return lhs.rect.y < rhs.rect.y; - } - }); + std::ranges::sort(m_result, [](const infrast::Oper& lhs, const infrast::Oper& rhs) -> bool { + // 先按心情排序,心情低的放前面 + if (std::fabs(lhs.mood_ratio - rhs.mood_ratio) > DoubleDiff) { + return lhs.mood_ratio < rhs.mood_ratio; + } + // 心情一样的就按位置排序,左边的放前面 + if (std::abs(lhs.rect.x - rhs.rect.x) > 5) { + return lhs.rect.x < rhs.rect.x; + } + else { + return lhs.rect.y < rhs.rect.y; + } + }); } void asst::InfrastOperImageAnalyzer::oper_detect() @@ -272,7 +271,7 @@ void asst::InfrastOperImageAnalyzer::skill_analyze() std::vector> possible_skills; // 逐个该设施内所有可能的技能,取得分最高的 - for (const auto& [id, skill] : Resrc.infrast().get_skills(m_facility)) { + for (const auto& skill : Resrc.infrast().get_skills(m_facility) | std::views::values) { skill_analyzer.set_templ_name(skill.templ_name); if (!skill_analyzer.analyze()) { @@ -296,9 +295,8 @@ void asst::InfrastOperImageAnalyzer::skill_analyze() else if (possible_skills.size() > 1) { // 匹配得分最高的id作为基准,排除有识别错误,其他的技能混进来了的情况 // 即排除容器中,除了有同一个技能的不同等级,还有别的技能的情况 - auto max_iter = std::max_element( - possible_skills.begin(), possible_skills.end(), - [](const auto& lhs, const auto& rhs) -> bool { + auto max_iter = + std::ranges::max_element(possible_skills, [](const auto& lhs, const auto& rhs) -> bool { return lhs.second.score < rhs.second.score; }); double base_score = max_iter->second.score; diff --git a/src/MeoAssistant/InfrastPowerTask.cpp b/src/MeoAssistant/InfrastPowerTask.cpp index fbcc9ba619..859bfd9495 100644 --- a/src/MeoAssistant/InfrastPowerTask.cpp +++ b/src/MeoAssistant/InfrastPowerTask.cpp @@ -34,11 +34,11 @@ bool asst::InfrastPowerTask::_run() opers_detect(); } - auto find_iter = std::find_if( - m_all_available_opers.begin(), m_all_available_opers.end(), - [&](const infrast::Oper& info) -> bool { - return info.selected; - }); + auto find_iter = std::ranges::find_if(m_all_available_opers + , + [&](const infrast::Oper& info) -> bool { + return info.selected; + }); bool need_shift = true; if (find_iter != m_all_available_opers.end()) { switch (m_work_mode) { diff --git a/src/MeoAssistant/InfrastProductionTask.cpp b/src/MeoAssistant/InfrastProductionTask.cpp index 176b3834b7..7bcc691b43 100644 --- a/src/MeoAssistant/InfrastProductionTask.cpp +++ b/src/MeoAssistant/InfrastProductionTask.cpp @@ -206,17 +206,17 @@ size_t asst::InfrastProductionTask::opers_detect() //--cur_available_num; continue; } - auto find_iter = std::find_if( - m_all_available_opers.cbegin(), m_all_available_opers.cend(), - [&](const infrast::Oper& oper) -> bool { - if (oper.skills != cur_oper.skills) { - return false; - } - // 有可能是同一个干员,比一下hash - int dist = HashImageAnalyzer::hamming(cur_oper.face_hash, oper.face_hash); - Log.debug("opers_detect hash dist |", dist); - return dist < face_hash_thres; - }); + auto find_iter = std::ranges::find_if(std::as_const(m_all_available_opers) + , + [&](const infrast::Oper& oper) -> bool { + if (oper.skills != cur_oper.skills) { + return false; + } + // 有可能是同一个干员,比一下hash + int dist = HashImageAnalyzer::hamming(cur_oper.face_hash, oper.face_hash); + Log.debug("opers_detect hash dist |", dist); + return dist < face_hash_thres; + }); // 如果两个的hash距离过小,则认为是同一个干员,不进行插入 if (find_iter != m_all_available_opers.cend()) { continue; @@ -244,10 +244,10 @@ bool asst::InfrastProductionTask::optimal_calc() std::vector optimal_combs; optimal_combs.reserve(cur_max_num_of_opers); double max_efficient = 0; - std::sort(all_available_combs.begin(), all_available_combs.end(), - [&](const infrast::SkillsComb& lhs, const infrast::SkillsComb& rhs) -> bool { - return lhs.efficient.at(m_product) > rhs.efficient.at(m_product); - }); + std::ranges::sort(all_available_combs, + [&](const infrast::SkillsComb& lhs, const infrast::SkillsComb& rhs) -> bool { + return lhs.efficient.at(m_product) > rhs.efficient.at(m_product); + }); for (const auto& comb : all_available_combs) { std::string skill_str; @@ -329,11 +329,11 @@ bool asst::InfrastProductionTask::optimal_calc() // necessary里的技能,一个都不能少 // TODO necessary暂时没做hash校验。因为没有需要比hash的necessary干员( for (const infrast::SkillsComb& nec_skills : group.necessary) { - auto find_iter = std::find_if( - cur_available_opers.cbegin(), cur_available_opers.cend(), - [&](const infrast::SkillsComb& arg) -> bool { - return arg == nec_skills; - }); + auto find_iter = std::ranges::find_if(std::as_const(cur_available_opers) + , + [&](const infrast::SkillsComb& arg) -> bool { + return arg == nec_skills; + }); if (find_iter == cur_available_opers.cend()) { group_unavailable = true; break; @@ -360,11 +360,11 @@ bool asst::InfrastProductionTask::optimal_calc() } } - std::sort(optional.begin(), optional.end(), - [&](const infrast::SkillsComb& lhs, - const infrast::SkillsComb& rhs) -> bool { - return lhs.efficient.at(m_product) > rhs.efficient.at(m_product); - }); + std::ranges::sort(optional, + [&](const infrast::SkillsComb& lhs, + const infrast::SkillsComb& rhs) -> bool { + return lhs.efficient.at(m_product) > rhs.efficient.at(m_product); + }); // 可能有多个干员有同样的技能,所以这里需要循环找同一个技能,直到找不到为止 for (const infrast::SkillsComb& opt : optional) { @@ -389,8 +389,8 @@ bool asst::InfrastProductionTask::optimal_calc() continue; } std::string name = name_analyzer.get_result().front().text; - hash_matched = std::find( - opt.name_filter.cbegin(), opt.name_filter.cend(), name) + hash_matched = std::ranges::find(opt.name_filter + , name) != opt.name_filter.cend(); } if (!hash_matched) { @@ -496,37 +496,37 @@ bool asst::InfrastProductionTask::opers_choose() auto cur_all_opers = oper_analyzer.get_result(); Log.trace("before mood filter, opers size:", cur_all_opers.size()); // 小于心情阈值的干员则不可用 - auto remove_iter = std::remove_if(cur_all_opers.begin(), cur_all_opers.end(), - [&](const infrast::Oper& rhs) -> bool { - return rhs.mood_ratio < m_mood_threshold; - }); + auto remove_iter = std::ranges::remove_if(cur_all_opers, + [&](const infrast::Oper& rhs) -> bool { + return rhs.mood_ratio < m_mood_threshold; + }).begin(); cur_all_opers.erase(remove_iter, cur_all_opers.end()); Log.trace("after mood filter, opers size:", cur_all_opers.size()); for (auto opt_iter = m_optimal_combs.begin(); opt_iter != m_optimal_combs.end();) { Log.trace("to find", opt_iter->skills.begin()->names.front()); - auto find_iter = std::find_if( - cur_all_opers.cbegin(), cur_all_opers.cend(), - [&](const infrast::Oper& lhs) -> bool { - if (lhs.skills != opt_iter->skills) { - return false; - } - if (opt_iter->name_filter.empty()) { - return true; - } - else { - OcrWithPreprocessImageAnalyzer name_analyzer(lhs.name_img); - name_analyzer.set_replace( - Task.get("CharsNameOcrReplace")->replace_map); - Log.trace("Analyze name filter"); - if (!name_analyzer.analyze()) { - return false; - } - std::string name = name_analyzer.get_result().front().text; - return std::find( - opt_iter->name_filter.cbegin(), opt_iter->name_filter.cend(), name) - != opt_iter->name_filter.cend(); - } - }); + auto find_iter = std::ranges::find_if(std::as_const(cur_all_opers) + , + [&](const infrast::Oper& lhs) -> bool { + if (lhs.skills != opt_iter->skills) { + return false; + } + if (opt_iter->name_filter.empty()) { + return true; + } + else { + OcrWithPreprocessImageAnalyzer name_analyzer(lhs.name_img); + name_analyzer.set_replace( + Task.get("CharsNameOcrReplace")->replace_map); + Log.trace("Analyze name filter"); + if (!name_analyzer.analyze()) { + return false; + } + std::string name = name_analyzer.get_result().front().text; + return std::ranges::find(std::as_const(opt_iter->name_filter) + , name) + != opt_iter->name_filter.cend(); + } + }); if (find_iter == cur_all_opers.cend()) { ++opt_iter; @@ -547,13 +547,13 @@ bool asst::InfrastProductionTask::opers_choose() m_ctrler->click(find_iter->rect); } { - auto avlb_iter = std::find_if( - m_all_available_opers.cbegin(), m_all_available_opers.cend(), - [&](const infrast::Oper& lhs) -> bool { - int dist = HashImageAnalyzer::hamming(lhs.face_hash, find_iter->face_hash); - Log.debug("opers_choose | face hash dist", dist); - return dist < face_hash_thres; - } + auto avlb_iter = std::ranges::find_if(std::as_const(m_all_available_opers) + , + [&](const infrast::Oper& lhs) -> bool { + int dist = HashImageAnalyzer::hamming(lhs.face_hash, find_iter->face_hash); + Log.debug("opers_choose | face hash dist", dist); + return dist < face_hash_thres; + } ); if (avlb_iter != m_all_available_opers.cend()) { m_all_available_opers.erase(avlb_iter); diff --git a/src/MeoAssistant/InfrastReceptionTask.cpp b/src/MeoAssistant/InfrastReceptionTask.cpp index 5982cf6ec5..2fb6419601 100644 --- a/src/MeoAssistant/InfrastReceptionTask.cpp +++ b/src/MeoAssistant/InfrastReceptionTask.cpp @@ -1,5 +1,7 @@ #include "InfrastReceptionTask.h" +#include + #include "Controller.h" #include "InfrastClueImageAnalyzer.h" #include "InfrastClueVacancyImageAnalyzer.h" @@ -70,7 +72,7 @@ bool asst::InfrastReceptionTask::use_clue() if (!vacancy_analyzer.analyze()) { } const auto& vacancy = vacancy_analyzer.get_vacancy(); - for (auto&& [id, _] : vacancy) { + for (const auto& id : vacancy | std::views::keys) { Log.trace("InfrastReceptionTask | Vacancy", id); } diff --git a/src/MeoAssistant/ItemConfiger.cpp b/src/MeoAssistant/ItemConfiger.cpp index 96dca49bf1..efd4b7d192 100644 --- a/src/MeoAssistant/ItemConfiger.cpp +++ b/src/MeoAssistant/ItemConfiger.cpp @@ -1,5 +1,6 @@ #include "ItemConfiger.h" +#include #include #include "Logger.hpp" @@ -20,13 +21,13 @@ bool asst::ItemConfiger::parse(const json::value& json) m_ordered_material_item_id.clear(); m_ordered_material_item_id.reserve(material_sortid.size()); - for (const auto& [item_id, _] : material_sortid) { + for (const auto& item_id : material_sortid | std::views::keys) { m_ordered_material_item_id.emplace_back(item_id); } - std::sort(m_ordered_material_item_id.begin(), m_ordered_material_item_id.end(), - [&](const std::string& lhs, const std::string& rhs) -> bool { - return material_sortid[lhs] < material_sortid[rhs]; - }); + std::ranges::sort(m_ordered_material_item_id, + [&](const std::string& lhs, const std::string& rhs) -> bool { + return material_sortid[lhs] < material_sortid[rhs]; + }); return true; } diff --git a/src/MeoAssistant/MultiMatchImageAnalyzer.cpp b/src/MeoAssistant/MultiMatchImageAnalyzer.cpp index b5ef709534..2cdc2ceb25 100644 --- a/src/MeoAssistant/MultiMatchImageAnalyzer.cpp +++ b/src/MeoAssistant/MultiMatchImageAnalyzer.cpp @@ -1,5 +1,6 @@ #include "MultiMatchImageAnalyzer.h" +#include #include #include "NoWarningCV.h" @@ -31,29 +32,29 @@ bool asst::MultiMatchImageAnalyzer::analyze() void asst::MultiMatchImageAnalyzer::sort_result_horizontal() { // 按位置排个序 - std::sort(m_result.begin(), m_result.end(), - [](const MatchRect& lhs, const MatchRect& rhs) -> bool { - if (std::abs(lhs.rect.y - rhs.rect.y) < 5) { // y差距较小则理解为是同一排的,按x排序 - return lhs.rect.x < rhs.rect.x; - } - else { - return lhs.rect.y < rhs.rect.y; - } - }); + std::ranges::sort(m_result, + [](const MatchRect& lhs, const MatchRect& rhs) -> bool { + if (std::abs(lhs.rect.y - rhs.rect.y) < 5) { // y差距较小则理解为是同一排的,按x排序 + return lhs.rect.x < rhs.rect.x; + } + else { + return lhs.rect.y < rhs.rect.y; + } + }); } void asst::MultiMatchImageAnalyzer::sort_result_vertical() { // 按位置排个序 - std::sort(m_result.begin(), m_result.end(), - [](const MatchRect& lhs, const MatchRect& rhs) -> bool { - if (std::abs(lhs.rect.x - rhs.rect.x) < 5) { // x差距较小则理解为是同一排的,按y排序 - return lhs.rect.y < rhs.rect.y; - } - else { - return lhs.rect.x < rhs.rect.x; - } - }); + std::ranges::sort(m_result, + [](const MatchRect& lhs, const MatchRect& rhs) -> bool { + if (std::abs(lhs.rect.x - rhs.rect.x) < 5) { // x差距较小则理解为是同一排的,按y排序 + return lhs.rect.y < rhs.rect.y; + } + else { + return lhs.rect.x < rhs.rect.x; + } + }); } void asst::MultiMatchImageAnalyzer::set_mask_range(int lower, int upper) noexcept @@ -131,11 +132,11 @@ bool asst::MultiMatchImageAnalyzer::multi_match_templ(const cv::Mat templ) bool need_push = true; // 如果有两个点离得太近,只取里面得分高的那个 // 一般相邻的都是刚刚push进去的,这里倒序快一点 - for (auto iter = m_result.rbegin(); iter != m_result.rend(); ++iter) { - if (std::abs(j + m_roi.x - iter->rect.x) < mini_distance && std::abs(i + m_roi.y - iter->rect.y) < mini_distance) { - if (iter->score < value) { - iter->rect = rect; - iter->score = value; + for (auto& iter : std::ranges::reverse_view(m_result)) { + if (std::abs(j + m_roi.x - iter.rect.x) < mini_distance && std::abs(i + m_roi.y - iter.rect.y) < mini_distance) { + if (iter.score < value) { + iter.rect = rect; + iter.score = value; } // else 这个点就放弃了 need_push = false; break; diff --git a/src/MeoAssistant/OcrImageAnalyzer.cpp b/src/MeoAssistant/OcrImageAnalyzer.cpp index 290a8e6c89..d8e5cb559a 100644 --- a/src/MeoAssistant/OcrImageAnalyzer.cpp +++ b/src/MeoAssistant/OcrImageAnalyzer.cpp @@ -27,7 +27,7 @@ bool asst::OcrImageAnalyzer::analyze() if (!m_required.empty()) { if (m_full_match) { TextRectProc required_match = [&](TextRect& tr) -> bool { - return std::find(m_required.cbegin(), m_required.cend(), tr.text) != m_required.cend(); + return std::ranges::find(std::as_const(m_required), tr.text) != m_required.cend(); }; preds_vec.emplace_back(required_match); } @@ -40,7 +40,7 @@ bool asst::OcrImageAnalyzer::analyze() tr.text = str; return true; }; - return std::find_if(m_required.cbegin(), m_required.cend(), is_sub) != m_required.cend(); + return std::ranges::find_if(std::as_const(m_required), is_sub) != m_required.cend(); }; preds_vec.emplace_back(required_search); } @@ -162,15 +162,15 @@ const std::vector& asst::OcrImageAnalyzer::get_result() const no void asst::OcrImageAnalyzer::sort_result_horizontal() { // 按位置排个序 - std::sort(get_result().begin(), get_result().end(), - [](const TextRect& lhs, const TextRect& rhs) -> bool { - if (std::abs(lhs.rect.y - rhs.rect.y) < 5) { // y差距较小则理解为是同一排的,按x排序 - return lhs.rect.x < rhs.rect.x; - } - else { - return lhs.rect.y < rhs.rect.y; - } - } + std::ranges::sort(get_result(), + [](const TextRect& lhs, const TextRect& rhs) -> bool { + if (std::abs(lhs.rect.y - rhs.rect.y) < 5) { // y差距较小则理解为是同一排的,按x排序 + return lhs.rect.x < rhs.rect.x; + } + else { + return lhs.rect.y < rhs.rect.y; + } + } ); } @@ -181,24 +181,24 @@ void asst::OcrImageAnalyzer::sort_result_vertical() // |1 3| // |2 4| // +---+ - std::sort(get_result().begin(), get_result().end(), - [](const TextRect& lhs, const TextRect& rhs) -> bool { - if (std::abs(lhs.rect.x - rhs.rect.x) < 5) { // x差距较小则理解为是同一排的,按y排序 - return lhs.rect.y < rhs.rect.y; - } - else { - return lhs.rect.x < rhs.rect.x; - } - } + std::ranges::sort(get_result(), + [](const TextRect& lhs, const TextRect& rhs) -> bool { + if (std::abs(lhs.rect.x - rhs.rect.x) < 5) { // x差距较小则理解为是同一排的,按y排序 + return lhs.rect.y < rhs.rect.y; + } + else { + return lhs.rect.x < rhs.rect.x; + } + } ); } void asst::OcrImageAnalyzer::sort_result_by_score() { - std::sort(get_result().begin(), get_result().end(), - [](const TextRect& lhs, const TextRect& rhs) -> bool { - return lhs.score > rhs.score; - } + std::ranges::sort(get_result(), + [](const TextRect& lhs, const TextRect& rhs) -> bool { + return lhs.score > rhs.score; + } ); } @@ -215,16 +215,16 @@ void asst::OcrImageAnalyzer::sort_result_by_required() auto& result = get_result(); // 不在 m_required 中的将被排在最后 - std::sort(result.begin(), result.end(), - [&req_cache](const auto& lhs, const auto& rhs) -> bool { - size_t lvalue = req_cache[lhs.text]; - size_t rvalue = req_cache[rhs.text]; - if (lvalue == 0) { - return false; - } - else if (rvalue == 0) { - return true; - } - return lvalue < rvalue; - }); + std::ranges::sort(result, + [&req_cache](const auto& lhs, const auto& rhs) -> bool { + size_t lvalue = req_cache[lhs.text]; + size_t rvalue = req_cache[rhs.text]; + if (lvalue == 0) { + return false; + } + else if (rvalue == 0) { + return true; + } + return lvalue < rvalue; + }); } diff --git a/src/MeoAssistant/RecruitConfiger.cpp b/src/MeoAssistant/RecruitConfiger.cpp index fc4152f50a..08ff76c0e8 100644 --- a/src/MeoAssistant/RecruitConfiger.cpp +++ b/src/MeoAssistant/RecruitConfiger.cpp @@ -35,7 +35,7 @@ bool asst::RecruitConfiger::parse(const json::value& json) } // 按干员等级排个序 - std::sort(m_all_opers.begin(), m_all_opers.end(), [](const auto& lhs, const auto& rhs) -> bool { + std::ranges::sort(m_all_opers, [](const auto& lhs, const auto& rhs) -> bool { return lhs.level > rhs.level; }); diff --git a/src/MeoAssistant/RecruitConfiger.h b/src/MeoAssistant/RecruitConfiger.h index 286a1bf08e..cde6300f31 100644 --- a/src/MeoAssistant/RecruitConfiger.h +++ b/src/MeoAssistant/RecruitConfiger.h @@ -24,13 +24,18 @@ namespace asst std::string name_en; bool has_tag(const std::string &tag) const { - return tags.find(tag) != tags.cend(); + return tags.contains(tag); } - friend bool operator<(const RecruitOperInfo& lhs, const RecruitOperInfo& rhs) + friend std::strong_ordering operator<=>(const RecruitOperInfo& lhs, const RecruitOperInfo& rhs) { - if (lhs.level != rhs.level) return lhs.level > rhs.level; - return lhs.name < rhs.name; + if (lhs.level != rhs.level) return rhs.level <=> lhs.level; + return lhs.name <=> rhs.name; + } + + friend bool operator==(const RecruitOperInfo& lhs, const RecruitOperInfo& rhs) + { + return lhs.name == rhs.name && lhs.level == rhs.level; } }; @@ -64,22 +69,18 @@ namespace asst // intersection of two recruit combs friend RecruitCombs operator*(RecruitCombs& lhs, RecruitCombs& rhs) { - std::sort(lhs.tags.begin(), lhs.tags.end()); - std::sort(lhs.opers.begin(), lhs.opers.end()); - std::sort(rhs.tags.begin(), rhs.tags.end()); - std::sort(rhs.opers.begin(), rhs.opers.end()); + std::ranges::sort(lhs.tags); + std::ranges::sort(lhs.opers); + std::ranges::sort(rhs.tags); + std::ranges::sort(rhs.opers); RecruitCombs result; - std::set_union( - lhs.tags.cbegin(), lhs.tags.cend(), - rhs.tags.cbegin(), rhs.tags.cend(), - std::back_inserter(result.tags)); + std::ranges::set_union(std::as_const(lhs.tags), std::as_const(rhs.tags) , + std::back_inserter(result.tags)); - std::set_intersection( - lhs.opers.cbegin(), lhs.opers.cend(), - rhs.opers.cbegin(), rhs.opers.cend(), - std::back_inserter(result.opers)); + std::ranges::set_intersection(std::as_const(lhs.opers), std::as_const(rhs.opers) , + std::back_inserter(result.opers)); result.update_attributes(); diff --git a/src/MeoAssistant/RecruitImageAnalyzer.cpp b/src/MeoAssistant/RecruitImageAnalyzer.cpp index 5ca8d40a2f..37441a73e9 100644 --- a/src/MeoAssistant/RecruitImageAnalyzer.cpp +++ b/src/MeoAssistant/RecruitImageAnalyzer.cpp @@ -27,7 +27,7 @@ bool asst::RecruitImageAnalyzer::tags_analyze() std::vector all_tags_vec; all_tags_vec.assign(all_tags_set.begin(), all_tags_set.end()); // 把因为“资深干员”是“高级资深干员”的子串,把“高级资深干员”放到最前面,免得先被“资深干员”匹配上了 - auto ssr_iter = std::find(all_tags_vec.begin(), all_tags_vec.end(), "高级资深干员"); + auto ssr_iter = std::ranges::find(all_tags_vec, "高级资深干员"); if (ssr_iter != all_tags_vec.end()) { std::swap(*ssr_iter, all_tags_vec.front()); } diff --git a/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp b/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp index 5f46126814..384423daf8 100644 --- a/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp +++ b/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "NoWarningCV.h" @@ -140,7 +141,7 @@ bool asst::RoguelikeBattleTaskPlugin::get_stage_info() m_homes = opt->replacement_home; std::string log_str = "[ "; for (auto& home : m_homes) { - if (m_normal_tile_info.find(home) == m_normal_tile_info.end()) { + if (!m_normal_tile_info.contains(home)) { Log.error("No replacement home point", home.x, home.y); } log_str += "( " + std::to_string(home.x) + ", " + std::to_string(home.y) + " ), "; @@ -382,7 +383,7 @@ bool asst::RoguelikeBattleTaskPlugin::abandon() void asst::RoguelikeBattleTaskPlugin::all_melee_retreat() { - for (const auto& [loc, _] : m_used_tiles) { + for (const auto& loc : m_used_tiles | std::views::keys) { auto& tile_info = m_normal_tile_info[loc]; auto& type = tile_info.buildable; if (type == Loc::Melee || type == Loc::All) { @@ -606,7 +607,7 @@ asst::RoguelikeBattleTaskPlugin::DeployInfo asst::RoguelikeBattleTaskPlugin::cal std::vector available_locations; for (const auto& [loc, tile] : m_normal_tile_info) { if ((tile.buildable == buildable_type || tile.buildable == Loc::All) - && m_used_tiles.find(loc) == m_used_tiles.cend()) { + && !m_used_tiles.contains(loc)) { available_locations.emplace_back(loc); } } @@ -614,13 +615,13 @@ asst::RoguelikeBattleTaskPlugin::DeployInfo asst::RoguelikeBattleTaskPlugin::cal Log.error("No available locations"); if (m_used_tiles.empty()) { Log.error("No used tiles"); - return DeployInfo(); + return {}; } m_used_tiles.clear(); return calc_best_plan(oper); } - std::sort(available_locations.begin(), available_locations.end(), comp_dist); + std::ranges::sort(available_locations, comp_dist); // 取距离最近的N个点,计算分数。然后使用得分最高的点 constexpr int CalcPointCount = 4; @@ -773,7 +774,7 @@ std::pair asst::RoguelikeBattleTaskPlugin::calc_best_direction switch (oper.role) { case BattleRole::Medic: - if (m_used_tiles.find(absolute_pos) != m_used_tiles.end()) // 根据哪个方向上人多决定朝向哪 + if (m_used_tiles.contains(absolute_pos)) // 根据哪个方向上人多决定朝向哪 score += 10000; if (auto iter = m_side_tile_info.find(absolute_pos); iter != m_side_tile_info.end()) score += TileKeyMedicWeights.at(iter->second.key); diff --git a/src/MeoAssistant/RoguelikeFormationTaskPlugin.cpp b/src/MeoAssistant/RoguelikeFormationTaskPlugin.cpp index c2f0f4cd31..57a784de6a 100644 --- a/src/MeoAssistant/RoguelikeFormationTaskPlugin.cpp +++ b/src/MeoAssistant/RoguelikeFormationTaskPlugin.cpp @@ -58,8 +58,8 @@ bool asst::RoguelikeFormationTaskPlugin::_run() } auto& new_result = formation_analyzer.get_result(); - size_t new_selected_count = std::count_if(new_result.cbegin(), new_result.cend(), - [](const auto& oper) { return oper.selected; }); + size_t new_selected_count = std::ranges::count_if(new_result, + [](const auto& oper) { return oper.selected; }); // 说明 select_count 计数没生效,即都没点上 if (new_selected_count == pre_selected) { reselect = true; diff --git a/src/MeoAssistant/RoguelikeRecruitImageAnalyzer.cpp b/src/MeoAssistant/RoguelikeRecruitImageAnalyzer.cpp index 3bcf957cdf..e91a2d1eda 100644 --- a/src/MeoAssistant/RoguelikeRecruitImageAnalyzer.cpp +++ b/src/MeoAssistant/RoguelikeRecruitImageAnalyzer.cpp @@ -32,16 +32,16 @@ bool asst::RoguelikeRecruitImageAnalyzer::analyze() info.name = name; info.elite = elite; info.level = level; - info.required = std::find(order.cbegin(), order.cend(), name) != order.cend(); + info.required = std::ranges::find(order, name) != order.cend(); Log.info(__FUNCTION__, name, elite, level, rect.to_string()); m_result.emplace_back(std::move(info)); } - auto first_un_req = std::find_if(m_result.begin(), m_result.end(), - [&](const auto& info) -> bool { - return info.required == false; - }); + auto first_un_req = std::ranges::find_if(m_result, + [&](const auto& info) -> bool { + return info.required == false; + }); std::sort(first_un_req, m_result.end(), [&](const auto& lhs, const auto& rhs) -> bool { if (lhs.elite == rhs.elite) { @@ -100,8 +100,8 @@ int asst::RoguelikeRecruitImageAnalyzer::match_level(const Rect& raw_roi) } const std::string& level = analyzer.get_result().front().text; - if (level.empty() || !std::all_of(level.cbegin(), level.cend(), - [](char c) -> bool {return std::isdigit(c);})) { + if (level.empty() || !std::ranges::all_of(level, + [](char c) -> bool {return std::isdigit(c);})) { return 0; } return std::stoi(level); diff --git a/src/MeoAssistant/RoguelikeRecruitTaskPlugin.cpp b/src/MeoAssistant/RoguelikeRecruitTaskPlugin.cpp index 555c5bdee2..f71b7927b1 100644 --- a/src/MeoAssistant/RoguelikeRecruitTaskPlugin.cpp +++ b/src/MeoAssistant/RoguelikeRecruitTaskPlugin.cpp @@ -130,10 +130,10 @@ bool asst::RoguelikeRecruitTaskPlugin::check_core_char() break; } const auto& chars = analyzer.get_result(); - auto it = std::find_if(chars.cbegin(), chars.cend(), - [&](const BattleRecruitOperInfo& oper) -> bool { - return oper.name == core_opt.value(); - }); + auto it = std::ranges::find_if(chars, + [&](const BattleRecruitOperInfo& oper) -> bool { + return oper.name == core_opt.value(); + }); std::string oper_names = ""; for (const auto& oper : chars) { diff --git a/src/MeoAssistant/RoguelikeShoppingTaskPlugin.cpp b/src/MeoAssistant/RoguelikeShoppingTaskPlugin.cpp index b4a87fac2f..899eedf5bb 100644 --- a/src/MeoAssistant/RoguelikeShoppingTaskPlugin.cpp +++ b/src/MeoAssistant/RoguelikeShoppingTaskPlugin.cpp @@ -101,11 +101,11 @@ bool asst::RoguelikeShoppingTaskPlugin::_run() continue; } - auto find_it = std::find_if(result.cbegin(), result.cend(), - [&](const TextRect& tr) -> bool { - return tr.text.find(goods.name) != std::string::npos || - goods.name.find(tr.text) != std::string::npos; - }); + auto find_it = std::ranges::find_if(result, + [&](const TextRect& tr) -> bool { + return tr.text.find(goods.name) != std::string::npos || + goods.name.find(tr.text) != std::string::npos; + }); if (find_it == result.cend()) { continue; } @@ -147,8 +147,7 @@ bool asst::RoguelikeShoppingTaskPlugin::_run() } if (!goods.chars.empty()) { - auto iter = std::find_first_of(chars_list.cbegin(), chars_list.cend(), - goods.chars.cbegin(), goods.chars.cend()); + auto iter = std::ranges::find_first_of(std::as_const(chars_list), goods.chars); if (iter == chars_list.cend()) { Log.trace("Ready to buy", goods.name, ", but there is no such character, skip"); diff --git a/src/MeoAssistant/StageDropsImageAnalyzer.cpp b/src/MeoAssistant/StageDropsImageAnalyzer.cpp index a28e63b656..9dd92b87a9 100644 --- a/src/MeoAssistant/StageDropsImageAnalyzer.cpp +++ b/src/MeoAssistant/StageDropsImageAnalyzer.cpp @@ -1,5 +1,7 @@ #include "StageDropsImageAnalyzer.h" +#include + #include "NoWarningCV.h" #include "TaskData.h" @@ -55,10 +57,10 @@ bool asst::StageDropsImageAnalyzer::analyze_stage_code() const auto& stages = Resrc.drops().get_all_stage_code(); std::vector stages_req(stages.cbegin(), stages.cend()); // 名字长的放前面 - std::sort(stages_req.begin(), stages_req.end(), - [](const std::string& lhs, const std::string& rhs) -> bool { - return lhs.size() > rhs.size(); - }); + std::ranges::sort(stages_req, + [](const std::string& lhs, const std::string& rhs) -> bool { + return lhs.size() > rhs.size(); + }); analyzer.set_required(std::move(stages_req)); if (!analyzer.analyze()) { @@ -326,7 +328,7 @@ bool asst::StageDropsImageAnalyzer::analyze_baseline() m_baseline.emplace_back(baseline, match_droptype(baseline)); } } - if (m_baseline.size() >= 1) { + if (!m_baseline.empty()) { if (m_baseline.back().second == StageDropType::Unknown) { Log.warn(__FUNCTION__, "The last baseline is unknown type, remove it"); m_baseline.pop_back(); @@ -334,8 +336,8 @@ bool asst::StageDropsImageAnalyzer::analyze_baseline() } Log.trace(__FUNCTION__, "baseline size", m_baseline.size()); - for (const auto& baseline : m_baseline) { - Log.trace(__FUNCTION__, "baseline", baseline.first.to_string()); + for (const auto& key : m_baseline | std::views::keys) { + Log.trace(__FUNCTION__, "baseline", key.to_string()); } return !m_baseline.empty(); @@ -557,8 +559,8 @@ int asst::StageDropsImageAnalyzer::match_quantity(const Rect& roi) //} if (digit_str.empty() || - !std::all_of(digit_str.cbegin(), digit_str.cend(), - [](char c) -> bool {return std::isdigit(c) || c == '.';})) { + !std::ranges::all_of(std::as_const(digit_str), + [](char c) -> bool {return std::isdigit(c) || c == '.';})) { return 0; } diff --git a/src/MeoAssistant/StageDropsTaskPlugin.cpp b/src/MeoAssistant/StageDropsTaskPlugin.cpp index 0dafd4a18e..09fdf92a02 100644 --- a/src/MeoAssistant/StageDropsTaskPlugin.cpp +++ b/src/MeoAssistant/StageDropsTaskPlugin.cpp @@ -220,7 +220,7 @@ void asst::StageDropsTaskPlugin::upload_to_penguin() for (const auto& drop : m_cur_info_json["drops"].as_array()) { static const std::vector filter = { "NORMAL_DROP", "EXTRA_DROP" , "FURNITURE", "SPECIAL_DROP" }; std::string drop_type = drop.at("dropType").as_string(); - if (std::find(filter.cbegin(), filter.cend(), drop_type) == filter.cend()) { + if (std::ranges::find(filter, drop_type) == filter.cend()) { continue; } if (drop.at("itemId").as_string().empty()) { diff --git a/src/MeoAssistant/TaskData.cpp b/src/MeoAssistant/TaskData.cpp index ba782d2cc2..68b5c45d73 100644 --- a/src/MeoAssistant/TaskData.cpp +++ b/src/MeoAssistant/TaskData.cpp @@ -23,7 +23,7 @@ bool asst::TaskData::parse(const json::value& json) }; for (const auto& [name, task_json] : json.as_object()) { std::string algorithm_str = task_json.get("algorithm", "matchtemplate"); - std::transform(algorithm_str.begin(), algorithm_str.end(), algorithm_str.begin(), to_lower); + std::ranges::transform(algorithm_str, algorithm_str.begin(), to_lower); auto algorithm = AlgorithmType::Invalid; if (algorithm_str == "matchtemplate") { algorithm = AlgorithmType::MatchTemplate; @@ -97,7 +97,7 @@ bool asst::TaskData::parse(const json::value& json) task_info_ptr->algorithm = algorithm; task_info_ptr->name = name; std::string action = task_json.get("action", "donothing"); - std::transform(action.begin(), action.end(), action.begin(), to_lower); + std::ranges::transform(action, action.begin(), to_lower); if (action == "clickself") { task_info_ptr->action = ProcessTaskAction::ClickSelf; } diff --git a/src/MeoAssistant/TemplResource.cpp b/src/MeoAssistant/TemplResource.cpp index 2f7132117e..8a5a32c3c9 100644 --- a/src/MeoAssistant/TemplResource.cpp +++ b/src/MeoAssistant/TemplResource.cpp @@ -40,7 +40,7 @@ bool asst::TemplResource::load(const std::string& dir) bool asst::TemplResource::exist_templ(const std::string& key) const noexcept { - return m_templs.find(key) != m_templs.cend(); + return m_templs.contains(key); } const cv::Mat asst::TemplResource::get_templ(const std::string& key) const noexcept diff --git a/tools/ResourceUpdater/main.cpp b/tools/ResourceUpdater/main.cpp index 883f25cc3f..944637e8a7 100644 --- a/tools/ResourceUpdater/main.cpp +++ b/tools/ResourceUpdater/main.cpp @@ -21,6 +21,7 @@ #elif defined(__GNUC__) #pragma GCC diagnostic pop #endif +#include #include bool update_items_data(const std::filesystem::path& input_dir, const std::filesystem::path& output_dir); @@ -318,8 +319,8 @@ bool update_infrast_data(const std::filesystem::path& input_dir, const std::file // 这里面有些是手动修改的,要保留 json::value& root = old_json; std::unordered_set rooms; - for (auto& [_, buff_obj] : buffs) { - std::string raw_room_type = (std::string)buff_obj["roomType"]; + for (auto& buff_obj : buffs | std::views::values) { + std::string raw_room_type = static_cast(buff_obj["roomType"]); // 为了兼容老版本的字段 orz static const std::unordered_map RoomTypeMapping = { @@ -341,10 +342,10 @@ bool update_infrast_data(const std::filesystem::path& input_dir, const std::file rooms.emplace(room_type); - std::string key = (std::string)buff_obj["skillIcon"]; - std::string name = (std::string)buff_obj["buffName"]; + std::string key = static_cast(buff_obj["skillIcon"]); + std::string name = static_cast(buff_obj["buffName"]); // 这玩意里面有类似 xml 的东西,全删一下 - std::string desc = (std::string)buff_obj["description"]; + std::string desc = static_cast(buff_obj["description"]); remove_xml(desc); auto& skill = root[room_type]["skills"][key]; @@ -565,7 +566,7 @@ bool update_battle_chars_info(const std::filesystem::path& input_dir, const std: char_data.get("phases", 2, "rangeId", default_range), }; } - char_new_data["rarity"] = (int)char_data["rarity"] + 1; + char_new_data["rarity"] = static_cast(char_data["rarity"]) + 1; chars.emplace(id, std::move(char_new_data)); }