diff --git a/src/MeoAssistant/AutoRecruitTask.cpp b/src/MeoAssistant/AutoRecruitTask.cpp index 47aa89eb9d..96745f2362 100644 --- a/src/MeoAssistant/AutoRecruitTask.cpp +++ b/src/MeoAssistant/AutoRecruitTask.cpp @@ -127,21 +127,12 @@ bool asst::AutoRecruitTask::_run() if (!recruit_begin()) return false; - if (!check_recruit_home_page()) { - return false; - } + static constexpr int slot_retry_limit = 3; - if (!m_use_expedited) { // analyze once only - if (!analyze_start_buttons()) return true; - } - - static constexpr size_t slot_retry_limit = 3; - - // m_cur_times means how many times has the confirm button been pressed, NOT expedited plan used - while ((m_use_expedited || !m_pending_recruit_slot.empty()) && m_cur_times != m_max_times) { + // m_cur_times means how many times has the confirm button been pressed, NOT expedited plans used + while (m_cur_times != m_max_times) { if (m_force_discard_flag) { return false; } if (m_slot_fail >= slot_retry_limit) { return false; } - if (!check_recruit_home_page()) { return false; } if (m_use_expedited) { Log.info("ready to use expedited"); if (need_exit()) return false; @@ -149,10 +140,15 @@ bool asst::AutoRecruitTask::_run() m_force_discard_flag = true; return false; } - analyze_start_buttons(); + } + auto start_rect = try_get_start_button(m_ctrler->get_image()); + if (!start_rect) { + if (!check_recruit_home_page()) return false; + Log.info("There is no available start button."); + return true; } if (need_exit()) return false; - if (!recruit_one()) + if (!recruit_one(start_rect.value())) ++m_slot_fail; else ++m_cur_times; @@ -160,25 +156,14 @@ bool asst::AutoRecruitTask::_run() return true; } -bool asst::AutoRecruitTask::analyze_start_buttons() +std::optional asst::AutoRecruitTask::try_get_start_button(const cv::Mat& image) { OcrImageAnalyzer start_analyzer; start_analyzer.set_task_info("StartRecruit"); - - auto image = m_ctrler->get_image(); start_analyzer.set_image(image); - m_pending_recruit_slot.clear(); - if (!start_analyzer.analyze()) { - Log.info("There is no start button"); - return false; - } + if (!start_analyzer.analyze()) return std::nullopt; start_analyzer.sort_result_horizontal(); - m_start_buttons = start_analyzer.get_result(); - for (size_t i = 0; i < m_start_buttons.size(); ++i) { - m_pending_recruit_slot.emplace_back(i); - } - Log.info("Recruit start button size", m_start_buttons.size()); - return true; + return start_analyzer.get_result().front().rect; } /// open a pending recruit slot, set timer and tags then confirm, or leave the slot doing nothing @@ -186,29 +171,18 @@ bool asst::AutoRecruitTask::analyze_start_buttons() /// - recognition failed /// - timer or tags corrupted /// - failed to confirm -bool asst::AutoRecruitTask::recruit_one() +bool asst::AutoRecruitTask::recruit_one(const Rect& button) { LogTraceFunction; int delay = Resrc.cfg().get_options().task_delay; - if (m_pending_recruit_slot.empty()) return false; - size_t index = m_pending_recruit_slot.front(); - if (index > m_start_buttons.size()) { - Log.info("index", index, "out of range."); - m_pending_recruit_slot.pop_front(); - return false; - } - Log.info("recruit_index", index); - Rect button = m_start_buttons.at(index).rect; m_ctrler->click(button); sleep(delay); auto calc_result = recruit_calc_task(); sleep(delay); - m_pending_recruit_slot.pop_front(); - if (!calc_result.success) { // recognition failed, perhaps open the slot again would not help { @@ -233,8 +207,7 @@ bool asst::AutoRecruitTask::recruit_one() // timer was not set to 09:00:00 properly, likely the tag selection was also corrupted // see https://github.com/MaaAssistantArknights/MaaAssistantArknights/pull/300#issuecomment-1073287984 // return and try later - Log.info("Timer of this slot has not been reduced as expected, will retry later."); - m_pending_recruit_slot.push_back(index); + Log.info("Timer of this slot has not been reduced as expected."); click_return_button(); return false; } diff --git a/src/MeoAssistant/AutoRecruitTask.h b/src/MeoAssistant/AutoRecruitTask.h index 2d28c289bb..546948327b 100644 --- a/src/MeoAssistant/AutoRecruitTask.h +++ b/src/MeoAssistant/AutoRecruitTask.h @@ -5,6 +5,7 @@ #include #include +#include namespace asst { @@ -26,8 +27,8 @@ namespace asst virtual bool _run() override; bool is_calc_only_task() { return m_max_times <= 0 || m_confirm_level.empty(); } - bool analyze_start_buttons(); - bool recruit_one(); + static std::optional try_get_start_button(const cv::Mat&); + bool recruit_one(const Rect&); bool check_recruit_home_page(); bool recruit_begin(); bool check_time_unreduced(); @@ -54,8 +55,6 @@ namespace asst bool m_skip_robot = true; bool m_set_time = true; - std::vector m_start_buttons; - std::list m_pending_recruit_slot; int m_slot_fail = 0; int m_cur_times = 0; }; diff --git a/src/MeoAssistant/RecruitConfiger.h b/src/MeoAssistant/RecruitConfiger.h index dbd326a7ba..286a1bf08e 100644 --- a/src/MeoAssistant/RecruitConfiger.h +++ b/src/MeoAssistant/RecruitConfiger.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "AsstTypes.h" @@ -44,15 +45,20 @@ namespace asst double avg_level = 0; void update_attributes() { - double sum = 0; - min_level = 7; - max_level = 0; - for (const auto& op : opers) { - sum += op.level; - min_level = (std::min)(min_level, op.level); - max_level = (std::max)(max_level, op.level); - } - avg_level = sum / static_cast(opers.size()); + min_level = std::transform_reduce( + opers.cbegin(), opers.cend(), 7, + [](int a, int b) -> int { return (std::min)(a, b); }, + std::mem_fn(&RecruitOperInfo::level)); + + max_level = std::transform_reduce( + opers.cbegin(), opers.cend(), 0, + [](int a, int b) -> int { return (std::max)(a, b); }, + std::mem_fn(&RecruitOperInfo::level)); + + avg_level = std::transform_reduce( + opers.cbegin(), opers.cend(), 0., + std::plus{}, + std::mem_fn(&RecruitOperInfo::level)) / static_cast(opers.size()); } // intersection of two recruit combs