diff --git a/src/engine/HRD_analy.cpp b/src/engine/HRD_analy.cpp index f09bf5e..f58851e 100644 --- a/src/engine/HRD_analy.cpp +++ b/src/engine/HRD_analy.cpp @@ -66,22 +66,16 @@ void HRD_analy::Output_Graph(unsigned long long Code, unsigned int square_width, } width = temp.size(); height = temp[0].size(); - for (x = 0; x < width + square_gap * 2 + 2; x++) { - cout << str; - } + 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 << " "; - } + 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 < square_gap; x++) {cout << " ";} for (x = 0; x < width; x++) { if (temp[x][y]) { cout << str; @@ -89,28 +83,21 @@ void HRD_analy::Output_Graph(unsigned long long Code, unsigned int square_width, cout << " "; } } - for (x = 0; x < square_gap; x++) { - 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 << " "; - } + 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; - } + 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; - vector case_list; if (!quiet) { cout << "Output into: " << File_name << "..."; } @@ -145,18 +132,19 @@ void HRD_analy::Output_Detail(string File_name) { // 输出分析结果到文件 output << "[Layer]" << endl; for (i = 0; i < Layer.size(); i++) { for (j = 0; j < Layer[i].size(); j++) { - output << "(" << i << "," << j << ") -> "; + output << "(" << i << "," << j << ") = "; output << Change_str((*Layer[i][j]).code) << endl; } } + vector *case_list; output << "[Next]" << endl; for (i = 0; i < Layer.size(); i++) { for (j = 0; j < Layer[i].size(); j++) { - case_list = (*(*Layer[i][j]).adjacent).next_case; + case_list = Layer[i][j]->next_case; output << "(" << i << "," << j << ") ->"; - for (k = 0; k < case_list.size(); k++) { - output << " (" << (*case_list[k]).layer_num; - output << "," << (*case_list[k]).layer_index << ")"; + for (k = 0; k < case_list->size(); k++) { + output << " (" << (*case_list->at(k)).layer_num; + output << "," << (*case_list->at(k)).layer_index << ")"; } output << endl; } @@ -164,19 +152,17 @@ void HRD_analy::Output_Detail(string File_name) { // 输出分析结果到文件 output << "[Source]" << endl; for (i = 0; i < Layer.size(); i++) { for (j = 0; j < Layer[i].size(); j++) { - case_list = (*(*Layer[i][j]).adjacent).source_case; + case_list = Layer[i][j]->source_case; output << "(" << i << "," << j << ") <-"; - for (k = 0; k < case_list.size(); k++) { - output << " (" << (*case_list[k]).layer_num; - output << "," << (*case_list[k]).layer_index << ")"; + for (k = 0; k < case_list->size(); k++) { + output << " (" << (*case_list->at(k)).layer_num; + output << "," << (*case_list->at(k)).layer_index << ")"; } output << endl; } } output.close(); - if (!quiet) { - cout << "done" << endl; - } + if (!quiet) {cout << "done" << endl;} } void HRD_analy::Analyse_Case(unsigned long long code) { // 分析输入编码的各种参数 @@ -208,7 +194,7 @@ void HRD_analy::Analyse_Case(unsigned long long code) { // 分析输入编码的 // 获取最少步解 for (i = 0; i < Layer.size(); i++) { for (j = 0; j < Layer[i].size(); j++) { - if (((*Layer[i][j]).code >> 32) == 0xD) { // 2 * 2块在出口位置 + if ((Layer[i][j]->code >> 32) == 0xD) { // 2 * 2块在出口位置 min_solution_step = i; // 找到最少步数 j = Layer[i].size(); // 跳出两层循环 i = Layer.size(); @@ -217,7 +203,7 @@ void HRD_analy::Analyse_Case(unsigned long long code) { // 分析输入编码的 } if (min_solution_step == -1) {return;} // 无解则退出 for (i = 0; i < Layer[min_solution_step].size(); i++) { // 遍历最少步所在层 - if (((*Layer[min_solution_step][i]).code >> 32) == 0xD) { // 判断是否为解 + if ((Layer[min_solution_step][i]->code >> 32) == 0xD) { // 判断是否为解 min_solution_case.push_back((*Layer[min_solution_step][i]).code); // 加入最少步解序列中 solution_flag[min_solution_step][i] = true; // 标识 } @@ -225,7 +211,7 @@ void HRD_analy::Analyse_Case(unsigned long long code) { // 分析输入编码的 min_solution_num = min_solution_case.size(); sort(min_solution_case.begin(), min_solution_case.end()); // 得到的结果进行排序 // 获取全部解 - vector case_list; + vector *case_list; solution_case = min_solution_case; // 同步最少步解到所有解序列中 for (i = 0; i < solution_case.size(); i++) { // 初始化已知部分的solution_step solution_step.push_back(min_solution_step); @@ -233,17 +219,17 @@ void HRD_analy::Analyse_Case(unsigned long long code) { // 分析输入编码的 for (i = 0; i < Layer.size() - 1; i++) { // 遍历除最后一层外的所有层 for (j = 0; j < Layer[i].size(); j++) { // 遍历层内元素 if (solution_flag[i][j]) { // 若该元素被标识 - case_list = (*(*Layer[i][j]).adjacent).next_case; - for (k = 0; k < case_list.size(); k++) { // 遍历其下一步 - solution_flag[i + 1][(*case_list[k]).layer_index] = true; // 标识 + case_list = Layer[i][j]->next_case; + for (k = 0; k < case_list->size(); k++) { // 遍历其下一步 + solution_flag[i + 1][(*case_list->at(k)).layer_index] = true; // 标识 } } } temp.clear(); for (j = 0; j < Layer[i + 1].size(); j++) { // 遍历下一层内元素 if (!solution_flag[i + 1][j]) { // 得到未被标识的元素 - if (((*Layer[i + 1][j]).code >> 32) == 0xD) { // 若为解的布局 - temp.push_back((*Layer[i + 1][j]).code); // 先加入到temp中方便排序 + if ((Layer[i + 1][j]->code >> 32) == 0xD) { // 若为解的布局 + temp.push_back(Layer[i + 1][j]->code); // 先加入到temp中方便排序 solution_step.push_back(i + 1); solution_flag[i + 1][j] = true; // 标识 } @@ -255,6 +241,7 @@ void HRD_analy::Analyse_Case(unsigned long long code) { // 分析输入编码的 } } solution_num = solution_case.size(); + if (quiet) {return;} // 若quiet为true则不输出 cout << "---------------------------" << endl; cout << "farthest_step = " << farthest_step << endl; @@ -283,7 +270,8 @@ void HRD_analy::Free_Data() { // 释放上一次的计算结果 unsigned int i, j; for (i = 0; i < Layer.size(); i++) { // 释放Layer中指向的全部节点 for (j = 0; j < Layer[i].size(); j++) { - delete (*Layer[i][j]).adjacent; + delete Layer[i][j]->source_case; + delete Layer[i][j]->next_case; delete Layer[i][j]; } } @@ -294,18 +282,20 @@ void HRD_analy::Free_Data() { // 释放上一次的计算结果 } void HRD_analy::Calculate(unsigned long long code) { - Free_Data(); // 初始化数据结构 + Free_Data(); // 初始化 Case_cal *start = new Case_cal; - (*start).adjacent = new Case_near; + start->source_case = new vector ; + start->next_case = new vector ; if (!Parse_Code(*start, code)) { // 若输入编码错误 退出 - delete (*start).adjacent; + delete start->source_case; + delete start->next_case; delete start; return; } Layer.resize(1); // 创建第0层 Layer[0].push_back(start); // 加入根节点 - (*start).layer_num = (*start).layer_index = 0; // 初始化根节点编号 - Layer_hash[0xffff & ((*start).code >> 16)].push_back(start); // 根节点加入哈希表 + start->layer_num = start->layer_index = 0; // 初始化根节点编号 + Layer_hash[0xffff & (start->code >> 16)].push_back(start); // 根节点加入哈希表 now_move_num = now_move_index = 0; // 从根节点开始运算 while (1 == 1) { // 创建死循环 if (now_move_index == 0) { // 若在计算层的第一个元素 @@ -332,17 +322,17 @@ void HRD_analy::Calculate(unsigned long long code) { void HRD_analy::Add_Case(Case_cal *dat) { // 将计算得到的节点加入层级中 unsigned int i, x, y; Case_cal *repeat_case; - int hash_index = 0xffff & ((*dat).code >> 16); // 取得哈希索引 + int hash_index = 0xffff & (dat->code >> 16); // 取得哈希索引 for (i = 0; i < Layer_hash[hash_index].size(); i++) { // 遍历索引内容 repeat_case = Layer_hash[hash_index][i]; - if ((*repeat_case).code == (*dat).code) { // 发现重复 - if ((*repeat_case).layer_num == now_move_num + 1) { // 若发现的目标比现在多一层 - (*(*repeat_case).adjacent).source_case.push_back(now_move_case); // 记录父节点信息 - (*(*now_move_case).adjacent).next_case.push_back(repeat_case); // 记录子节点信息 + if (repeat_case->code == dat->code) { // 发现重复 + if (repeat_case->layer_num == now_move_num + 1) { // 若发现的目标比现在多一层 + (*repeat_case->source_case).push_back(now_move_case); // 记录父节点信息 + (*now_move_case->next_case).push_back(repeat_case); // 记录子节点信息 for (x = 0; x < 4; x++) { // 遍历freeze表 for (y = 0; y < 5; y++) { - if ((*dat).freeze[x][y]) { // 将输入表合并到原先的表上 - (*repeat_case).freeze[x][y] = true; + if (dat->freeze[x][y]) { // 将输入表合并到原先的表上 + repeat_case->freeze[x][y] = true; } } } @@ -351,11 +341,12 @@ void HRD_analy::Add_Case(Case_cal *dat) { // 将计算得到的节点加入层 return; // 退出 } } - (*dat).adjacent = new Case_near; // 初始化节点的相邻布局结构 - (*(*dat).adjacent).source_case.push_back(now_move_case); // 记录父节点信息 - (*(*now_move_case).adjacent).next_case.push_back(dat); // 记录子节点信息 - (*dat).layer_num = now_move_num + 1; // 记录节点的层编号 - (*dat).layer_index = Layer[now_move_num + 1].size(); // 记录节点在层中的编号 + dat->source_case = new vector ; + dat->next_case = new vector ; + (*dat->source_case).push_back(now_move_case); // 记录父节点信息 + (*now_move_case->next_case).push_back(dat); // 记录子节点信息 + dat->layer_num = now_move_num + 1; // 记录节点的层编号 + dat->layer_index = Layer[now_move_num + 1].size(); // 记录节点在层中的编号 Layer[now_move_num + 1].push_back(dat); // 加入层级结构中 Layer_hash[hash_index].push_back(dat); // 加入哈希索引 } @@ -522,25 +513,41 @@ void HRD_analy::Build_Case(Case_cal &dat, int &num, int x, int y, bool addr[4][5 *dat_mod = dat; switch ((*dat_mod).type[num]) { // 注入移动后的信息 case 0: // 2 * 2 - (*dat_mod).status[x][y] = (*dat_mod).status[x][y + 1] - = (*dat_mod).status[x + 1][y] = (*dat_mod).status[x + 1][y + 1] = num; + dat_mod->status[x][y] = dat_mod->status[x][y + 1] + = dat_mod->status[x + 1][y] = dat_mod->status[x + 1][y + 1] = num; break; case 1: // 2 * 1 - (*dat_mod).status[x][y] = (*dat_mod).status[x + 1][y] = num; + dat_mod->status[x][y] = dat_mod->status[x + 1][y] = num; break; case 2: // 1 * 2 - (*dat_mod).status[x][y] = (*dat_mod).status[x][y + 1] = num; + dat_mod->status[x][y] = dat_mod->status[x][y + 1] = num; break; case 3: // 1 * 1 - (*dat_mod).status[x][y] = num; + dat_mod->status[x][y] = num; break; } Get_Code(*dat_mod); // 更新移动后的编码 Add_Case(dat_mod); // 发送给Add_Case Find_Sub_Case(dat, num, x, y, addr); // 递归搜索 } +bool HRD_analy::Is_Mirror(unsigned long long code) { + Case_cal dat; + Parse_Code(dat, code); + for (int j = 0; j < 5; j++) { + for (int i = 0; i < 2; i++) { + if (dat.status[i][j] == 0xFF) { // undefined + return false; // 编码有误 + } else if (dat.status[i][j] == 0xFE) { // space + if (dat.status[3 - i][j] != 0xFE) {return false;} // 不对称 + } else { + if (dat.type[dat.status[i][j]] != dat.type[dat.status[3 - i][j]]) {return false;} // 不对称 + } + } + } + return true; +} -bool HRD_analy::Check_Code(unsigned long long code) { +bool HRD_analy::Check_Code(unsigned long long code) { // 判断布局是否左右对称 Case_cal dat; return Parse_Code(dat, code); } diff --git a/src/engine/HRD_analy.h b/src/engine/HRD_analy.h index 8bb923a..6598b23 100644 --- a/src/engine/HRD_analy.h +++ b/src/engine/HRD_analy.h @@ -7,7 +7,6 @@ using namespace std; class HRD_analy { public: - struct Case_near; struct Case_cal { bool freeze[4][5]; // true -> no move ; false -> can move unsigned char status[4][5]; // 0xFF -> undefined ; 0xFE -> space @@ -15,11 +14,8 @@ class HRD_analy { unsigned long long code; unsigned int layer_num; unsigned int layer_index; - Case_near *adjacent; - }; - struct Case_near { - vector source_case; - vector next_case; + vector *source_case; + vector *next_case; }; vector > Layer; // 储存全部层数据的节点 Case_cal Parse_dat; @@ -39,6 +35,7 @@ class HRD_analy { string Change_str(unsigned long long dat); bool Check_Code(unsigned long long code); bool Parse_Code(unsigned long long Code); + bool Is_Mirror(unsigned long long code); void Analyse_Case(unsigned long long code); void Output_Detail(string File_name); void Free_Data(); diff --git a/src/engine/HRD_cal.cpp b/src/engine/HRD_cal.cpp index 0cce608..d37176c 100644 --- a/src/engine/HRD_cal.cpp +++ b/src/engine/HRD_cal.cpp @@ -13,7 +13,7 @@ vector HRD_cal::Calculate_All(unsigned long long Code) { // } cal(Code); // 进行广搜 for (i = 0; i < List.size(); i++) { - data.push_back((*List[i]).code); // 储存计算结果 + data.push_back(List[i]->code); // 储存计算结果 } init_data(); // 防止内存泄漏 return data; @@ -63,12 +63,12 @@ vector HRD_cal::Calculate(unsigned long long Code) { // 寻 vector HRD_cal::Get_Path(unsigned int result_num) { // 找到开始到目标的最短路径 vector Path; Path.clear(); - Path.push_back((*List[result_num]).code); // 加入目标布局 + Path.push_back(List[result_num]->code); // 加入目标布局 while (List_source[result_num] != 0) { // 找到路径主体 result_num = List_source[result_num]; - Path.push_back((*List[result_num]).code); // 加入记录 + Path.push_back(List[result_num]->code); // 加入记录 } - Path.push_back((*List[0]).code); // 加入开始布局 + Path.push_back(List[0]->code); // 加入开始布局 reverse(Path.begin(), Path.end()); // 路径倒置 init_data(); return Path; @@ -102,7 +102,7 @@ void HRD_cal::cal(unsigned long long Code) { // 广搜寻找目标 } List.push_back(start); // 加入根节点 List_source.push_back(0); - List_hash[0xffff & ((*start).code >> 16)].push_back(start); + List_hash[0xffff & (start->code >> 16)].push_back(start); while (now_move != List.size()) { // 找到所有元素后退出 Find_Next_Case(*List[now_move]); if (flag) {break;} // 若找到则退出 @@ -112,14 +112,14 @@ void HRD_cal::cal(unsigned long long Code) { // 广搜寻找目标 void HRD_cal::Add_Case(Case_cal *dat) { // 将找到的布局加入队列中 unsigned int i, x, y; - int hash_index = 0xffff & ((*dat).code >> 16); // 取得哈希索引 + int hash_index = 0xffff & (dat->code >> 16); // 取得哈希索引 for (i = 0; i < List_hash[hash_index].size(); i++) { // 遍历索引内容 - if ((*List_hash[hash_index][i]).code == (*dat).code) { // 发现重复 + if (List_hash[hash_index][i]->code == dat->code) { // 发现重复 // 通过freeze表合并来屏蔽不必要的移动 for (x = 0; x < 4; x++) { // 遍历freeze表 for (y = 0; y < 5; y++) { - if ((*dat).freeze[x][y]) { // 将输入表合并到原先的表上 - (*List_hash[hash_index][i]).freeze[x][y] = true; + if (dat->freeze[x][y]) { // 将输入表合并到原先的表上 + List_hash[hash_index][i]->freeze[x][y] = true; } } } @@ -131,12 +131,12 @@ void HRD_cal::Add_Case(Case_cal *dat) { // 将找到的布局加入队列中 List_source.push_back(now_move); // 记录溯源信息 List_hash[hash_index].push_back(dat); // 加入哈希索引 if (mode == 1) { // 寻解模式 - if ((0xF & ((*dat).code >> 32)) == 0xD) { // 2 * 2块在出口位置 + if ((0xF & (dat->code >> 32)) == 0xD) { // 2 * 2块在出口位置 flag = true; // 标志已找到目标 result = List.size() - 1; // 记录找到的目标位置 } } else if (mode == 2) { // 查找目标模式 - if ((*dat).code == target_code) { // 搜索到目标 + if (dat->code == target_code) { // 搜索到目标 flag = true; // 标志已找到目标 result = List.size() - 1; // 记录找到的目标位置 } @@ -306,17 +306,17 @@ void HRD_cal::Build_Case(Case_cal &dat, int &num, int x, int y, bool addr[4][5]) *dat_mod = dat; switch ((*dat_mod).type[num]) { // 注入移动后的信息 case 0: // 2 * 2 - (*dat_mod).status[x][y] = (*dat_mod).status[x][y + 1] - = (*dat_mod).status[x + 1][y] = (*dat_mod).status[x + 1][y + 1] = num; + dat_mod->status[x][y] = dat_mod->status[x][y + 1] + = dat_mod->status[x + 1][y] = dat_mod->status[x + 1][y + 1] = num; break; case 1: // 2 * 1 - (*dat_mod).status[x][y] = (*dat_mod).status[x + 1][y] = num; + dat_mod->status[x][y] = dat_mod->status[x + 1][y] = num; break; case 2: // 1 * 2 - (*dat_mod).status[x][y] = (*dat_mod).status[x][y + 1] = num; + dat_mod->status[x][y] = dat_mod->status[x][y + 1] = num; break; case 3: // 1 * 1 - (*dat_mod).status[x][y] = num; + dat_mod->status[x][y] = num; break; } Get_Code(*dat_mod); // 更新移动后的编码 diff --git a/src/engine/HRD_group.cpp b/src/engine/HRD_group.cpp index 394bd84..9eae8dd 100644 --- a/src/engine/HRD_group.cpp +++ b/src/engine/HRD_group.cpp @@ -61,24 +61,24 @@ void HRD_group::Analyse_Group(vector dat) { // 传入整个 vector List_hash[0x10000]; // 哈希索引 for (i = 0; i < dat.size(); i++) { // 将数据注入到List中 Case *temp = new Case; - (*temp).Code = dat[i]; + temp->Code = dat[i]; List.push_back(temp); } for (i = 0; i < List.size(); i++) { // 构建哈希索引表 - hash_index = 0xffff & ((*List[i]).Code >> 16); + hash_index = 0xffff & (List[i]->Code >> 16); List_hash[hash_index].push_back(List[i]); } for (i = 0; i < List.size(); i++) { // 计算全部2 * 2块的位置 - (*List[i]).addr_2x2 = (*List[i]).Code >> 32; + List[i]->addr_2x2 = List[i]->Code >> 32; } vector next_code; for (i = 0; i < List.size(); i++) { // 构建关系网 - next_code = Find_Next_Case((*List[i]).Code); // 找到全部子布局 + next_code = Find_Next_Case(List[i]->Code); // 找到全部子布局 for (j = 0; j < next_code.size(); j++) { // 遍历子布局 hash_index = 0xffff & (next_code[j] >> 16); // 取得哈希索引 for (k = 0; List_hash[hash_index].size(); k++) { // 搜索该索引 - if ((*List_hash[hash_index][k]).Code == next_code[j]) { // 找到目标 - (*List[i]).Next.push_back(List_hash[hash_index][k]); // 链接目标位置 + if (List_hash[hash_index][k]->Code == next_code[j]) { // 找到目标 + List[i]->Next.push_back(List_hash[hash_index][k]); // 链接目标位置 break; // 退出循环 } } @@ -87,8 +87,8 @@ void HRD_group::Analyse_Group(vector dat) { // 传入整个 Case_detail *result; for(i = 0; i < List.size(); i++) { // 遍历整个队列 for (k = 0; k < List.size(); k++) { // 初始化 - (*List[k]).Layer_num = -1; - (*List[k]).Flag = false; + List[k]->Layer_num = -1; + List[k]->Flag = false; } result = Analyse_Case(List[i]); // 计算对应布局数据并储存到result中 Output_detail(result); @@ -105,36 +105,36 @@ void HRD_group::Analyse_Group(vector dat) { // 传入整个 void HRD_group::Output_detail(Case_detail *dat) { unsigned int i; // farthest - output_farthest << Change_str((*dat).code) << ","; - output_farthest << (*dat).farthest_step << ","; - output_farthest << (*dat).farthest_num << ","; - for (i = 0; i < (*dat).farthest_case.size(); i++) { - output_farthest << Change_str((*dat).farthest_case[i]); - if (i + 1 != (*dat).farthest_case.size()) { + output_farthest << Change_str(dat->code) << ","; + output_farthest << dat->farthest_step << ","; + output_farthest << dat->farthest_num << ","; + for (i = 0; i < dat->farthest_case.size(); i++) { + output_farthest << Change_str(dat->farthest_case[i]); + if (i + 1 != dat->farthest_case.size()) { output_farthest << "-"; } } output_farthest << endl; // solution - output_solution << Change_str((*dat).code) << ","; - output_solution << (*dat).min_solution_step << ","; - output_solution << (*dat).min_solution_num << ","; - for (i = 0; i < (*dat).min_solution_case.size(); i++) { - output_solution << Change_str((*dat).min_solution_case[i]); - if (i + 1 != (*dat).min_solution_case.size()) { + output_solution << Change_str(dat->code) << ","; + output_solution << dat->min_solution_step << ","; + output_solution << dat->min_solution_num << ","; + for (i = 0; i < dat->min_solution_case.size(); i++) { + output_solution << Change_str(dat->min_solution_case[i]); + if (i + 1 != dat->min_solution_case.size()) { output_solution << "-"; } } - output_solution << "," << (*dat).solution_num; + output_solution << "," << dat->solution_num; if (!Output_solution_case) { output_solution << endl; return; } output_solution << ","; - for (i = 0; i < (*dat).solution_case.size(); i++) { - output_solution << Change_str((*dat).solution_case[i]); - output_solution << "(" << (*dat).solution_step[i] << ")"; - if (i + 1 != (*dat).solution_case.size()) { + for (i = 0; i < dat->solution_case.size(); i++) { + output_solution << Change_str(dat->solution_case[i]); + output_solution << "(" << dat->solution_step[i] << ")"; + if (i + 1 != dat->solution_case.size()) { output_solution << "-"; } } @@ -146,63 +146,63 @@ HRD_group::Case_detail* HRD_group::Analyse_Case(Case *start) { // 根据关系 vector case_list; Case_detail *dat = new Case_detail; // dat储存分析结果 Case_detail_init(*dat); // 初始化 - (*dat).code = (*start).Code; - (*start).Layer_num = 0; //令入口节点的层级为0 + dat->code = start->Code; + start->Layer_num = 0; //令入口节点的层级为0 case_list.push_back(start); // 加入队列中 i = 0; while (i != case_list.size()) { // 找到所有元素后退出 if ((*case_list[i]).addr_2x2 == 0xD) { // 2 * 2块在出口位置 - if (!(*case_list[i]).Flag) { // 未被标识 - (*dat).solution_case.push_back((*case_list[i]).Code); // 判定为解 - (*dat).solution_step.push_back((*case_list[i]).Layer_num); - (*case_list[i]).Flag = true; // 进行标识 + if (!case_list[i]->Flag) { // 未被标识 + dat->solution_case.push_back(case_list[i]->Code); // 判定为解 + dat->solution_step.push_back(case_list[i]->Layer_num); + case_list[i]->Flag = true; // 进行标识 } } - for (k = 0; k < (*case_list[i]).Next.size(); k++) { // 检测目标布局的全部子布局 - if ((*(*case_list[i]).Next[k]).Layer_num == -1) { // 若之前还未被搜索到 - (*(*case_list[i]).Next[k]).Layer_num = (*case_list[i]).Layer_num + 1; // 记录层级信息 - case_list.push_back((*case_list[i]).Next[k]); // 加入搜索队列 + for (k = 0; k < case_list[i]->Next.size(); k++) { // 检测目标布局的全部子布局 + if ((*case_list[i]->Next[k]).Layer_num == -1) { // 若之前还未被搜索到 + (*case_list[i]->Next[k]).Layer_num = case_list[i]->Layer_num + 1; // 记录层级信息 + case_list.push_back(case_list[i]->Next[k]); // 加入搜索队列 } - if ((*case_list[i]).Flag) { // 若已经标识 则感染下一层的子布局 - if ((*(*case_list[i]).Next[k]).Layer_num == (*case_list[i]).Layer_num + 1) { // 若为下一层 - (*(*case_list[i]).Next[k]).Flag = true; // 标识 + if (case_list[i]->Flag) { // 若已经标识 则感染下一层的子布局 + if ((*case_list[i]->Next[k]).Layer_num == case_list[i]->Layer_num + 1) { // 若为下一层 + (*case_list[i]->Next[k]).Flag = true; // 标识 } } } i++; // 搜索下一个布局 } // 计算最远布局 - (*dat).farthest_step = (*case_list[case_list.size() - 1]).Layer_num; // 得到最远步数 + dat->farthest_step = case_list[case_list.size() - 1]->Layer_num; // 得到最远步数 for (int i = case_list.size() - 1; i >= 0; i--) { // 逆向搜索 - if ((*case_list[i]).Layer_num == (*dat).farthest_step) { // 如果是最远布局 - (*dat).farthest_case.push_back((*case_list[i]).Code); // 加入记录 + if (case_list[i]->Layer_num == dat->farthest_step) { // 如果是最远布局 + dat->farthest_case.push_back(case_list[i]->Code); // 加入记录 } else { break; // 退出搜索 } } - (*dat).farthest_num = (*dat).farthest_case.size(); // 得到最远布局的个数 - sort((*dat).farthest_case.begin(), (*dat).farthest_case.end()); + dat->farthest_num = dat->farthest_case.size(); // 得到最远布局的个数 + sort(dat->farthest_case.begin(), dat->farthest_case.end()); // 计算解的情况 - (*dat).solution_num = (*dat).solution_case.size(); // 得到解的个数 + dat->solution_num = dat->solution_case.size(); // 得到解的个数 int step = -1; vector < vector > temp; // 暂存不同步数解的信息 - for (i = 0; i < (*dat).solution_step.size(); i++) { // 遍历全部解 - if (step != int((*dat).solution_step[i])) { // 发现步数不同 + for (i = 0; i < dat->solution_step.size(); i++) { // 遍历全部解 + if (step != int(dat->solution_step[i])) { // 发现步数不同 temp.resize(temp.size() + 1); // temp扩容 - step = (*dat).solution_step[i]; // 重置步数 + step = dat->solution_step[i]; // 重置步数 } - temp[temp.size() - 1].push_back((*dat).solution_case[i]); // 数据加入到temp中 + temp[temp.size() - 1].push_back(dat->solution_case[i]); // 数据加入到temp中 } - (*dat).solution_case.clear(); // 清空原数据 + dat->solution_case.clear(); // 清空原数据 for (i = 0; i < temp.size(); i++) { // 将排序后的数据重新写入 sort(temp[i].begin(), temp[i].end()); // 排序同一步数的不同解 if (i == 0) { // 若为最少步数 - (*dat).min_solution_case = temp[0]; // 记录最少步解的布局 - (*dat).min_solution_num = temp[0].size(); // 记录最少步解的个数 - (*dat).min_solution_step = (*dat).solution_step[0]; // 记录最少步数 + dat->min_solution_case = temp[0]; // 记录最少步解的布局 + dat->min_solution_num = temp[0].size(); // 记录最少步解的个数 + dat->min_solution_step = (*dat).solution_step[0]; // 记录最少步数 } for (k = 0; k < temp[i].size(); k++) { - (*dat).solution_case.push_back(temp[i][k]); // 写入数据 + dat->solution_case.push_back(temp[i][k]); // 写入数据 } } return dat; diff --git a/src/engine/HRD_statistic.cpp b/src/engine/HRD_statistic.cpp index 61a5f1f..913319f 100644 --- a/src/engine/HRD_statistic.cpp +++ b/src/engine/HRD_statistic.cpp @@ -33,7 +33,7 @@ void HRD_statistic::Get_seed() { 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) { + 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); } } @@ -41,7 +41,7 @@ void HRD_statistic::Get_seed() { 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) { + if (All_Case[case_index[j]]->group_num > All_Case[case_index[j + 1]]->group_num) { swap(case_index[j], case_index[j + 1]); } } @@ -49,7 +49,7 @@ void HRD_statistic::Get_seed() { 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); + output_seed << cal.Change_str(All_Case[case_index[i]]->code); if (i != case_index.size() - 1) { // 如果不是最后一组就输出回车 output_seed << endl; } @@ -65,7 +65,8 @@ void HRD_statistic::Sort_All_Case() { // 整理所有布局 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); // 解析布局 + All_Case[i]->is_mirror = analy.Is_Mirror(All_Case[i]->code); + analy.Parse_Code(All_Case[i]->code); // 解析布局 jiang_num = bing_num = style_num = 0; for (num = 1; num < 15; num++) { // 遍历所有棋子 switch (analy.Parse_dat.type[num]) { @@ -83,9 +84,9 @@ void HRD_statistic::Sort_All_Case() { // 整理所有布局 continue; } } - (*All_Case[i]).jiang_num = jiang_num; - (*All_Case[i]).bing_num = bing_num; - (*All_Case[i]).style_num = style_num; + 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) { // 显示计算进度 cout << i << "/" << All_Case.size() << endl; } @@ -100,18 +101,18 @@ void HRD_statistic::Sort_All_Case() { // 整理所有布局 case_index.clear(); case_code.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) { + 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); // 记录找到布局的索引 } } for (i = 0; i < case_index.size(); i++) { // 录入找到布局的编码 - case_code.push_back((*All_Case[case_index[i]]).code); + 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; // 记录群组分类结果 - (*All_Case[case_index[i]]).group_index = (*case_res[i]).group_index; + 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]; // 释放内存 } cout << "OK" << endl; @@ -130,18 +131,18 @@ vector HRD_statistic::Split_Group(vector > groups; // 记录群组数组 for (i = 0; i < input_dat.size(); i++) { // 记录输入的编码 Case_group *temp = new Case_group; - (*temp).id = i; - (*temp).code = input_dat[i]; + temp->id = i; + temp->code = input_dat[i]; case_list.push_back(temp); } while (case_list.size() != 0) { // 循环分割群组 it = case_list.begin(); // 定位当前序列起始点 - dat = cal.Calculate_All((*(*it)).code); // 计算起始点编码所在的整个群 + 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) { // 在序列中找到 + if (dat[i] == (*it)->code) { // 在序列中找到 groups[groups.size() - 1].push_back(*it); // 记录找到的编码 case_list.erase(it++); // 删除序列中当前的编码 并指向序列中下一个编码 break; // 退出循环 @@ -161,9 +162,9 @@ vector HRD_statistic::Split_Group(vector group_num = i; + groups[i][j]->group_index = j; + output_dat[groups[i][j]->id] = groups[i][j]; // 记录元素到返回数组 } } return output_dat; @@ -175,7 +176,7 @@ void HRD_statistic::Output_All_Case(string File_name) { // 输出全部编码 ofstream output; output.open(File_name); for (i = 0; i < All_Case.size(); i++) { // 遍历全部布局 - output << cal.Change_str((*All_Case[i]).code); + output << cal.Change_str(All_Case[i]->code); if (i != All_Case.size() - 1) { // 如果不是最后一组就输出回车 output << endl; } @@ -192,13 +193,18 @@ void HRD_statistic::Output_main_table(string File_name) { // 输出全部编码 ofstream output; output.open(File_name); 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) << ","; - output << int((*All_Case[i]).bing_num) << ","; - output << int((*All_Case[i]).style_num) << ","; - output << (*All_Case[i]).group_num << ","; - output << (*All_Case[i]).group_index; + output << All_Case[i]->id << ","; + output << cal.Change_str(All_Case[i]->code) << ","; + if (All_Case[i]->is_mirror) { + output << "Y,"; + } else { + output << "N,"; + } + output << int(All_Case[i]->jiang_num) << ","; + output << int(All_Case[i]->bing_num) << ","; + 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) { // 如果不是最后一组就输出回车 output << endl; } @@ -219,8 +225,8 @@ void HRD_statistic::Find_All_Case() { // 找到所有编码 Code = (n << 32) | i; // 生成Code if (cal.Check_Code(Code)) { // 检查编码是否正确 Case *temp = new Case; - (*temp).code = Code; - (*temp).id = num; + temp->code = Code; + temp->id = num; All_Case.push_back(temp); // 记录搜到的编码 num++; } diff --git a/src/engine/HRD_statistic.h b/src/engine/HRD_statistic.h index e675652..523da07 100644 --- a/src/engine/HRD_statistic.h +++ b/src/engine/HRD_statistic.h @@ -13,6 +13,7 @@ class HRD_statistic { private: struct Case { unsigned int id; + bool is_mirror; unsigned long long code; unsigned char jiang_num; unsigned char bing_num; diff --git a/src/engine/main.cpp b/src/engine/main.cpp index ef5aa45..ced9d25 100644 --- a/src/engine/main.cpp +++ b/src/engine/main.cpp @@ -15,8 +15,10 @@ unsigned long long checked_code; bool code_check(string str) { HRD_cal cal; char code_str[10]; - if (str.length() != 9) { + if (str.length() > 9) { // 超过九位 错误 return false; + } else { + str.resize(9, '0'); // 剩余的补0 } for (unsigned int i = 0; i < str.length(); i++) { code_str[i] = str[i]; @@ -324,65 +326,65 @@ void show_help() { 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 << " eg: ./engine --show 1A9BF0C00" << endl; + cout << " ./engine --show 1A9BF0C00 4" << endl; cout << endl; cout << " --cal [file_name]" << endl; cout << " Purpose: Find the minimum step solution of " << endl; - cout << " exp: ./engine --cal 1A9BF0C00" << endl; - cout << " ./engine --cal 1A9BF0C00 demo.txt" << endl; + cout << " eg: ./engine --cal 1A9BF0C00" << endl; + cout << " ./engine --cal 1A9BF0C00 demo.txt" << endl; cout << endl; cout << " --cal-target [file_name]" << 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 << " eg: ./engine --cal-target 4FEA13400 43EA73400" << endl; + cout << " ./engine --cal-target 4FEA13400 43EA73400 demo.txt" << endl; cout << 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 << " eg: ./engine --group 4FEA13400" << endl; + cout << " ./engine --group 4FEA13400 demo.txt" << endl; cout << 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 << " eg: ./engine --analy 1A9BF0C00" << endl; + cout << " ./engine --analy 1A9BF0C00 demo.txt" << endl; cout << endl; cout << " --analy-quiet " << 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 << " eg: ./engine --analy-quiet 1A9BF0C00 demo.txt" << endl; cout << 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 << " eg: ./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 << " eg: ./engine --analy-group-integral 1A9BF0C00 farthest.csv solution.csv" << endl; cout << 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 << " eg: ./engine --analy-multi-group 5-4-0.txt farthest.csv solution.csv" << endl; cout << 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 << " eg: ./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 << " eg: ./engine --all" << endl; cout << endl; cout << " --all-code " << endl; cout << " Purpose: Find all the code of klotski" << endl; - cout << " exp: ./engine --all-code All_Case.txt" << endl; + cout << " eg: ./engine --all-code All_Case.txt" << endl; cout << endl; cout << " --help" << endl; cout << " Purpose: Display instructions for use" << endl; - cout << " exp: ./engine --help" << endl; + cout << " eg: ./engine --help" << endl; cout << endl; cout << "More details: https://github.com/dnomd343/HRD_Database" << endl; cout << endl;