mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-20 10:57:45 +08:00
Merge branch 'MaaAssistantArknights:dev' into dev
This commit is contained in:
85
.github/labeler.yml
vendored
Normal file
85
.github/labeler.yml
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
# <!-- [Aa]dd `LABEL` --> 可以强制加上一个 label
|
||||
# <!-- [Rr]emove `LABEL` --> 可以强制去掉一个 label
|
||||
# Add 的优先级比 Remove 高
|
||||
"module: copilot":
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)copilot(?:`|)|自动(作战|战斗|编队)|作业|自動(戰|戦)(鬥|闘)|作業|copilot)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)copilot(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)copilot(?:`|))))[\\s\\S]*$)"
|
||||
"module: fight":
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)fight(?:`|)|刷图|刷.{0,6}材料|关卡选择|战斗|作战|(戰|戦)(鬥|闘)|fight|battle)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)fight(?:`|)|^(?![\\s\\S]*(?:\
|
||||
自动(作战|战斗|编队)|作业|自動(戰|戦)(鬥|闘)|作業|copilot|\
|
||||
肉(鸽|鴿)|集成战略|rogue|ローグ|\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)fight(?:`|))))[\\s\\S]*$)"
|
||||
"module: GUI":
|
||||
# 其它模块都匹配不上的时候再尝试匹配GUI
|
||||
# 因为可能有人说“公招界面”“肉鸽崩溃”“基建闪退”等等
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)GUI(?:`|)|图形化界面|闪退|gui|GUI|インターフェース)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)GUI(?:`|)|^(?![\\s\\S]*(?:\
|
||||
自动编队|作业|作業|copilot|\
|
||||
刷图|刷.{0,6}材料|关卡选择|战斗|作战|(戰|戦)(鬥|闘)|fight|battle|\
|
||||
基建|贸易站|制造站|控制中枢|会客室|基地|infrast|base|\
|
||||
信用|拜访|登录|开始唤醒|visit|login|startup|\
|
||||
公招|招募|公開(募集|求人)|recruit|\
|
||||
肉(鸽|鴿)|集成战略|rogue|ローグ|\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)GUI(?:`|))))[\\s\\S]*$)"
|
||||
"module: infrast":
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)infrast(?:`|)|基建|贸易站|制造站|控制中枢|会客室|基地|infrast|base)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)infrast(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)infrast(?:`|))))[\\s\\S]*$)"
|
||||
"module: others":
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)others(?:`|)|信用|拜访|登录|开始唤醒|visit|login|startup)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)others(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)others(?:`|))))[\\s\\S]*$)"
|
||||
"module: recruit":
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)recruit(?:`|)|公招|招募|公開(募集|求人)|recruit)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)recruit(?:`|)|^(?![\\s\\S]*(?:\
|
||||
肉(鸽|鴿)|集成战略|rogue|ローグ|\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)recruit(?:`|))))[\\s\\S]*$)"
|
||||
"module: roguelike":
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)roguelike(?:`|)|肉(鸽|鴿)|集成战略|rogue|ローグ)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)roguelike(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)roguelike(?:`|))))[\\s\\S]*$)"
|
||||
"release":
|
||||
- '(?:[Aa]dd (?:`|)release(?:`|)|Release v(?:\d)+\.(?:\d)+\.(?:\d)+)'
|
||||
- "(?:[Aa]dd (?:`|)release(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)release(?:`|))))[\\s\\S]*$)"
|
||||
"ambiguous":
|
||||
# 不符合上面任何一个的分类并且(如果是PR)不符合 commitizen
|
||||
- '(?:[Aa]dd (?:`|)ambiguous(?:`|))'
|
||||
- "(?:[Aa]dd (?:`|)ambiguous(?:`|)|^(?![\\s\\S]*(?:\
|
||||
feat|chore|perf|style|refactor|fix|doc|\
|
||||
自动编队|作业|作業|copilot|\
|
||||
刷图|刷.{0,6}材料|关卡选择|战斗|作战|戰鬥|戦闘|fight|battle|\
|
||||
图形化界面|闪退|gui|GUI|インターフェース|\
|
||||
基建|贸易站|制造站|控制中枢|会客室|基地|infrast|base|\
|
||||
信用|拜访|登录|开始唤醒|visit|login|startup|\
|
||||
公招|招募|公開(募集|求人)|recruit|\
|
||||
肉(鸽|鴿)|集成战略|rogue|ローグ|\
|
||||
Release v(?:\\d)+\\.(?:\\d)+\\.(?:\\d)+|\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)ambiguous(?:`|))))[\\s\\S]*$)"
|
||||
"translation required":
|
||||
# 不要使用日文发 issue
|
||||
- "(?:[Aa]dd (?:`|)translation required(?:`|)|([\\u3040-\\u30ff]|[㍿㍐]))"
|
||||
- "(?:[Aa]dd (?:`|)translation required(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)translation required(?:`|))))[\\s\\S]*$)"
|
||||
"Client: JP":
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)Client: JP(?:`|)|日(文|语|本|)服|YoStarJP)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)Client: JP(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)Client: JP(?:`|))))[\\s\\S]*$)"
|
||||
"Client: EN":
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)Client: EN(?:`|)|英(文|语|)服|国际服|美服|YoStarEN)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)Client: EN(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)Client: EN(?:`|))))[\\s\\S]*$)"
|
||||
"Client: KR":
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)Client: KR(?:`|)|韩(文|语|国|)服|YoStarKR)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)Client: KR(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)Client: KR(?:`|))))[\\s\\S]*$)"
|
||||
"Client: ZH_TW":
|
||||
- '(?:[Aa]dd (?:`|)(?:module: |)Client: ZH_TW(?:`|)|繁中服|台(湾|灣|)服|繁体中文服|(龙|龍)成|天下网游|txwy)'
|
||||
- "(?:[Aa]dd (?:`|)(?:module: |)Client: ZH_TW(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:module: |)Client: ZH_TW(?:`|))))[\\s\\S]*$)"
|
||||
"MAA Team":
|
||||
- '(?:[Aa]dd (?:`|)(?:MAA|maa)(?: |)[Tt]eam(?:`|))'
|
||||
- "(?:[Aa]dd (?:`|)(?:MAA|maa)(?: |)[Tt]eam(?:`|)|^(?![\\s\\S]*(?:\
|
||||
[Rr]emove (?:[Aa]ll labels|(?:`|)(?:MAA|maa)(?: |)[Tt]eam(?:`|))))[\\s\\S]*$)"
|
||||
18
.github/workflows/labeler.yml
vendored
Normal file
18
.github/workflows/labeler.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: "Labeler"
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
pull_request:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: github/issue-labeler@v2.5
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
configuration-path: .github/labeler.yml
|
||||
not-before: 2022-08-05T00:00:00Z
|
||||
enable-versioned-regex: 0
|
||||
include-title: 1
|
||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,7 +1,8 @@
|
||||
- Support I.S. custom start in YoStarEN and YoStarJP @MistEO @Npipyd
|
||||
- 新增支持剿灭 `全权委托` 关卡导航及掉落识别 @MistEO
|
||||
- 优化 界面 全屏显示及部分细节效果 @ABA2396
|
||||
- 修复 肉鸽 编队会漏掉某些干员的问题 @MistEO
|
||||
- 修复 公招 出 6 星时不显示组合的问题 @horror-proton
|
||||
- 尝试修复 基建 选择干员时的错误 @MistEO
|
||||
- C++ 20 升级工作 及 项目代码整理 @zzyyyl @horror-proton @lhhxxxxx @MistEO
|
||||
- 修复 `1-7` 关卡导航失败的问题 @ABA2396
|
||||
- 修复 肉鸽 `假日威龙陈` 技能选择错误 @MistEO
|
||||
- 修复 肉鸽 商店偶现卡住的问题 @MistEO
|
||||
- 调整 肉鸽 商店收藏品购买优先级 @MistEO
|
||||
- 优化 界面显示 @ABA2396
|
||||
- 项目代码优化、文档整理 @lhhxxxxx @horror-proton
|
||||
- 项目文档、labeler 整理 @zzyyyl @horror-proton @zzyyyl @ABA2396
|
||||
- 修复 Release checksum 编码错误 @LiamSho
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "Assistant.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include <meojson/json.hpp>
|
||||
|
||||
@@ -180,7 +180,7 @@ std::vector<Assistant::TaskId> asst::Assistant::get_tasks_list() const
|
||||
{
|
||||
std::vector<TaskId> result;
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
for (const auto& id : m_tasks_list | std::views::keys) {
|
||||
for (const auto& id : m_tasks_list | views::keys) {
|
||||
result.emplace_back(id);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(ASST_USE_RANGES_STL) && !defined(ASST_USE_RANGES_RANGE_V3) && !defined(ASST_USE_RANGES_BOOST)
|
||||
#ifdef __clang__
|
||||
#define ASST_USE_RANGES_RANGE_V3
|
||||
#else
|
||||
#define ASST_USE_RANGES_STL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define ASST_DO_PRAGMA(x) __pragma(x)
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
65
src/MeoAssistant/AsstRanges.hpp
Normal file
65
src/MeoAssistant/AsstRanges.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include "AsstConf.h"
|
||||
|
||||
#ifdef ASST_USE_RANGES_RANGE_V3
|
||||
|
||||
#include <range/v3/all.hpp>
|
||||
|
||||
namespace asst
|
||||
{
|
||||
namespace ranges
|
||||
{
|
||||
using namespace ::ranges;
|
||||
|
||||
// return type of ::ranges::remove_if is different from which of std::remove_if
|
||||
struct remove_if_fn
|
||||
{
|
||||
template <permutable I, sentinel_for<I> S, typename C, typename P = identity>
|
||||
constexpr subrange<I>
|
||||
operator()(I first, S last, C pred, P proj = P{}) const
|
||||
{
|
||||
return { ::ranges::remove_if(std::move(first), last, std::move(pred), std::move(proj)), last };
|
||||
}
|
||||
|
||||
template <forward_range Rng, typename C, typename P = identity>
|
||||
constexpr borrowed_subrange_t<Rng> operator()(Rng&& rng, C pred, P proj = P{}) const
|
||||
{
|
||||
return (*this)(begin(rng), end(rng), std::move(pred), std::move(proj));
|
||||
}
|
||||
};
|
||||
|
||||
// this one will be found before ::ranges::remove_if
|
||||
inline constexpr remove_if_fn remove_if{};
|
||||
}
|
||||
|
||||
namespace views = ::ranges::views;
|
||||
}
|
||||
|
||||
#elif defined(ASST_USE_RANGES_STL)
|
||||
|
||||
#include <ranges>
|
||||
|
||||
namespace asst
|
||||
{
|
||||
namespace ranges = std::ranges;
|
||||
namespace views = std::views;
|
||||
}
|
||||
|
||||
#elif defined(ASST_USE_RANGES_BOOST)
|
||||
|
||||
#error "Not implemented"
|
||||
|
||||
#include <boost/range/algorithm.hpp>
|
||||
#include <boost/range/adaptors.hpp>
|
||||
|
||||
namespace asst {
|
||||
namespace ranges = boost::range;
|
||||
namespace views = boost::adaptors;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error
|
||||
|
||||
#endif
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "Logger.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
namespace asst::recruit_calc
|
||||
{
|
||||
@@ -20,7 +20,7 @@ namespace asst::recruit_calc
|
||||
|
||||
{
|
||||
rcs_with_single_tag.reserve(tags.size());
|
||||
std::ranges::transform(tags, std::back_inserter(rcs_with_single_tag), [](const std::string& t) {
|
||||
ranges::transform(tags, std::back_inserter(rcs_with_single_tag), [](const std::string& t) {
|
||||
RecruitCombs result;
|
||||
result.tags = { t };
|
||||
result.min_level = 6;
|
||||
@@ -42,8 +42,8 @@ namespace asst::recruit_calc
|
||||
for (auto& rc : rcs_with_single_tag) {
|
||||
rc.avg_level /= static_cast<double>(rc.opers.size());
|
||||
// intersection and union are based on sorted container
|
||||
std::ranges::sort(rc.tags);
|
||||
std::ranges::sort(rc.opers);
|
||||
ranges::sort(rc.tags);
|
||||
ranges::sort(rc.opers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,13 +75,13 @@ namespace asst::recruit_calc
|
||||
static constexpr std::string_view SeniorOper = "高级资深干员";
|
||||
|
||||
for (auto comb_iter = result.begin(); comb_iter != result.end();) {
|
||||
if (std::ranges::find(comb_iter->tags, SeniorOper) != comb_iter->tags.end()) {
|
||||
if (ranges::find(comb_iter->tags, SeniorOper) != comb_iter->tags.end()) {
|
||||
++comb_iter;
|
||||
continue;
|
||||
}
|
||||
// no senior tag, remove 6-star operators
|
||||
// assuming sorted by level
|
||||
auto iter = std::ranges::find_if(comb_iter->opers, [](const RecruitOperInfo& op) { return op.level >= 6; });
|
||||
auto iter = ranges::find_if(comb_iter->opers, [](const RecruitOperInfo& op) { return op.level >= 6; });
|
||||
if (iter == comb_iter->opers.end()) {
|
||||
++comb_iter;
|
||||
continue;
|
||||
@@ -188,7 +188,7 @@ std::optional<asst::Rect> asst::AutoRecruitTask::try_get_start_button(const cv::
|
||||
if (!start_analyzer.analyze()) return std::nullopt;
|
||||
start_analyzer.sort_result_horizontal();
|
||||
auto iter =
|
||||
std::ranges::find_if(std::as_const(start_analyzer.get_result()),
|
||||
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));
|
||||
});
|
||||
@@ -278,7 +278,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc
|
||||
bool has_refresh = !image_analyzer.get_refresh_rect().empty();
|
||||
|
||||
std::vector<std::string> tag_names;
|
||||
std::ranges::transform(tags, std::back_inserter(tag_names), std::mem_fn(&TextRect::text));
|
||||
ranges::transform(tags, std::back_inserter(tag_names), std::mem_fn(&TextRect::text));
|
||||
|
||||
bool has_special_tag = false;
|
||||
bool has_robot_tag = false;
|
||||
@@ -287,7 +287,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc
|
||||
{
|
||||
json::value info = basic_info();
|
||||
std::vector<json::value> tag_json_vector;
|
||||
std::ranges::transform(tags, std::back_inserter(tag_json_vector), std::mem_fn(&TextRect::text));
|
||||
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) } };
|
||||
@@ -296,7 +296,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc
|
||||
|
||||
// special tags
|
||||
const std::vector<std::string> SpecialTags = { "高级资深干员", "资深干员" };
|
||||
auto special_iter = std::ranges::find_first_of(SpecialTags, tag_names);
|
||||
auto special_iter = ranges::find_first_of(SpecialTags, tag_names);
|
||||
if (special_iter != SpecialTags.cend()) [[unlikely]] {
|
||||
json::value info = basic_info();
|
||||
info["what"] = "RecruitSpecialTag";
|
||||
@@ -307,7 +307,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc
|
||||
|
||||
// robot tags
|
||||
const std::vector<std::string> RobotTags = { "支援机械" };
|
||||
auto robot_iter = std::ranges::find_first_of(RobotTags, tag_names);
|
||||
auto robot_iter = ranges::find_first_of(RobotTags, tag_names);
|
||||
if (robot_iter != RobotTags.cend()) [[unlikely]] {
|
||||
json::value info = basic_info();
|
||||
info["what"] = "RecruitRobotTag";
|
||||
@@ -323,20 +323,20 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc
|
||||
for (RecruitCombs& rc : result_vec) {
|
||||
if (rc.min_level < 3) {
|
||||
// find another min level (assuming operator list sorted in increment order by level)
|
||||
auto sec = std::ranges::find_if(rc.opers, [](const RecruitOperInfo& op) { return op.level >= 3; });
|
||||
auto sec = ranges::find_if(rc.opers, [](const RecruitOperInfo& op) { return op.level >= 3; });
|
||||
if (sec != rc.opers.cend()) { rc.min_level = sec->level; }
|
||||
}
|
||||
}
|
||||
|
||||
std::ranges::sort(result_vec,
|
||||
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();
|
||||
ranges::find_first_of(lhs.tags, SpecialTags) != lhs.tags.cend();
|
||||
bool r_has =
|
||||
std::ranges::find_first_of(rhs.tags, SpecialTags) != rhs.tags.cend();
|
||||
ranges::find_first_of(rhs.tags, SpecialTags) != rhs.tags.cend();
|
||||
if (l_has != r_has) return l_has > r_has;
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc
|
||||
comb_json["tags"] = json::array(std::move(tags_json_vector));
|
||||
|
||||
std::vector<json::value> opers_json_vector;
|
||||
for (const RecruitOperInfo& oper_info : std::ranges::reverse_view(comb.opers)) { // print reversely
|
||||
for (const RecruitOperInfo& oper_info : ranges::reverse_view(comb.opers)) { // print reversely
|
||||
json::value oper_json;
|
||||
oper_json["name"] = oper_info.name;
|
||||
oper_json["level"] = oper_info.level;
|
||||
@@ -433,7 +433,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc
|
||||
|
||||
if (!is_calc_only_task()) {
|
||||
// do not confirm, force skip
|
||||
if (std::ranges::none_of(m_confirm_level, [&](const auto& i) { return i == final_combination.min_level; })) {
|
||||
if (ranges::none_of(m_confirm_level, [&](const auto& i) { return i == final_combination.min_level; })) {
|
||||
calc_task_result_type result;
|
||||
result.success = true;
|
||||
result.force_skip = true;
|
||||
@@ -456,7 +456,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc
|
||||
}
|
||||
|
||||
// nothing to select, leave the selection empty
|
||||
if (std::ranges::none_of(m_select_level, [&](const auto& i) { return i == final_combination.min_level; })) {
|
||||
if (ranges::none_of(m_select_level, [&](const auto& i) { return i == final_combination.min_level; })) {
|
||||
calc_task_result_type result;
|
||||
result.success = true;
|
||||
result.force_skip = false;
|
||||
@@ -467,7 +467,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::ranges::find_if(tags, [&](const TextRect& r) { return r.text == final_tag_name; });
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "BattleDataConfiger.h"
|
||||
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
#include <meojson/json.hpp>
|
||||
|
||||
bool asst::BattleDataConfiger::parse(const json::value& json)
|
||||
{
|
||||
for (const auto& char_data_json : json.at("chars").as_object() | std::views::values) {
|
||||
for (const auto& char_data_json : json.at("chars").as_object() | views::values) {
|
||||
BattleCharData data;
|
||||
std::string name = char_data_json.at("name").as_string();
|
||||
data.name = name;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "BattleFormationTask.h"
|
||||
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include "Resource.h"
|
||||
#include "Controller.h"
|
||||
@@ -31,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 : m_groups | std::views::keys) {
|
||||
for (const auto& name : m_groups | views::keys) {
|
||||
formation.array_emplace(name);
|
||||
}
|
||||
callback(AsstMsg::SubTaskExtraInfo, info);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "BattleImageAnalyzer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include "NoWarningCV.h"
|
||||
|
||||
@@ -116,7 +117,7 @@ void asst::BattleImageAnalyzer::clear() noexcept
|
||||
void asst::BattleImageAnalyzer::sort_opers_by_cost()
|
||||
{
|
||||
// 本来游戏就是按费用排的,这里倒序一下就行了
|
||||
std::ranges::reverse(m_opers);
|
||||
ranges::reverse(m_opers);
|
||||
}
|
||||
|
||||
bool asst::BattleImageAnalyzer::opers_analyze()
|
||||
@@ -500,7 +501,7 @@ bool asst::BattleImageAnalyzer::kills_analyze()
|
||||
// 例子中的"0"
|
||||
std::string kills_count = kills_text.substr(0, pos);
|
||||
if (kills_count.empty() ||
|
||||
!std::ranges::all_of(kills_count,
|
||||
!ranges::all_of(kills_count,
|
||||
[](char c) -> bool {return std::isdigit(c);})) {
|
||||
return false;
|
||||
}
|
||||
@@ -511,7 +512,7 @@ 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::ranges::all_of(total_kills,
|
||||
!ranges::all_of(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,7 +540,7 @@ bool asst::BattleImageAnalyzer::cost_analyze()
|
||||
std::string cost_str = cost_analyzer.get_result().front().text;
|
||||
|
||||
if (cost_str.empty() ||
|
||||
!std::ranges::all_of(cost_str,
|
||||
!ranges::all_of(cost_str,
|
||||
[](const char& c) -> bool {return std::isdigit(c);})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include "NoWarningCV.h"
|
||||
|
||||
@@ -180,7 +180,7 @@ bool asst::BattleProcessTask::analyze_opers_preview()
|
||||
bool not_found = true;
|
||||
// 找出这个干员是哪个组里的,以及他的技能用法等
|
||||
for (const auto& [group_name, deploy_opers] : m_copilot_data.groups) {
|
||||
auto iter = std::ranges::find_if(deploy_opers,
|
||||
auto iter = ranges::find_if(deploy_opers,
|
||||
[&](const BattleDeployOper& deploy) -> bool {
|
||||
return deploy.name == oper_name;
|
||||
});
|
||||
@@ -596,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& info : m_used_opers | std::views::values) {
|
||||
for (auto& info : m_used_opers | views::values) {
|
||||
if (info.info.skill_usage != BattleSkillUsage::Possibly
|
||||
&& info.info.skill_usage != BattleSkillUsage::Once) {
|
||||
continue;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "CreditShopImageAnalyzer.h"
|
||||
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include "NoWarningCV.h"
|
||||
|
||||
@@ -91,9 +91,9 @@ bool asst::CreditShopImageAnalyzer::whether_to_buy_analyze()
|
||||
}
|
||||
|
||||
if (m_is_white_list) {
|
||||
std::ranges::sort(m_need_to_buy, [&](const auto& lhs, const auto& rhs) -> bool {
|
||||
return std::ranges::find(m_shopping_list, lhs.second)
|
||||
< std::ranges::find(m_shopping_list, rhs.second);
|
||||
ranges::sort(m_need_to_buy, [&](const auto& lhs, const auto& rhs) -> bool {
|
||||
return ranges::find(m_shopping_list, lhs.second)
|
||||
< ranges::find(m_shopping_list, rhs.second);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -106,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 | std::views::keys) {
|
||||
for (const auto& commodity : m_need_to_buy | views::keys) {
|
||||
sold_out_analyzer.set_roi(commodity);
|
||||
if (sold_out_analyzer.analyze()) {
|
||||
#ifdef ASST_DEBUG
|
||||
|
||||
@@ -281,7 +281,7 @@ int asst::DepotImageAnalyzer::match_quantity(const Rect& roi)
|
||||
//}
|
||||
|
||||
if (digit_str.empty() ||
|
||||
!std::ranges::all_of(digit_str,
|
||||
!ranges::all_of(digit_str,
|
||||
[](const char& c) -> bool {return std::isdigit(c) || c == '.';})) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ bool asst::InfrastFacilityImageAnalyzer::analyze()
|
||||
|
||||
const auto& cur_res = mm_analyzer.get_result();
|
||||
auto cur_max_iter =
|
||||
std::ranges::max_element(cur_res, [](const MatchRect& lhs, const MatchRect& rhs) -> bool {
|
||||
ranges::max_element(cur_res, [](const MatchRect& lhs, const MatchRect& rhs) -> bool {
|
||||
return lhs.score < rhs.score;
|
||||
});
|
||||
if (cur_max_iter == cur_res.cend()) {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "Controller.h"
|
||||
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
bool asst::InfrastOfficeTask::_run()
|
||||
{
|
||||
m_all_available_opers.clear();
|
||||
@@ -22,7 +24,7 @@ bool asst::InfrastOfficeTask::_run()
|
||||
}
|
||||
swipe_to_the_left_of_operlist();
|
||||
|
||||
auto find_iter = std::ranges::find_if(m_all_available_opers,
|
||||
auto find_iter = ranges::find_if(m_all_available_opers,
|
||||
[&](const infrast::Oper& info) -> bool {
|
||||
return info.selected;
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "InfrastOperImageAnalyzer.h"
|
||||
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include "NoWarningCV.h"
|
||||
|
||||
@@ -45,7 +45,7 @@ void asst::InfrastOperImageAnalyzer::sort_by_loc()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
std::ranges::sort(m_result, [](const infrast::Oper& lhs, const infrast::Oper& rhs) -> bool {
|
||||
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;
|
||||
@@ -60,7 +60,7 @@ void asst::InfrastOperImageAnalyzer::sort_by_mood()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
std::ranges::sort(m_result, [](const infrast::Oper& lhs, const infrast::Oper& rhs) -> bool {
|
||||
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;
|
||||
@@ -271,7 +271,7 @@ void asst::InfrastOperImageAnalyzer::skill_analyze()
|
||||
|
||||
std::vector<std::pair<infrast::Skill, MatchRect>> possible_skills;
|
||||
// 逐个该设施内所有可能的技能,取得分最高的
|
||||
for (const auto& skill : Resrc.infrast().get_skills(m_facility) | std::views::values) {
|
||||
for (const auto& skill : Resrc.infrast().get_skills(m_facility) | views::values) {
|
||||
skill_analyzer.set_templ_name(skill.templ_name);
|
||||
|
||||
if (!skill_analyzer.analyze()) {
|
||||
@@ -296,7 +296,7 @@ void asst::InfrastOperImageAnalyzer::skill_analyze()
|
||||
// 匹配得分最高的id作为基准,排除有识别错误,其他的技能混进来了的情况
|
||||
// 即排除容器中,除了有同一个技能的不同等级,还有别的技能的情况
|
||||
auto max_iter =
|
||||
std::ranges::max_element(possible_skills, [](const auto& lhs, const auto& rhs) -> bool {
|
||||
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;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "Controller.h"
|
||||
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
bool asst::InfrastPowerTask::_run()
|
||||
{
|
||||
m_all_available_opers.clear();
|
||||
@@ -34,7 +36,7 @@ bool asst::InfrastPowerTask::_run()
|
||||
opers_detect();
|
||||
}
|
||||
|
||||
auto find_iter = std::ranges::find_if(m_all_available_opers,
|
||||
auto find_iter = ranges::find_if(m_all_available_opers,
|
||||
[&](const infrast::Oper& info) -> bool {
|
||||
return info.selected;
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "InfrastProductionTask.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include <calculator/calculator.hpp>
|
||||
|
||||
@@ -206,7 +207,7 @@ size_t asst::InfrastProductionTask::opers_detect()
|
||||
//--cur_available_num;
|
||||
continue;
|
||||
}
|
||||
auto find_iter = std::ranges::find_if(m_all_available_opers,
|
||||
auto find_iter = ranges::find_if(m_all_available_opers,
|
||||
[&](const infrast::Oper& oper) -> bool {
|
||||
if (oper.skills != cur_oper.skills) {
|
||||
return false;
|
||||
@@ -243,7 +244,7 @@ bool asst::InfrastProductionTask::optimal_calc()
|
||||
std::vector<infrast::SkillsComb> optimal_combs;
|
||||
optimal_combs.reserve(cur_max_num_of_opers);
|
||||
double max_efficient = 0;
|
||||
std::ranges::sort(all_available_combs,
|
||||
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);
|
||||
});
|
||||
@@ -328,7 +329,7 @@ bool asst::InfrastProductionTask::optimal_calc()
|
||||
// necessary里的技能,一个都不能少
|
||||
// TODO necessary暂时没做hash校验。因为没有需要比hash的necessary干员(
|
||||
for (const infrast::SkillsComb& nec_skills : group.necessary) {
|
||||
auto find_iter = std::ranges::find_if(cur_available_opers,
|
||||
auto find_iter = ranges::find_if(cur_available_opers,
|
||||
[&](const infrast::SkillsComb& arg) -> bool {
|
||||
return arg == nec_skills;
|
||||
});
|
||||
@@ -358,7 +359,7 @@ bool asst::InfrastProductionTask::optimal_calc()
|
||||
}
|
||||
}
|
||||
|
||||
std::ranges::sort(optional,
|
||||
ranges::sort(optional,
|
||||
[&](const infrast::SkillsComb& lhs,
|
||||
const infrast::SkillsComb& rhs) -> bool {
|
||||
return lhs.efficient.at(m_product) > rhs.efficient.at(m_product);
|
||||
@@ -387,7 +388,7 @@ bool asst::InfrastProductionTask::optimal_calc()
|
||||
continue;
|
||||
}
|
||||
std::string name = name_analyzer.get_result().front().text;
|
||||
hash_matched = std::ranges::find(opt.name_filter, name) != opt.name_filter.cend();
|
||||
hash_matched = ranges::find(opt.name_filter, name) != opt.name_filter.cend();
|
||||
}
|
||||
if (!hash_matched) {
|
||||
++find_iter;
|
||||
@@ -492,7 +493,7 @@ 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::ranges::remove_if(cur_all_opers,
|
||||
auto remove_iter = ranges::remove_if(cur_all_opers,
|
||||
[&](const infrast::Oper& rhs) -> bool {
|
||||
return rhs.mood_ratio < m_mood_threshold;
|
||||
}).begin();
|
||||
@@ -500,7 +501,7 @@ bool asst::InfrastProductionTask::opers_choose()
|
||||
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::ranges::find_if(cur_all_opers,
|
||||
auto find_iter = ranges::find_if(cur_all_opers,
|
||||
[&](const infrast::Oper& lhs) -> bool {
|
||||
if (lhs.skills != opt_iter->skills) {
|
||||
return false;
|
||||
@@ -517,7 +518,7 @@ bool asst::InfrastProductionTask::opers_choose()
|
||||
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();
|
||||
return ranges::find(std::as_const(opt_iter->name_filter), name) != opt_iter->name_filter.cend();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -540,7 +541,7 @@ bool asst::InfrastProductionTask::opers_choose()
|
||||
m_ctrler->click(find_iter->rect);
|
||||
}
|
||||
{
|
||||
auto avlb_iter = std::ranges::find_if(m_all_available_opers,
|
||||
auto avlb_iter = ranges::find_if(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);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "InfrastReceptionTask.h"
|
||||
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include "Controller.h"
|
||||
#include "InfrastClueImageAnalyzer.h"
|
||||
@@ -72,7 +72,7 @@ bool asst::InfrastReceptionTask::use_clue()
|
||||
if (!vacancy_analyzer.analyze()) {
|
||||
}
|
||||
const auto& vacancy = vacancy_analyzer.get_vacancy();
|
||||
for (const auto& id : vacancy | std::views::keys) {
|
||||
for (const auto& id : vacancy | views::keys) {
|
||||
Log.trace("InfrastReceptionTask | Vacancy", id);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "ItemConfiger.h"
|
||||
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
#include <meojson/json.hpp>
|
||||
|
||||
#include "Logger.hpp"
|
||||
@@ -21,10 +21,10 @@ 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 | std::views::keys) {
|
||||
for (const auto& item_id : material_sortid | views::keys) {
|
||||
m_ordered_material_item_id.emplace_back(item_id);
|
||||
}
|
||||
std::ranges::sort(m_ordered_material_item_id,
|
||||
ranges::sort(m_ordered_material_item_id,
|
||||
[&](const std::string& lhs, const std::string& rhs) -> bool {
|
||||
return material_sortid[lhs] < material_sortid[rhs];
|
||||
});
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
<ClInclude Include="AsstUtils.hpp" />
|
||||
<ClInclude Include="AsstTypes.h" />
|
||||
<ClInclude Include="AsstMsg.h" />
|
||||
<ClInclude Include="AsstRanges.hpp" />
|
||||
<ClInclude Include="AutoRecruitTask.h" />
|
||||
<ClInclude Include="AwardTask.h" />
|
||||
<ClInclude Include="BattleDataConfiger.h" />
|
||||
|
||||
@@ -114,6 +114,9 @@
|
||||
<ClInclude Include="AsstMsg.h">
|
||||
<Filter>头文件\Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AsstRanges.hpp">
|
||||
<Filter>头文件\Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AbstractConfiger.h">
|
||||
<Filter>头文件\Resource</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "MultiMatchImageAnalyzer.h"
|
||||
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
#include <utility>
|
||||
|
||||
#include "NoWarningCV.h"
|
||||
@@ -32,7 +32,7 @@ bool asst::MultiMatchImageAnalyzer::analyze()
|
||||
void asst::MultiMatchImageAnalyzer::sort_result_horizontal()
|
||||
{
|
||||
// 按位置排个序
|
||||
std::ranges::sort(m_result,
|
||||
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;
|
||||
@@ -46,7 +46,7 @@ void asst::MultiMatchImageAnalyzer::sort_result_horizontal()
|
||||
void asst::MultiMatchImageAnalyzer::sort_result_vertical()
|
||||
{
|
||||
// 按位置排个序
|
||||
std::ranges::sort(m_result,
|
||||
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;
|
||||
@@ -132,7 +132,7 @@ bool asst::MultiMatchImageAnalyzer::multi_match_templ(const cv::Mat templ)
|
||||
bool need_push = true;
|
||||
// 如果有两个点离得太近,只取里面得分高的那个
|
||||
// 一般相邻的都是刚刚push进去的,这里倒序快一点
|
||||
for (auto& iter : std::ranges::reverse_view(m_result)) {
|
||||
for (auto& iter : 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;
|
||||
|
||||
@@ -27,7 +27,7 @@ bool asst::OcrImageAnalyzer::analyze()
|
||||
if (!m_required.empty()) {
|
||||
if (m_full_match) {
|
||||
TextRectProc required_match = [&](TextRect& tr) -> bool {
|
||||
return std::ranges::find(m_required, tr.text) != m_required.cend();
|
||||
return ranges::find(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::ranges::find_if(m_required, is_sub) != m_required.cend();
|
||||
return ranges::find_if(m_required, is_sub) != m_required.cend();
|
||||
};
|
||||
preds_vec.emplace_back(required_search);
|
||||
}
|
||||
@@ -161,7 +161,7 @@ const std::vector<asst::TextRect>& asst::OcrImageAnalyzer::get_result() const no
|
||||
void asst::OcrImageAnalyzer::sort_result_horizontal()
|
||||
{
|
||||
// 按位置排个序
|
||||
std::ranges::sort(get_result(),
|
||||
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;
|
||||
@@ -180,7 +180,7 @@ void asst::OcrImageAnalyzer::sort_result_vertical()
|
||||
// |1 3|
|
||||
// |2 4|
|
||||
// +---+
|
||||
std::ranges::sort(get_result(),
|
||||
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;
|
||||
@@ -194,7 +194,7 @@ void asst::OcrImageAnalyzer::sort_result_vertical()
|
||||
|
||||
void asst::OcrImageAnalyzer::sort_result_by_score()
|
||||
{
|
||||
std::ranges::sort(get_result(),
|
||||
ranges::sort(get_result(),
|
||||
[](const TextRect& lhs, const TextRect& rhs) -> bool {
|
||||
return lhs.score > rhs.score;
|
||||
}
|
||||
@@ -214,7 +214,7 @@ void asst::OcrImageAnalyzer::sort_result_by_required()
|
||||
|
||||
auto& result = get_result();
|
||||
// 不在 m_required 中的将被排在最后
|
||||
std::ranges::sort(result,
|
||||
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];
|
||||
|
||||
@@ -35,7 +35,7 @@ bool asst::RecruitConfiger::parse(const json::value& json)
|
||||
}
|
||||
|
||||
// 按干员等级排个序
|
||||
std::ranges::sort(m_all_opers, [](const auto& lhs, const auto& rhs) -> bool {
|
||||
ranges::sort(m_all_opers, [](const auto& lhs, const auto& rhs) -> bool {
|
||||
return lhs.level > rhs.level;
|
||||
});
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include "AsstTypes.h"
|
||||
|
||||
@@ -71,16 +72,16 @@ namespace asst
|
||||
// intersection of two recruit combs
|
||||
friend RecruitCombs operator*(RecruitCombs& lhs, RecruitCombs& rhs)
|
||||
{
|
||||
std::ranges::sort(lhs.tags);
|
||||
std::ranges::sort(lhs.opers);
|
||||
std::ranges::sort(rhs.tags);
|
||||
std::ranges::sort(rhs.opers);
|
||||
ranges::sort(lhs.tags);
|
||||
ranges::sort(lhs.opers);
|
||||
ranges::sort(rhs.tags);
|
||||
ranges::sort(rhs.opers);
|
||||
|
||||
RecruitCombs result;
|
||||
|
||||
std::ranges::set_union(lhs.tags, rhs.tags, std::back_inserter(result.tags));
|
||||
ranges::set_union(lhs.tags, rhs.tags, std::back_inserter(result.tags));
|
||||
|
||||
std::ranges::set_intersection(lhs.opers, rhs.opers, std::back_inserter(result.opers));
|
||||
ranges::set_intersection(lhs.opers, rhs.opers, std::back_inserter(result.opers));
|
||||
|
||||
result.update_attributes();
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ bool asst::RecruitImageAnalyzer::tags_analyze()
|
||||
std::vector<std::string> all_tags_vec;
|
||||
all_tags_vec.assign(all_tags_set.begin(), all_tags_set.end());
|
||||
// 把因为“资深干员”是“高级资深干员”的子串,把“高级资深干员”放到最前面,免得先被“资深干员”匹配上了
|
||||
auto ssr_iter = std::ranges::find(all_tags_vec, "高级资深干员");
|
||||
auto ssr_iter = ranges::find(all_tags_vec, "高级资深干员");
|
||||
if (ssr_iter != all_tags_vec.end()) {
|
||||
std::swap(*ssr_iter, all_tags_vec.front());
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include "NoWarningCV.h"
|
||||
|
||||
@@ -383,7 +383,7 @@ bool asst::RoguelikeBattleTaskPlugin::abandon()
|
||||
|
||||
void asst::RoguelikeBattleTaskPlugin::all_melee_retreat()
|
||||
{
|
||||
for (const auto& loc : m_used_tiles | std::views::keys) {
|
||||
for (const auto& loc : m_used_tiles | views::keys) {
|
||||
auto& tile_info = m_normal_tile_info[loc];
|
||||
auto& type = tile_info.buildable;
|
||||
if (type == Loc::Melee || type == Loc::All) {
|
||||
@@ -621,7 +621,7 @@ asst::RoguelikeBattleTaskPlugin::DeployInfo asst::RoguelikeBattleTaskPlugin::cal
|
||||
return calc_best_plan(oper);
|
||||
}
|
||||
|
||||
std::ranges::sort(available_locations, comp_dist);
|
||||
ranges::sort(available_locations, comp_dist);
|
||||
|
||||
// 取距离最近的N个点,计算分数。然后使用得分最高的点
|
||||
constexpr int CalcPointCount = 4;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "RoguelikeFormationTaskPlugin.h"
|
||||
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include "RoguelikeFormationImageAnalyzer.h"
|
||||
#include "Controller.h"
|
||||
#include "TaskData.h"
|
||||
@@ -58,7 +60,7 @@ bool asst::RoguelikeFormationTaskPlugin::_run()
|
||||
}
|
||||
|
||||
auto& new_result = formation_analyzer.get_result();
|
||||
size_t new_selected_count = std::ranges::count_if(new_result,
|
||||
size_t new_selected_count = ranges::count_if(new_result,
|
||||
[](const auto& oper) { return oper.selected; });
|
||||
// 说明 select_count 计数没生效,即都没点上
|
||||
if (new_selected_count == pre_selected) {
|
||||
|
||||
@@ -32,13 +32,13 @@ bool asst::RoguelikeRecruitImageAnalyzer::analyze()
|
||||
info.name = name;
|
||||
info.elite = elite;
|
||||
info.level = level;
|
||||
info.required = std::ranges::find(order, name) != order.cend();
|
||||
info.required = 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::ranges::find_if(m_result,
|
||||
auto first_un_req = ranges::find_if(m_result,
|
||||
[&](const auto& info) -> bool {
|
||||
return info.required == false;
|
||||
});
|
||||
@@ -100,7 +100,7 @@ int asst::RoguelikeRecruitImageAnalyzer::match_level(const Rect& raw_roi)
|
||||
}
|
||||
|
||||
const std::string& level = analyzer.get_result().front().text;
|
||||
if (level.empty() || !std::ranges::all_of(level,
|
||||
if (level.empty() || !ranges::all_of(level,
|
||||
[](char c) -> bool {return std::isdigit(c);})) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ bool asst::RoguelikeRecruitTaskPlugin::check_core_char()
|
||||
break;
|
||||
}
|
||||
const auto& chars = analyzer.get_result();
|
||||
auto it = std::ranges::find_if(chars,
|
||||
auto it = ranges::find_if(chars,
|
||||
[&](const BattleRecruitOperInfo& oper) -> bool {
|
||||
return oper.name == core_opt.value();
|
||||
});
|
||||
|
||||
@@ -101,7 +101,7 @@ bool asst::RoguelikeShoppingTaskPlugin::_run()
|
||||
continue;
|
||||
}
|
||||
|
||||
auto find_it = std::ranges::find_if(result,
|
||||
auto find_it = 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;
|
||||
@@ -147,7 +147,7 @@ bool asst::RoguelikeShoppingTaskPlugin::_run()
|
||||
}
|
||||
|
||||
if (!goods.chars.empty()) {
|
||||
if (std::ranges::find_first_of(chars_list, goods.chars) == chars_list.cend()) {
|
||||
if (ranges::find_first_of(chars_list, goods.chars) == chars_list.cend()) {
|
||||
Log.trace("Ready to buy", goods.name,
|
||||
", but there is no such character, skip");
|
||||
continue;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "StageDropsImageAnalyzer.h"
|
||||
|
||||
#include <ranges>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include "NoWarningCV.h"
|
||||
|
||||
@@ -57,7 +57,7 @@ bool asst::StageDropsImageAnalyzer::analyze_stage_code()
|
||||
const auto& stages = Resrc.drops().get_all_stage_code();
|
||||
std::vector<std::string> stages_req(stages.cbegin(), stages.cend());
|
||||
// 名字长的放前面
|
||||
std::ranges::sort(stages_req,
|
||||
ranges::sort(stages_req,
|
||||
[](const std::string& lhs, const std::string& rhs) -> bool {
|
||||
return lhs.size() > rhs.size();
|
||||
});
|
||||
@@ -336,7 +336,7 @@ bool asst::StageDropsImageAnalyzer::analyze_baseline()
|
||||
}
|
||||
|
||||
Log.trace(__FUNCTION__, "baseline size", m_baseline.size());
|
||||
for (const auto& key : m_baseline | std::views::keys) {
|
||||
for (const auto& key : m_baseline | views::keys) {
|
||||
Log.trace(__FUNCTION__, "baseline", key.to_string());
|
||||
}
|
||||
|
||||
@@ -559,7 +559,7 @@ int asst::StageDropsImageAnalyzer::match_quantity(const Rect& roi)
|
||||
//}
|
||||
|
||||
if (digit_str.empty() ||
|
||||
!std::ranges::all_of(digit_str,
|
||||
!ranges::all_of(digit_str,
|
||||
[](const char& c) -> bool {return std::isdigit(c) || c == '.';})) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ void asst::StageDropsTaskPlugin::upload_to_penguin()
|
||||
for (const auto& drop : m_cur_info_json["drops"].as_array()) {
|
||||
static const std::vector<std::string> filter = { "NORMAL_DROP", "EXTRA_DROP" , "FURNITURE", "SPECIAL_DROP" };
|
||||
std::string drop_type = drop.at("dropType").as_string();
|
||||
if (std::ranges::find(filter, drop_type) == filter.cend()) {
|
||||
if (ranges::find(filter, drop_type) == filter.cend()) {
|
||||
continue;
|
||||
}
|
||||
if (drop.at("itemId").as_string().empty()) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "TaskData.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "AsstRanges.hpp"
|
||||
|
||||
#include <meojson/json.hpp>
|
||||
|
||||
@@ -23,7 +24,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::ranges::transform(algorithm_str, algorithm_str.begin(), to_lower);
|
||||
ranges::transform(algorithm_str, algorithm_str.begin(), to_lower);
|
||||
auto algorithm = AlgorithmType::Invalid;
|
||||
if (algorithm_str == "matchtemplate") {
|
||||
algorithm = AlgorithmType::MatchTemplate;
|
||||
@@ -97,7 +98,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::ranges::transform(action, action.begin(), to_lower);
|
||||
ranges::transform(action, action.begin(), to_lower);
|
||||
if (action == "clickself") {
|
||||
task_info_ptr->action = ProcessTaskAction::ClickSelf;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace asst
|
||||
|
||||
template<typename TargetTaskInfoType>
|
||||
requires std::derived_from<TargetTaskInfoType, TaskInfo>
|
||||
&& !std::same_as<TargetTaskInfoType, TaskInfo> // Parameter must be a TaskInfo and not same as TaskInfo
|
||||
&& (!std::same_as<TargetTaskInfoType, TaskInfo>) // Parameter must be a TaskInfo and not same as TaskInfo
|
||||
std::shared_ptr<TargetTaskInfoType> get(const std::string& name)
|
||||
{
|
||||
auto it = m_all_tasks_info.find(name);
|
||||
|
||||
Reference in New Issue
Block a user