Browse Source

update engine

master
Dnomd343 4 years ago
parent
commit
a9f176ec06
  1. 133
      src/engine/HRD_analy.cpp
  2. 9
      src/engine/HRD_analy.h
  3. 32
      src/engine/HRD_cal.cpp
  4. 106
      src/engine/HRD_group.cpp
  5. 62
      src/engine/HRD_statistic.cpp
  6. 1
      src/engine/HRD_statistic.h
  7. 40
      src/engine/main.cpp

133
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_cal *> 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_cal *> *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_cal *> case_list;
vector <Case_cal *> *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 <Case_cal *>;
start->next_case = new vector <Case_cal *>;
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 <Case_cal *>;
dat->next_case = new vector <Case_cal *>;
(*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);
}

9
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 <Case_cal *> source_case;
vector <Case_cal *> next_case;
vector <Case_cal *> *source_case;
vector <Case_cal *> *next_case;
};
vector <vector <Case_cal *> > 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();

32
src/engine/HRD_cal.cpp

@ -13,7 +13,7 @@ vector <unsigned long long> 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 <unsigned long long> HRD_cal::Calculate(unsigned long long Code) { // 寻
vector <unsigned long long> HRD_cal::Get_Path(unsigned int result_num) { // 找到开始到目标的最短路径
vector <unsigned long long> 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); // 更新移动后的编码

106
src/engine/HRD_group.cpp

@ -61,24 +61,24 @@ void HRD_group::Analyse_Group(vector <unsigned long long> dat) { // 传入整个
vector <Case *> 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 <unsigned long long> 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 <unsigned long long> 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 <unsigned long long> 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 *> 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 <unsigned long long> > 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;

62
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::Case_group *> HRD_statistic::Split_Group(vector <unsigned
vector < vector <Case_group *> > 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::Case_group *> HRD_statistic::Split_Group(vector <unsigned
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]; // 记录元素到返回数组
groups[i][j]->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++;
}

1
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;

40
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 <code> [square_width]" << endl;
cout << " Purpose: Visualize the <code>" << 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 <code> [file_name]" << endl;
cout << " Purpose: Find the minimum step solution of <code>" << 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 <code> <target> [file_name]" << endl;
cout << " Purpose: Find the shortest path from <code> to <target>" << 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 <code> [file_name]" << endl;
cout << " Purpose: Find all elements of the group where <code> 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 <code> [file_name]" << endl;
cout << " Purpose: Detailed analysis of the <code> " << 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 <code> <file_name>" << 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 <code> <file_name_farthest> <file_name_solution>" << endl;
cout << " <file_name_farthest>: As the output file of \"farthest\"" << endl;
cout << " <file_name_solution>: As the output file of \"solution\"" << endl;
cout << " Purpose: Analyze the whole group where <code> 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 <code> <file_name_farthest> <file_name_farthest>" << 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 <input_file_name> <file_name_farthest> <file_name_farthest>" << endl;
cout << " <input_file_name>: As the input file of seeds" << endl;
cout << " <file_name_farthest>: As the output file of \"farthest\"" << endl;
cout << " <file_name_farthest>: 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 <input_file_name> <file_name_farthest> <file_name_farthest>" << 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 <file_name>" << 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;

Loading…
Cancel
Save