diff --git a/src/engine/HRD_analy.cpp b/src/engine/HRD_analy.cpp index 06e3e79..c81c4b0 100644 --- a/src/engine/HRD_analy.cpp +++ b/src/engine/HRD_analy.cpp @@ -5,6 +5,108 @@ #include #include "HRD_analy.h" +void HRD_analy::Output_Graph(unsigned long long Code, unsigned int square_width, unsigned int square_gap, char str[3]) { + Case_cal dat; + unsigned int i, j; + unsigned int x, y; + unsigned int width, height; + bool exclude[4][5]; // 用于标记排除 + vector < vector > temp; + temp.resize(square_width * 4 + square_gap * 3); + for (x = 0; x < temp.size(); x++) { + temp[x].resize(square_width * 5 + square_gap * 4); + for (y = 0; y < temp[0].size(); y++) { + temp[x][y] = false; + } + } + for (x = 0; x < 4; x++) { // 初始化exclude + for (y = 0; y < 5; y++) { + exclude[x][y] = false; + } + } + Parse_Code(dat, Code); + for (y = 0; y < 5; y++) { // 遍历20个格 + for (x = 0; x < 4; x++) { + if (exclude[x][y] == true || dat.status[x][y] == 0xFE) {continue;} // 该格为空或已被占用 + switch (dat.type[dat.status[x][y]]) { // type -> 0 / 1 / 2 / 3 + case 0: // 2 * 2 + width = height = 2; + exclude[x][y + 1] = exclude[x + 1][y] = exclude[x + 1][y + 1] = true; + break; + case 1: // 2 * 1 + width = 2; + height = 1; + exclude[x + 1][y] = true; + break; + case 2: // 1 * 2 + width = 1; + height = 2; + exclude[x][y + 1] = true; + break; + case 3: // 1 * 1 + width = height = 1; + break; + } + if (width == 1) { + width = square_width; + } else { + width = square_width * 2 + square_gap; + } + if (height == 1) { + height = square_width; + } else { + height = square_width * 2 + square_gap; + } + for (i = 0; i < width; i++) { + for (j = 0; j < height; j++) { + temp[x * (square_width + square_gap) + i][y * (square_width + square_gap) + j] = true; + } + } + } + } + width = temp.size(); + height = temp[0].size(); + for (x = 0; x < width + square_gap * 2 + 2; x++) { + cout << str; + } + cout << endl; + for (y = 0; y < square_gap; y++) { + cout << str; + for (x = 0; x < width + square_gap * 2; x++) { + cout << " "; + } + cout << str << endl; + } + for (y = 0; y < height; y++) { + cout << str; + for (x = 0; x < square_gap; x++) { + cout << " "; + } + for (x = 0; x < width; x++) { + if (temp[x][y] == true) { + cout << str; + } else { + cout << " "; + } + } + for (x = 0; x < square_gap; x++) { + cout << " "; + } + cout << str << endl; + } + for (y = 0; y < square_gap; y++) { + cout << str; + for (x = 0; x < width + square_gap * 2; x++) { + cout << " "; + } + cout << str << endl; + } + for (x = 0; x < width + square_gap * 2 + 2; x++) { + cout << str; + } + cout << endl; +} + void HRD_analy::Output_Detail(string File_name) { // 输出分析结果到文件 unsigned int i, j, k; ofstream output; @@ -13,6 +115,7 @@ void HRD_analy::Output_Detail(string File_name) { // 输出分析结果到文件 cout << "Output into: " << File_name << "..."; } output.open(File_name); + // min_solution output << "[Min_solution_step]" << endl; output << min_solution_step << endl; output << "[Min_solution_case]" << endl; @@ -20,6 +123,7 @@ void HRD_analy::Output_Detail(string File_name) { // 输出分析结果到文件 for (i = 0; i < min_solution_case.size(); i++) { output << Change_str(min_solution_case[i]) << endl; } + // farthest output << "[Farthest_step]" << endl; output << farthest_step << endl; output << "[Farthest_case]" << endl; @@ -27,11 +131,13 @@ void HRD_analy::Output_Detail(string File_name) { // 输出分析结果到文件 for (i = 0; i < farthest_case.size(); i++) { output << Change_str(farthest_case[i]) << endl; } + // solution output << "[Solution]" << endl; output << "num: " << solution_num << endl; for (i = 0; i < solution_case.size(); i++) { output << Change_str(solution_case[i]) << "(" << solution_step[i] << ")" << endl; } + // layer output << "[Layer_Size]" << endl; for (i = 0; i < Layer.size(); i++) { output << i << " -> " << Layer[i].size() << endl; @@ -486,7 +592,7 @@ void HRD_analy::Get_Code(Case_cal &dat) { // 获取编码并存储在dat.code dat.code &= 0xFFFFFFFFF; // 清除高28位内容 } -bool HRD_analy::Parse_Code(unsigned long long Code) { +bool HRD_analy::Parse_Code(unsigned long long Code) { // 外部解析函数 结果储存在Parse_dat 返回编码正确性 Parse_dat.layer_num = Parse_dat.layer_index = 0; return Parse_Code(Parse_dat, Code); } @@ -506,7 +612,7 @@ bool HRD_analy::Parse_Code(Case_cal &dat, unsigned long long Code) { // 解析 } num = 0; for (i = 15; i >= 0; i--) { // 载入排列到range - range[i] = Code & 0x3 ; + range[i] = Code & 0x3; if (range[i] == 0) {num++;} Code >>= 2; } @@ -517,7 +623,6 @@ bool HRD_analy::Parse_Code(Case_cal &dat, unsigned long long Code) { // 解析 x = Code % 4; y = Code / 4; dat.status[x][y] = dat.status[x + 1][y] = dat.status[x][y + 1] = dat.status[x + 1][y + 1] = 0; - num = x = y = 0; for (i = 0; i < 16; i++) { while (dat.status[x][y] != 0xFF) { // 找到下一个未填入的位置 diff --git a/src/engine/HRD_analy.h b/src/engine/HRD_analy.h index 3678058..8bb923a 100644 --- a/src/engine/HRD_analy.h +++ b/src/engine/HRD_analy.h @@ -41,6 +41,8 @@ class HRD_analy { bool Parse_Code(unsigned long long Code); void Analyse_Case(unsigned long long code); void Output_Detail(string File_name); + void Free_Data(); + void Output_Graph(unsigned long long Code, unsigned int square_width, unsigned int square_gap, char str[2]); private: vector Layer_hash[0x10000]; // 哈希表 @@ -53,7 +55,6 @@ class HRD_analy { void Find_Next_Case(Case_cal &dat_raw); void Add_Case(Case_cal *dat); void Calculate(unsigned long long code); - void Free_Data(); }; #endif diff --git a/src/engine/HRD_cal.cpp b/src/engine/HRD_cal.cpp index f09200a..4e3a715 100644 --- a/src/engine/HRD_cal.cpp +++ b/src/engine/HRD_cal.cpp @@ -15,7 +15,7 @@ vector HRD_cal::Calculate_All(unsigned long long Code) { // for (i = 0; i < List.size(); i++) { data.push_back((*List[i]).code); // 储存计算结果 } - init_data(); + init_data(); // 防止内存泄漏 return data; } @@ -35,7 +35,7 @@ vector HRD_cal::Calculate(unsigned long long Code, unsigned if (flag == true) { // 若找到目标 return Get_Path(result); } else { // 未找到目标 - init_data(); + init_data(); // 防止内存泄漏 return temp; // 返回空序列 } } @@ -55,7 +55,7 @@ vector HRD_cal::Calculate(unsigned long long Code) { // 寻 if (flag == true) { // 若找到解 return Get_Path(result); } else { // 无解 - init_data(); + init_data(); // 防止内存泄漏 return temp; // 返回空序列 } } @@ -86,7 +86,7 @@ void HRD_cal::init_data() { // 初始化数据结构 List_source.clear(); } -bool HRD_cal::Check_Code(unsigned long long Code) { +bool HRD_cal::Check_Code(unsigned long long Code) { // 检查编码: 错误 -> false / 正确 -> true Case_cal dat; return Parse_Code(dat, Code); } @@ -387,7 +387,7 @@ bool HRD_cal::Parse_Code(Case_cal &dat, unsigned long long Code) { // 解析编 } num = 0; for (i = 15; i >= 0; i--) { // 载入排列到range - range[i] = Code & 0x3 ; + range[i] = Code & 0x3; if (range[i] == 0) {num++;} Code >>= 2; } @@ -398,7 +398,6 @@ bool HRD_cal::Parse_Code(Case_cal &dat, unsigned long long Code) { // 解析编 x = Code % 4; y = Code / 4; dat.status[x][y] = dat.status[x + 1][y] = dat.status[x][y + 1] = dat.status[x + 1][y + 1] = 0; - num = x = y = 0; for (i = 0; i < 16; i++) { while (dat.status[x][y] != 0xFF) { // 找到下一个未填入的位置 diff --git a/src/engine/HRD_group.cpp b/src/engine/HRD_group.cpp index debe996..8c25f6b 100644 --- a/src/engine/HRD_group.cpp +++ b/src/engine/HRD_group.cpp @@ -8,20 +8,53 @@ ofstream output_farthest; ofstream output_solution; +ifstream input_seed; -void HRD_group::Batch_Analyse(unsigned long long seed, string name_farthest, string name_solution, bool is_output_solution) { +bool HRD_group::Multi_Analyse(string seed_File_name, string name_farthest, string name_solution, bool is_output_solution) { HRD_cal cal; + char str[10]; vector dat; - if (cal.Check_Code(seed) == false) {return;} - dat = cal.Calculate_All(seed); - sort(dat.begin(), dat.end()); - File_name_farthest = name_farthest; - File_name_solution = name_solution; + vector seed; // 储存所有将要计算的布局编码 + input_seed.open(seed_File_name); + while (input_seed.eof() != true) { // 从外部文件读入列表 + input_seed >> str; + seed.push_back(Change_int(str)); + } + for (unsigned int i = 0; i < seed.size(); i++) { // 判断编码正确性 + if (cal.Check_Code(seed[i]) == false) { + cout << "input code error" << endl; // 发现错误编码 + return false; // 退出 + } + } Output_solution_case = is_output_solution; - Analyse_Group(dat); + output_farthest.open(name_farthest); + output_solution.open(name_solution); + for (unsigned int i = 0; i < seed.size(); i++) { + cout << "Start: " << Change_str(seed[i]) << endl; + dat = cal.Calculate_All(seed[i]); // 得到整个群 + sort(dat.begin(), dat.end()); // 排列 + Analyse_Group(dat); // 分析整个群 + } + output_farthest.close(); + output_solution.close(); + return true; } -void HRD_group::Analyse_Group(vector dat) { // 传入整个群 并将结果以csv格式输出到文件 +void HRD_group::Batch_Analyse(unsigned long long seed, string name_farthest, string name_solution, bool is_output_solution) { // 根据群中一个布局分析整个群全部布局的参数 并将结果以csv格式输出到文件 + HRD_cal cal; + vector dat; + if (cal.Check_Code(seed) == false) {return;} // 编码错误 退出 + dat = cal.Calculate_All(seed); // 得到整个群 + sort(dat.begin(), dat.end()); // 排列 + Output_solution_case = is_output_solution; + output_farthest.open(name_farthest); + output_solution.open(name_solution); + Analyse_Group(dat); // 分析整个群 + output_farthest.close(); + output_solution.close(); +} + +void HRD_group::Analyse_Group(vector dat) { // 传入整个群并将结果输出到文件 unsigned int i, j, k; int hash_index; vector List; // 全组数据 @@ -52,8 +85,6 @@ void HRD_group::Analyse_Group(vector dat) { // 传入整个 } } Case_detail *result; - output_farthest.open(File_name_farthest); - output_solution.open(File_name_solution); for(i = 0; i < List.size(); i++) { // 遍历整个队列 for (k = 0; k < List.size(); k++) { // 初始化 (*List[k]).Layer_num = -1; @@ -61,13 +92,11 @@ void HRD_group::Analyse_Group(vector dat) { // 传入整个 } result = Analyse_Case(List[i]); // 计算对应布局数据并储存到result中 Output_detail(result); - delete result; + delete result; // 释放内存 if (i % 13 == 0) { cout << i << "/" << List.size() << endl; } } - output_farthest.close(); - output_solution.close(); for (i = 0; i < List.size(); i++) { // 释放List数据 delete List[i]; } @@ -429,7 +458,7 @@ bool HRD_group::Parse_Code(Case_cal &dat, unsigned long long Code) { // 解析 } num = 0; for (i = 15; i >= 0; i--) { // 载入排列到range - range[i] = Code & 0x3 ; + range[i] = Code & 0x3; if (range[i] == 0) {num++;} Code >>= 2; } diff --git a/src/engine/HRD_group.h b/src/engine/HRD_group.h index f8f8745..8b9bc10 100644 --- a/src/engine/HRD_group.h +++ b/src/engine/HRD_group.h @@ -10,6 +10,7 @@ class HRD_group { unsigned long long Change_int(char str[10]); string Change_str(unsigned long long dat); void Batch_Analyse(unsigned long long seed, string name_farthest, string name_solution, bool is_output_solution); + bool Multi_Analyse(string seed_File_name, string name_farthest, string name_solution, bool is_output_solution); private: struct Case_cal { @@ -39,9 +40,7 @@ class HRD_group { vector solution_step; }; vector Next_Case_dat; // 储存Find_Next_Case找到的结果 - string File_name_farthest; - string File_name_solution; - bool Output_solution_case; + bool Output_solution_case; // 是否输出全部solution_case bool Parse_Code(Case_cal &dat, unsigned long long Code); void Get_Code(Case_cal &dat); diff --git a/src/engine/HRD_statistic.cpp b/src/engine/HRD_statistic.cpp index 60f6b3b..82b928d 100644 --- a/src/engine/HRD_statistic.cpp +++ b/src/engine/HRD_statistic.cpp @@ -7,70 +7,112 @@ #include "HRD_analy.h" #include "HRD_statistic.h" -void HRD_statistic::Find_All_Case(string File_name) { +void HRD_statistic::All_Statistic() { Find_All_Case(); - Output_All_Case(File_name); + Sort_All_Case(); + Output_All_Case("All_Case.txt"); + Output_main_table("main.csv"); + Get_seed(); } -void HRD_statistic::Make_main_table(string File_name) { +void HRD_statistic::Find_All_Case(string File_name) { // 找到所有编码并输出到文件 Find_All_Case(); - Sort_All_Case(); - Output_main_table(File_name); + Output_All_Case(File_name); } -void HRD_statistic::Sort_All_Case() { +void HRD_statistic::Get_seed() { + HRD_cal cal; + unsigned int i, j; + string File_name; + ofstream output_seed; + vector case_index; + unsigned char jiang_num, bing_num, style_num; + for (jiang_num = 0; jiang_num <= 7; jiang_num++) { // 遍历全部jiang_num-bing_num-style_num组 + for (bing_num = 0; bing_num <= (14 - jiang_num * 2); bing_num++) { + for (style_num = 0; style_num <= jiang_num; style_num++){ + cout << int(jiang_num) << "-" << int(bing_num) << "-" << int(style_num) << " -> "; + case_index.clear(); + for (i = 0; i < All_Case.size(); i++) { // 在全部布局中找到符合当前要求的布局 + if ((*All_Case[i]).jiang_num == jiang_num && (*All_Case[i]).bing_num == bing_num && (*All_Case[i]).style_num == style_num && (*All_Case[i]).group_index == 0) { + case_index.push_back(i); + } + } + cout << case_index.size() << endl; + if (case_index.size() == 0) {continue;} + for (i = 0; i < case_index.size() - 1; i++) { + for (j = 0; j < case_index.size() - i - 1; j++) { + if ((*All_Case[case_index[j]]).group_num > (*All_Case[case_index[j + 1]]).group_num) { + swap(case_index[j], case_index[j + 1]); + } + } + } + File_name = to_string(jiang_num) + "-" + to_string(bing_num) + "-" + to_string(style_num) + ".txt"; + output_seed.open(File_name); + for (i = 0; i < case_index.size(); i++) { // 录入找到布局的编码 + output_seed << cal.Change_str((*All_Case[case_index[i]]).code); + if (i != case_index.size() - 1) { // 如果不是最后一组就输出回车 + output_seed << endl; + } + } + output_seed.close(); + } + } + } +} + +void HRD_statistic::Sort_All_Case() { // 整理所有布局 HRD_analy analy; unsigned int i, num; unsigned char jiang_num, bing_num, style_num; - for (i = 0; i < All_Case.size(); i++) { - analy.Parse_Code((*All_Case[i]).code); + for (i = 0; i < All_Case.size(); i++) { // 遍历全部布局 + analy.Parse_Code((*All_Case[i]).code); // 解析布局 jiang_num = bing_num = style_num = 0; - for (num = 0; num < 15; num++) { + for (num = 1; num < 15; num++) { // 遍历所有棋子 switch (analy.Parse_dat.type[num]) { - case 1: + case 1: // 2 * 1 jiang_num++; style_num++; break; - case 2: + case 2: // 1 * 2 jiang_num++; break; - case 3: + case 3: // 1 * 2 bing_num++; break; - default: + default: // space continue; } } (*All_Case[i]).jiang_num = jiang_num; (*All_Case[i]).bing_num = bing_num; (*All_Case[i]).style_num = style_num; - if (i % 1000000 == 0) { + if (i % 1000000 == 0) { // 显示计算进度 cout << i << "/" << All_Case.size() << endl; } } vector case_res; vector case_index; vector case_code; - for (jiang_num = 0; jiang_num <= 7; jiang_num++) { + for (jiang_num = 0; jiang_num <= 7; jiang_num++) { // 遍历全部jiang_num-bing_num-style_num组 for (bing_num = 0; bing_num <= (14 - jiang_num * 2); bing_num++) { for (style_num = 0; style_num <= jiang_num; style_num++){ cout << int(jiang_num) << "-" << int(bing_num) << "-" << int(style_num); case_index.clear(); case_code.clear(); - for (i = 0; i < All_Case.size(); i++) { + for (i = 0; i < All_Case.size(); i++) { // 在全部布局中找到符合当前要求的布局 if ((*All_Case[i]).jiang_num == jiang_num && (*All_Case[i]).bing_num == bing_num && (*All_Case[i]).style_num == style_num) { - case_index.push_back(i); + case_index.push_back(i); // 记录找到布局的索引 } } - for (i = 0; i < case_index.size(); i++) { + for (i = 0; i < case_index.size(); i++) { // 录入找到布局的编码 case_code.push_back((*All_Case[case_index[i]]).code); } cout << " (" << case_code.size() << ") ..."; - case_res = Split_Group(case_code); - for (i = 0; i < case_res.size(); i++) { - (*All_Case[case_index[i]]).group_num = (*case_res[i]).group_num; + case_res = Split_Group(case_code); // 进行群组分割 + for (i = 0; i < case_res.size(); i++) { // 遍历分割结果 + (*All_Case[case_index[i]]).group_num = (*case_res[i]).group_num; // 记录群组分类结果 (*All_Case[case_index[i]]).group_index = (*case_res[i]).group_index; - delete case_res[i]; + delete case_res[i]; // 释放内存 } cout << "OK" << endl; } @@ -78,80 +120,78 @@ void HRD_statistic::Sort_All_Case() { } } -vector HRD_statistic::Split_Group(vector input_dat) { +vector HRD_statistic::Split_Group(vector input_dat) { // 将输入的数据进行群组分割 输入的数据必须是一个或多个群的集合 输入的数据必须从大到小排列 unsigned int i, j; HRD_cal cal; - list case_list; - list case_list_bak; - vector output_dat; + list case_list; // 计算中间序列 + vector output_dat; // 储存计算结果 vector dat; - list ::iterator it; - vector < vector > groups; - for (i = 0; i < input_dat.size(); i++) { + list ::iterator it; // 声明迭代器 + vector < vector > groups; // 记录群组数组 + for (i = 0; i < input_dat.size(); i++) { // 记录输入的编码 Case_group *temp = new Case_group; (*temp).id = i; (*temp).code = input_dat[i]; case_list.push_back(temp); - case_list_bak.push_back(temp); } - while (case_list.size() != 0) { - it = case_list.begin(); - dat = cal.Calculate_All((*(*it)).code); - sort(dat.begin(), dat.end()); - groups.resize(groups.size() + 1); - for (i = 0; i < dat.size(); i++) { - while (it != case_list.end()) { - if (dat[i] == (*(*it)).code) { - groups[groups.size() - 1].push_back(*it); - case_list.erase(it++); - break; + while (case_list.size() != 0) { // 循环分割群组 + it = case_list.begin(); // 定位当前序列起始点 + dat = cal.Calculate_All((*(*it)).code); // 计算起始点编码所在的整个群 + sort(dat.begin(), dat.end()); // 整理顺序 + groups.resize(groups.size() + 1); // groups增加一组 + for (i = 0; i < dat.size(); i++) { // 遍历搜索到的整个群 + while (it != case_list.end()) { // 直到序列的结尾 + if (dat[i] == (*(*it)).code) { // 在序列中找到 + groups[groups.size() - 1].push_back(*it); // 记录找到的编码 + case_list.erase(it++); // 删除序列中当前的编码 并指向序列中下一个编码 + break; // 退出循环 } - it++; + it++; // 指向序列中下一个编码 } } } - if (groups.size() == 0) {return output_dat;} - for (i = 0; i < groups.size() - 1; i++) { + if (groups.size() == 0) {return output_dat;} // 如果找到0个群组则退出 + for (i = 0; i < groups.size() - 1; i++) { // 根据群的大小进行冒泡排序 for (j = 0; j < groups.size() - i - 1; j++) { if (groups[j].size() < groups[j + 1].size()) { swap(groups[j], groups[j + 1]); } } } - output_dat.resize(input_dat.size()); - for (i = 0; i < groups.size(); i++) { - for (j = 0; j < groups[i].size(); j++) { + output_dat.resize(input_dat.size()); // 声明返回数组的长度 + for (i = 0; i < groups.size(); i++) { // 遍历所有群 + for (j = 0; j < groups[i].size(); j++) { // 遍历群中的所有元素 (*groups[i][j]).group_num = i; (*groups[i][j]).group_index = j; - output_dat[(*groups[i][j]).id] = groups[i][j]; + output_dat[(*groups[i][j]).id] = groups[i][j]; // 记录元素到返回数组 } } return output_dat; } -void HRD_statistic::Output_All_Case(string File_name) { +void HRD_statistic::Output_All_Case(string File_name) { // 输出全部编码 unsigned int i; HRD_cal cal; ofstream output; output.open(File_name); - for (i = 0; i < All_Case.size(); i++) { + for (i = 0; i < All_Case.size(); i++) { // 遍历全部布局 output << cal.Change_str((*All_Case[i]).code); - if (i != All_Case.size() - 1) { + if (i != All_Case.size() - 1) { // 如果不是最后一组就输出回车 output << endl; } - if (i % 100000 == 0) { + if (i % 100000 == 0) { // 显示输出进度 cout << i << "/" << All_Case.size() << endl; } } output.close(); } -void HRD_statistic::Output_main_table(string File_name) { +void HRD_statistic::Output_main_table(string File_name) { // 输出全部编码及分类 unsigned int i; HRD_cal cal; ofstream output; output.open(File_name); - for (i = 0; i < All_Case.size(); i++) { + for (i = 0; i < All_Case.size(); i++) { // 遍历全部布局 output << (*All_Case[i]).id << ","; output << cal.Change_str((*All_Case[i]).code) << ","; output << int((*All_Case[i]).jiang_num) << ","; @@ -159,32 +199,32 @@ void HRD_statistic::Output_main_table(string File_name) { output << int((*All_Case[i]).style_num) << ","; output << (*All_Case[i]).group_num << ","; output << (*All_Case[i]).group_index; - if (i != All_Case.size() - 1) { + if (i != All_Case.size() - 1) { // 如果不是最后一组就输出回车 output << endl; } - if (i % 100000 == 0) { + if (i % 100000 == 0) { // 显示输出进度 cout << i << "/" << All_Case.size() << endl; } } output.close(); } -void HRD_statistic::Find_All_Case() { +void HRD_statistic::Find_All_Case() { // 找到所有编码 unsigned long long i, n, Code; unsigned int num = 0; HRD_cal cal; All_Case.clear(); - for (n = 0; n < 0xF; n++) { - if (n % 4 == 3) {continue;} - for (i = 0; i <= 0xFFFFFFFF; i++) { - Code = (n << 32) | i; - if (cal.Check_Code(Code) == true) { + for (n = 0; n < 0xF; n++) { // n为2 * 2块位置 亦编码左起第1位 + if (n % 4 == 3) {continue;} // 排除2 * 2块不可能在的位置 + for (i = 0; i <= 0xFFFFFFFF; i++) { // 遍历编码低32位 + Code = (n << 32) | i; // 生成Code + if (cal.Check_Code(Code) == true) { // 检查编码是否正确 Case *temp = new Case; (*temp).code = Code; (*temp).id = num; - All_Case.push_back(temp); + All_Case.push_back(temp); // 记录搜到的编码 num++; } - if (i % 0x1000000 == 0) { + if (i % 0x1000000 == 0) { // 输出搜索进度 cout << n << ": " << (i / 0x1000000) + 1 << "/256"; cout << " -> " << num << endl; } diff --git a/src/engine/HRD_statistic.h b/src/engine/HRD_statistic.h index 4bbf609..da4daa4 100644 --- a/src/engine/HRD_statistic.h +++ b/src/engine/HRD_statistic.h @@ -8,7 +8,7 @@ using namespace std; class HRD_statistic { public: void Find_All_Case(string File_name); - void Make_main_table(string File_name); + void All_Statistic(); private: struct Case { @@ -26,8 +26,9 @@ class HRD_statistic { unsigned int group_num; unsigned int group_index; }; - vector All_Case; + vector All_Case; // ¼вֵϢ + void Get_seed(); void Find_All_Case(); void Sort_All_Case(); vector Split_Group(vector dat); diff --git a/src/engine/main.cpp b/src/engine/main.cpp index f1f9efd..73efbf8 100644 --- a/src/engine/main.cpp +++ b/src/engine/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -21,11 +22,46 @@ bool code_check(string str) { for (unsigned int i = 0; i < str.length(); i++) { code_str[i] = str[i]; } - code_str[10] = '\0'; + code_str[9] = '\0'; checked_code = cal.Change_int(code_str); return cal.Check_Code(checked_code); } +void show_case(string str) { + unsigned long long code; + if (code_check(str) == false) { + cout << "code error" << endl; + cout << endl; + return; + } + code = checked_code; + HRD_analy analy; + char output_char[3] = "&%"; + cout << endl; + cout << "Code: " << analy.Change_str(code) << endl; + analy.Output_Graph(code, 3, 1, output_char); + cout << endl; +} + +void show_case(string str, string width) { + unsigned long long code; + if (code_check(str) == false) { + cout << "code error" << endl; + cout << endl; + return; + } + code = checked_code; + HRD_analy analy; + int square_width; + char output_char[3] = "&%"; + istringstream is(width); // ַstringתΪint + is >> square_width; + cout << endl; + cout << "Code: " << analy.Change_str(code) << endl; + analy.Output_Graph(code, square_width, 1, output_char); + cout << endl; +} + void cal_case(string str) { unsigned long long code; vector dat; @@ -68,11 +104,15 @@ void cal_case(string str, string File_name) { } File_Output.open(File_name); cout << "Data save at " << File_name << endl; - File_Output << dat.size() - 1 << endl; - for (unsigned int i = 0; i < dat.size(); i++) { - File_Output << cal.Change_str(dat[i]); - if (i + 1 != dat.size()) { - File_Output << endl; + if (dat.size() == 0) { + File_Output << "-1"; + } else { + File_Output << dat.size() - 1 << endl; + for (unsigned int i = 0; i < dat.size(); i++) { + File_Output << cal.Change_str(dat[i]); + if (i + 1 != dat.size()) { + File_Output << endl; + } } } cout << endl; @@ -135,17 +175,37 @@ void cal_target(string str_1, string str_2, string File_name) { } File_Output.open(File_name); cout << "Data save at " << File_name << endl; - File_Output << dat.size() - 1 << endl; - for (unsigned int i = 0; i < dat.size(); i++) { - File_Output << cal.Change_str(dat[i]); - if (i + 1 != dat.size()) { - File_Output << endl; + if (dat.size() == 0) { + File_Output << "-1"; + } else { + File_Output << dat.size() - 1 << endl; + for (unsigned int i = 0; i < dat.size(); i++) { + File_Output << cal.Change_str(dat[i]); + if (i + 1 != dat.size()) { + File_Output << endl; + } } } cout << endl; File_Output.close(); } +void cal_group(string str) { + unsigned long long code; + vector dat; + if (code_check(str) == false) { + cout << "code error" << endl; + cout << endl; + return; + } + HRD_cal cal; + code = checked_code; + cout << "Start code: " << cal.Change_str(code) << endl; + dat = cal.Calculate_All(code); + cout << "Group size: " << dat.size() << endl; + cout << endl; +} + void cal_group(string str, string File_name) { unsigned long long code; vector dat; @@ -172,6 +232,23 @@ void cal_group(string str, string File_name) { File_Output.close(); } +void analy_case(string str, bool quiet) { + unsigned long long code; + vector dat; + if (code_check(str) == false) { + cout << "code error" << endl; + cout << endl; + return; + } + HRD_analy analy; + code = checked_code; + cout << "Start code: " << analy.Change_str(code) << endl; + analy.quiet = quiet; + analy.Analyse_Case(code); + cout << endl; + analy.Free_Data(); +} + void analy_case(string str, string File_name, bool quiet) { unsigned long long code; vector dat; @@ -193,6 +270,7 @@ void analy_case(string str, string File_name, bool quiet) { cout << "done" << endl; } cout << endl; + analy.Free_Data(); } void analy_group(string str, string File_name_1, string File_name_2, bool is_all) { @@ -211,13 +289,23 @@ void analy_group(string str, string File_name_1, string File_name_2, bool is_all cout << endl; } -void find_all(string File_name) { +void analy_multi_group(string str, string File_name_1, string File_name_2, bool is_all) { + HRD_group group; + if (group.Multi_Analyse(str, File_name_1, File_name_2, is_all) == false) { + cout << endl; + return; + } + cout << "Data save at " << File_name_1 << " and " << File_name_2 << endl; + cout << endl; +} + +void find_all() { HRD_statistic statistic; cout << "Warning: It will consume nearly 2GB of memory, please make sure there is enough memory!" << endl; cout << "Press ENTER to start..."; cin.get(); - statistic.Find_All_Case(File_name); - cout << "Data save at " << File_name << endl; + statistic.All_Statistic(); + cout << "Data save at All_Case.txt, main.csv, *-*-*.txt" << endl; cout << endl; } @@ -226,7 +314,7 @@ void find_all_code(string File_name) { cout << "Warning: It will consume nearly 2GB of memory, please make sure there is enough memory!" << endl; cout << "Press ENTER to start..."; cin.get(); - statistic.Make_main_table(File_name); + statistic.Find_All_Case(File_name); cout << "Data save at " << File_name << endl; cout << endl; } @@ -235,75 +323,102 @@ void show_help() { cout << "(version: v0.0)" << endl; cout << "Usage of HRD_engine:" << endl; cout << endl; + cout << " --show [square_width]" << endl; + cout << " Purpose: Visualize the " << endl; + cout << " exp: ./engine --show 1A9BF0C00" << endl; + cout << " ./engine --show 1A9BF0C00 4" << endl; + cout << endl; cout << " --cal [file_name]" << endl; - cout << " [file_name]: for output the result" << endl; - cout << " Purpose: find the min step solution from " << endl; + cout << " Purpose: Find the minimum step solution of " << endl; cout << " exp: ./engine --cal 1A9BF0C00" << endl; cout << " ./engine --cal 1A9BF0C00 demo.txt" << endl; cout << endl; cout << " --cal-target [file_name]" << endl; - cout << " [file_name]: for output the result" << endl; - cout << " Purpose: find the min step path from to " << endl; + cout << " Purpose: Find the shortest path from to " << endl; cout << " exp: ./engine --cal-target 4FEA13400 43EA73400" << endl; cout << " ./engine --cal-target 4FEA13400 43EA73400 demo.txt" << endl; cout << endl; - cout << " --group " << endl; - cout << " : for output the result" << endl; - cout << " Purpose: find all cases in the group where loacted" << endl; - cout << " exp: ./engine --group 4FEA13400 demo.txt" << endl; + cout << " --group [file_name]" << endl; + cout << " Purpose: Find all elements of the group where located" << endl; + cout << " exp: ./engine --group 4FEA13400" << endl; + cout << " ./engine --group 4FEA13400 demo.txt" << endl; cout << endl; - cout << " --analy " << endl; - cout << " : for output the result" << endl; - cout << " Purpose: analyse the case with " << endl; - cout << " exp: ./engine --analy 1A9BF0C00 demo.txt" << endl; + cout << " --analy [file_name]" << endl; + cout << " Purpose: Detailed analysis of the " << endl; + cout << " exp: ./engine --analy 1A9BF0C00" << endl; + cout << " ./engine --analy 1A9BF0C00 demo.txt" << endl; cout << endl; cout << " --analy-quiet " << endl; - cout << " Purpose: the same function with analy but don't show the process" << endl; + cout << " Purpose: The same function as --analy, but doesn't show the specific process" << endl; cout << " exp: ./engine --analy-quiet 1A9BF0C00 demo.txt" << endl; cout << endl; - cout << " --analy-group " << endl; - cout << " : for output the result of \"farthest\"" << endl; - cout << " : for output the result of \"solution\"" << endl; - cout << " Purpose: analyse all cases in the group where loacted" << endl; - cout << " exp: ./engine --group 1A9BF0C00 farthest.csv solution.csv" << endl; + cout << " --analy-group " << endl; + cout << " : As the output file of \"farthest\"" << endl; + cout << " : As the output file of \"solution\"" << endl; + cout << " Purpose: Analyze the whole group where located" << endl; + cout << " exp: ./engine --analy-group 1A9BF0C00 farthest.csv solution.csv" << endl; + cout << endl; + cout << " --analy-group-integral " << endl; + cout << " Purpose: The same function as --analy-group, but all solution case will be output" << endl; + cout << " exp: ./engine --analy-group-integral 1A9BF0C00 farthest.csv solution.csv" << endl; cout << endl; - cout << " --analy-group-all " << endl; - cout << " Purpose: the same function with analy-group but more output all solution cases" << endl; - cout << " exp: ./engine --group-all 1A9BF0C00 farthest.csv solution.csv" << endl; + cout << " --analy-multi-group " << endl; + cout << " : As the input file of seeds" << endl; + cout << " : As the output file of \"farthest\"" << endl; + cout << " : As the output file of \"solution\"" << endl; + cout << " Purpose: Analyze the whole group where each seed located" << endl; + cout << " exp: ./engine --analy-multi-group 5-4-0.txt farthest.csv solution.csv" << endl; cout << endl; - cout << " --all " << endl; - cout << " Purpose: find all cases from klotski game with detail" << endl; - cout << " exp: ./engine --all main.csv" << endl; + cout << " --analy-multi-group-integral " << endl; + cout << " Purpose: The same function as --analy-multi-group, but all solution case will be output" << endl; + cout << " exp: ./engine --analy-multi-group-integral 5-4-0.txt farthest.csv solution.csv" << endl; + cout << endl; + cout << " --all" << endl; + cout << " Purpose: Find all the cases of klotski with detail" << endl; + cout << " exp: ./engine --all" << endl; cout << endl; cout << " --all-code " << endl; - cout << " Purpose: find all cases from klotski game only with code" << endl; + cout << " Purpose: Find all the code of klotski" << endl; cout << " exp: ./engine --all-code All_Case.txt" << endl; cout << endl; cout << " --help" << endl; - cout << " Purpose: show the usage" << endl; + cout << " Purpose: Display instructions for use" << endl; cout << " exp: ./engine --help" << endl; cout << endl; + cout << "More details: https://github.com/dnomd343/HRD_Database" << endl; + cout << endl; +} + +void parameter_err() { + cout << "parameter error" << endl; + cout << endl; } int main(int argc, char* argv[]) { cout << "Klotski engine by Dnomd343" << endl; if (argc <= 1) { cout << "no parameter" << endl; - cout << "You can try to use \"--help\" for more information" << endl; + cout << "You can try \"--help\" for more information" << endl; cout << endl; return 0; } string parameter; parameter = argv[1]; - if (parameter == "--cal") { + if (parameter == "--show") { + if (argc == 3) { + show_case(argv[2]); + } else if (argc == 4) { + show_case(argv[2], argv[3]); + } else { + parameter_err(); + } + } else if (parameter == "--cal") { if (argc == 3) { cal_case(argv[2]); } else if (argc == 4) { cal_case(argv[2], argv[3]); } else { - cout << "parameter error" << endl; - cout << endl; - return 0; + parameter_err(); } } else if (parameter == "--cal-target") { if (argc == 4) { @@ -311,71 +426,71 @@ int main(int argc, char* argv[]) { } else if (argc == 5) { cal_target(argv[2], argv[3], argv[4]); } else { - cout << "parameter error" << endl; - cout << endl; - return 0; + parameter_err(); } } else if (parameter == "--group") { - if (argc == 4) { + if (argc == 3) { + cal_group(argv[2]); + } else if (argc == 4) { cal_group(argv[2], argv[3]); } else { - cout << "parameter error" << endl; - cout << endl; - return 0; + parameter_err(); } } else if (parameter == "--analy") { - if (argc == 4) { + if (argc == 3) { + analy_case(argv[2], false); + } else if (argc == 4) { analy_case(argv[2], argv[3], false); } else { - cout << "parameter error" << endl; - cout << endl; - return 0; + parameter_err(); } } else if (parameter == "--analy-quiet") { if (argc == 4) { analy_case(argv[2], argv[3], true); } else { - cout << "parameter error" << endl; - cout << endl; - return 0; + parameter_err(); } } else if (parameter == "--analy-group") { if (argc == 5) { analy_group(argv[2], argv[3], argv[4], false); } else { - cout << "parameter error" << endl; - cout << endl; - return 0; + parameter_err(); } - } else if (parameter == "--analy-group-all") { + } else if (parameter == "--analy-group-integral") { if (argc == 5) { analy_group(argv[2], argv[3], argv[4], true); } else { - cout << "parameter error" << endl; - cout << endl; - return 0; + parameter_err(); + } + } else if (parameter == "--analy-multi-group") { + if (argc == 5) { + analy_multi_group(argv[2], argv[3], argv[4], false); + } else { + parameter_err(); + } + } else if (parameter == "--analy-multi-group-integral") { + if (argc == 5) { + analy_multi_group(argv[2], argv[3], argv[4], true); + } else { + parameter_err(); } } else if (parameter == "--all") { - if (argc == 3) { - find_all(argv[2]); + if (argc == 2) { + find_all(); } else { - cout << "parameter error" << endl; - cout << endl; - return 0; + parameter_err(); } } else if (parameter == "--all-code") { if (argc == 3) { find_all_code(argv[2]); } else { - cout << "parameter error" << endl; - cout << endl; - return 0; + parameter_err(); } } else if (parameter == "--help") { show_help(); } else { cout << "unknow parameter" << endl; - cout << "You can try to use \"--help\" for more information" << endl; + cout << "You can try \"--help\" for more information" << endl; cout << endl; } return 0;