完成基建制造and贸易站,非组合干员的选择

This commit is contained in:
MistEO
2021-09-10 00:53:36 +08:00
parent 2ada30fae0
commit 0ab487d6cd
6 changed files with 695 additions and 29 deletions

View File

@@ -226,6 +226,11 @@ namespace asst {
return name == rhs.name;
}
};
// 基建干员组合
struct OperInfrastComb {
std::vector<OperInfrastInfo> comb;
int efficiency = 0; // 组合的效率
};
constexpr double DoubleDiff = 1e-12;
}

View File

@@ -31,18 +31,22 @@ bool InfrastConfiger::parse(json::value&& json)
{
std::string key = facility["facility"].as_string();
std::vector<std::vector<OperInfrastInfo>> combs_vec;
for (json::value& comb : facility["combs"].as_array())
std::vector<OperInfrastComb> combs_vec;
for (json::value& comb_json : facility["combs"].as_array())
{
std::vector<OperInfrastInfo> opers;
for (json::value& oper : comb["opers"].as_array()) {
for (json::value& oper : comb_json["opers"].as_array()) {
OperInfrastInfo info;
info.name = oper["name"].as_string();
info.elite = oper.get("elite", 0);
info.level = oper.get("level", 0);
opers.emplace_back(std::move(info));
}
combs_vec.emplace_back(std::move(opers));
OperInfrastComb comb;
comb.comb = std::move(opers);
comb.efficiency = comb_json["efficiency"].as_integer();
combs_vec.emplace_back(std::move(comb));
}
m_infrast_combs.emplace(key, std::move(combs_vec));

View File

@@ -23,7 +23,7 @@ namespace asst {
std::unordered_map<std::string, std::string> m_oper_name_feat; // 根据关键字需要特征检测干员名如果OCR识别到了key的内容但是却没有value的内容则进行特征检测进一步确认
std::unordered_set<std::string> m_oper_name_feat_whatever; // 无论如何都进行特征检测的干员名
// 各个设施内的可能干员组合注意值是vector是有序的
std::unordered_map<std::string, std::vector<std::vector<OperInfrastInfo>>> m_infrast_combs;
std::unordered_map<std::string, std::vector<OperInfrastComb>> m_infrast_combs;
// 各个设施的识别结束标记,识别到这个名字就停止继续识别了,一般放列表中最后几个人名
std::unordered_map<std::string, std::vector<std::string>> m_infrast_end_flag;

View File

@@ -89,6 +89,7 @@ bool asst::InfrastStationTask::run()
return false;
}
auto cur_opers_info = std::move(detect_ret.value());
// TODO可以识别一次把前6个最优解都列出来最多6个制造站然后就不用每次都识别并计算最优解了
std::list<std::string> optimal_comb = calc_optimal_comb(cur_opers_info);
bool select_ret = swipe_and_select(optimal_comb);
}
@@ -171,35 +172,61 @@ std::list<std::string> asst::InfrastStationTask::calc_optimal_comb(
// 配置文件中的干员组合,和抓出来的干员名比对,如果组合中的干员都有,那就用这个组合
// 注意配置中的干员组合需要是有序的
// Todo 时间复杂度起飞了,需要优化下
std::list<std::string> optimal_comb; // OperInfrastInfo是带精英化和等级信息的基建里识别不到也用不到这里只保留干员名
for (const auto& name_vec : InfrastConfiger::get_instance().m_infrast_combs[m_facility]) {
int count = 0;
std::list<std::string> temp_comb;
for (const OperInfrastInfo& info : name_vec) {
// 找到了干员名,而且当前精英化等级需要大于等于配置文件中要求的精英化等级
if (cur_opers_info.find(info.name) != cur_opers_info.cend()
&& cur_opers_info.at(info.name).elite >= info.elite) {
++count;
temp_comb.emplace_back(info.name);
OperInfrastComb three_optimal_comb; // 三人组合的最优解
OperInfrastComb single_optimal_comb; // 由三个单人组成的组合 中的最优解
for (const OperInfrastComb& comb : InfrastConfiger::get_instance().m_infrast_combs[m_facility]) {
if (comb.comb.size() == 3) {
int count = 0;
for (const OperInfrastInfo& info : comb.comb) {
// 找到了干员名,而且当前精英化等级需要大于等于配置文件中要求的精英化等级
auto find_iter = cur_opers_info.find(info.name);
if (find_iter != cur_opers_info.cend()
&& find_iter->second.elite >= info.elite) {
++count;
}
else {
break;
}
}
else {
if (count == 3) {
three_optimal_comb = comb;
break;
}
}
if (count != 0 && count == name_vec.size()) {
optimal_comb = temp_comb;
break;
else if (comb.comb.size() == 1) {
const auto& cur_info = comb.comb.at(0);
auto find_iter = cur_opers_info.find(cur_info.name);
if (find_iter != cur_opers_info.cend()
&& find_iter->second.elite >= cur_info.elite) {
single_optimal_comb.comb.emplace_back(cur_info);
single_optimal_comb.efficiency += comb.efficiency;
if (single_optimal_comb.comb.size() >= 3) {
break;
}
}
}
else {
// 配置文件中没有两人的不可能走到这里TODO报错。
// 以后游戏更新了有双人的再说,思路是一样的,找出双人组合中干员都有的+单人组合中有的。
// 再建一个OperInfrastComb比一下效率
}
}
OperInfrastComb optimal_comb = three_optimal_comb.efficiency >= single_optimal_comb.efficiency
? three_optimal_comb : single_optimal_comb;
std::list<std::string> optimal_opers_name;
std::vector<std::string> optimal_comb_gbk; // 给回调json用的gbk的
for (const std::string& name : optimal_comb) {
optimal_comb_gbk.emplace_back(Utf8ToGbk(name));
for (const auto& info : optimal_comb.comb) {
optimal_opers_name.emplace_back(info.name);
optimal_comb_gbk.emplace_back(Utf8ToGbk(info.name));
}
json::value opers_json;
opers_json["comb"] = json::array(optimal_comb_gbk);
m_callback(AsstMsg::InfrastComb, opers_json, m_callback_arg);
return optimal_comb;
return optimal_opers_name;
}
bool asst::InfrastStationTask::swipe_and_select(std::list<std::string>& name_comb, int swipe_max_times)

View File

@@ -17,6 +17,7 @@ namespace asst {
}
protected:
constexpr static int SwipeMaxTimes = 17;
constexpr static int MaxOpers = 3; // 单个制造站/贸易站最大干员数
// 一边滑动一边识别
virtual std::optional<std::unordered_map<std::string, OperInfrastInfo>> swipe_and_detect() override;

View File

@@ -54,6 +54,249 @@
}
],
"efficiency": 90
},
{
"opers": [
{
"name": "槐琥",
"elite": 2
}
],
"efficiency": 40
},
{
"opers": [
{
"name": "食铁兽",
"elite": 2
}
],
"efficiency": 35
},
{
"opers": [
{
"name": "断罪者",
"elite": 2
}
],
"efficiency": 35
},
{
"opers": [
{
"name": "白雪",
"elite": 1
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "霜叶",
"elite": 1
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "红豆",
"elite": 0
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "Castle-3",
"elite": 0
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "梅尔",
"elite": 2
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "帕拉斯",
"elite": 2
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "水月",
"elite": 2
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "白面鸮",
"elite": 2
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "赫默",
"elite": 2
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "杰西卡",
"elite": 0
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "史都华德",
"elite": 1
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "香草",
"elite": 0
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "调香师",
"elite": 1
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "石棉",
"elite": 0
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "泡普卡",
"elite": 0
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "芬",
"elite": 0
}
],
"efficiency": 23
},
{
"opers": [
{
"name": "克洛斯",
"elite": 0
}
],
"efficiency": 20
},
{
"opers": [
{
"name": "豆苗",
"elite": 0
}
],
"efficiency": 15
},
{
"opers": [
{
"name": "流星",
"elite": 0
}
],
"efficiency": 15
},
{
"opers": [
{
"name": "夜刀",
"elite": 0
}
],
"efficiency": 15
},
{
"opers": [
{
"name": "蛇屠箱",
"elite": 0
}
],
"efficiency": 10
},
{
"opers": [
{
"name": "黑角",
"elite": 0
}
],
"efficiency": 10
},
{
"opers": [
{
"name": "卡缇",
"elite": 0
}
],
"efficiency": 10
},
{
"opers": [
{
"name": "米格鲁",
"elite": 0
}
],
"efficiency": 10
}
],
"endFlag": [
@@ -90,21 +333,255 @@
{
"opers": [
{
"name": "",
"elite": 2
},
{
"name": "夜烟",
"name": "贝娜",
"elite": 0
},
{
"name": "泡泡",
"elite": 1
},
{
"name": "火神",
"elite": 2
}
],
"efficiency": 93
},
{
"opers": [
{
"name": "温蒂",
"elite": 2
},
{
"name": "异客",
"elite": 2
},
{
"name": "森蚺",
"elite": 2
}
],
"efficiency": 90
},
{
"opers": [
{
"name": "砾",
"elite": 2
}
],
"efficiency": 35
},
{
"opers": [
{
"name": "斑点",
"elite": 0
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "夜烟",
"elite": 0
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "帕拉斯",
"elite": 2
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "槐琥",
"elite": 2
}
],
"efficiency": 40
},
{
"opers": [
{
"name": "梅尔",
"elite": 2
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "水月",
"elite": 2
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "白面鸮",
"elite": 2
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "赫默",
"elite": 2
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "杰西卡",
"elite": 0
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "史都华德",
"elite": 1
}
],
"efficiency": 95
"efficiency": 25
},
{
"opers": [
{
"name": "香草",
"elite": 0
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "调香师",
"elite": 1
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "石棉",
"elite": 0
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "泡普卡",
"elite": 0
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "芬",
"elite": 0
}
],
"efficiency": 23
},
{
"opers": [
{
"name": "克洛斯",
"elite": 0
}
],
"efficiency": 20
},
{
"opers": [
{
"name": "豆苗",
"elite": 0
}
],
"efficiency": 15
},
{
"opers": [
{
"name": "流星",
"elite": 0
}
],
"efficiency": 15
},
{
"opers": [
{
"name": "夜刀",
"elite": 0
}
],
"efficiency": 15
},
{
"opers": [
{
"name": "蛇屠箱",
"elite": 0
}
],
"efficiency": 10
},
{
"opers": [
{
"name": "黑角",
"elite": 0
}
],
"efficiency": 10
},
{
"opers": [
{
"name": "卡缇",
"elite": 0
}
],
"efficiency": 10
},
{
"opers": [
{
"name": "米格鲁",
"elite": 0
}
],
"efficiency": 10
}
],
"endFlag": [
"安洁莉娜",
"嵯峨",
@@ -188,6 +665,159 @@
}
],
"efficiency": 100
},
{
"opers": [
{
"name": "空弦",
"elite": 2
}
],
"efficiency": 40
},
{
"opers": [
{
"name": "能天使",
"elite": 2
}
],
"efficiency": 35
},
{
"opers": [
{
"name": "雪雉",
"elite": 2
}
],
"efficiency": 35
},
{
"opers": [
{
"name": "古米",
"elite": 0
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "空爆",
"elite": 0
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "月见夜",
"elite": 0
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "空",
"elite": 2
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "安比尔",
"elite": 1
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "缠丸",
"elite": 1
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "芬",
"elite": 1
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "芬",
"elite": 1
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "慕斯",
"elite": 0
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "夜刀",
"elite": 0
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "夜烟",
"elite": 1
}
],
"efficiency": 30
},
{
"opers": [
{
"name": "玫兰莎",
"elite": 0
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "梓兰",
"elite": 0
}
],
"efficiency": 25
},
{
"opers": [
{
"name": "远山",
"elite": 0
}
],
"efficiency": 25
}
],
"endFlag": [
@@ -207,7 +837,6 @@
"夜莺",
"推进之王",
"星熊",
"银灰",
"浊心斯卡蒂",
"歌蕾蒂娅",
"莫斯提马",