Browse Source

v1.8

master v1.8
Dnomd343 5 years ago
parent
commit
1f58ca7532
  1. 644
      Engine.cpp
  2. BIN
      Engine.exe
  3. 358
      Form_Detail.frm
  4. BIN
      Form_Detail.frx
  5. 13
      Form_Game.frm
  6. 3
      HRD_Game.vbp
  7. 3
      HRD_Game.vbw
  8. 1
      Module.bas

644
Engine.cpp

@ -0,0 +1,644 @@
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <fstream>
using namespace std;
ifstream File_Input;
ofstream File_Output;
const unsigned char Up = 1, Down = 2, Left = 3, Right = 4;
//用于寻找下一布局
struct block_struct {
unsigned char address; //0~19
unsigned char style; //0:2*2 1:2*1 2:1*2 3:1*1
};
unsigned char table[20]; //0~9:block[?] 0xA:space 0xFF:empty
unsigned char space[2]; //space[0~1]的位置
struct block_struct block[10]; //0:2*2 1~5:1*2,2*1 6~9:1*1
bool quick; //仅计算最短步骤
int Solution_num_quick;
vector <unsigned int> Source_quick; //父布局编号
vector <unsigned int> Solution_quick; //最短路径
//用于绘制整个队列树
unsigned int Now_Move; //目前正在进行计算的布局编号
list <unsigned int> int_list; //空列表
vector <unsigned int> int_vector; //空vector
list <unsigned int> Hash[0x10000]; //哈希索引表
vector <unsigned int> List; //所有情况的队列
vector <unsigned int> Layer_Num; //所在层的编号
vector <unsigned int> Layer_Index; //层中所属的编号
vector <list <unsigned int> > Source; //父布局编号
vector <vector <unsigned int> > Layer; //分层
vector <vector <vector <unsigned int> > > Layer_Next; //分层链接
//布局的基本参数
int group_size; //整个队列组的大小
int min_steps; //解的最少步骤
int farthest_steps; //最远布局的步数
vector <unsigned int> Solutions; //所有解
vector <unsigned int> Solutions_steps; //所有解的最少步
vector <unsigned int> min_Solutions; //所有最少步解
vector <unsigned int> farthest_cases; //所有最远的布局
//vector <unsigned int> solution_path; //最少步解法
void debug();
void Find_All_Case();
void Data_Output(string File_name);
void Split_Layer();
unsigned int Change_int (char str[8]);
string Change_str (unsigned int dat);
void Output_Graph (unsigned int Code);
void Analyse_Code (unsigned int Code);
void Add_Case (unsigned int Code);
void Calculate (unsigned int Start_Code);
void Date_Back_quick (int num);
void Calculate_quick (unsigned int Start_Code);
bool Check (unsigned int Code);
unsigned int Get_Code();
void Find_Next();
bool Check_Empty (unsigned char address,unsigned char dir,unsigned char num);
void Move_Block (unsigned char num,unsigned char dir_1,unsigned char dir_2);
void Fill_Block (unsigned char addr, unsigned char style, unsigned char filler);
vector <unsigned int> Search_Path (unsigned int target_num);
void Analyse_Case (unsigned int Start_Code);
int main(int argc, char* argv[]) {
unsigned int Code, i;
string File_name, Parameter;
cout << "HRD-Engine by Dnomd343" << endl;
if (argc == 3) {
Parameter = argv[1];
Code = Change_int(argv[2]);
if (Check(Code) == false) {cout << "Code Error" << endl; return 0;}
File_name = Change_str(Code) + ".txt";
if (Parameter == "-q") {
cout << "Quick Calculate Mode." << endl;
cout << "Code: " << Change_str(Code) << endl;
cout << "Data Save at " << File_name << endl;
quick = true;
Calculate_quick(Code);
Date_Back_quick(Solution_num_quick);
File_Output.open(File_name.c_str());
if (Solution_quick.size() == 0) {
File_Output << "No Solution" << endl;
} else {
File_Output << Solution_quick.size() - 1 << endl;
}
for (i = 0; i < Solution_quick.size(); i++) {
File_Output << Change_str(Solution_quick[i]) << endl;
}
File_Output.close();
} else if (Parameter == "-a") {
cout << "All Calculate Mode." << endl;
cout << "Code: " << Change_str(Code) << endl;
cout << "Data Save at " << File_name << endl;
quick = false;
Analyse_Case(Code);
Data_Output(File_name);
} else {
cout << "Parameter Error" << endl;
}
} else {
cout << "Usage: [HRD-Engine.exe] [-q]/[-a] Code" << endl;
cout << "-q: Quick Calculate Mode" << endl << "-a: All Calculate Mode" << endl;
cout << "Such as 'HRD-Engine.exe -q 4FEA134'" << endl << " or 'HRD-Engine.exe -a 1A9BF0C'" << endl;
}
return 0;
}
void Analyse_Case (unsigned int Start_Code) { //对一个布局进行分析
unsigned int i, first_solution;
if (Check(Start_Code) == false) {return;} //若输入编码无效则退出
Calculate(Start_Code); //通过计算建立队列表
group_size = List.size(); //整个队列树大小
min_steps = -1;
farthest_steps = -1;
Solutions.clear();
Solutions_steps.clear();
min_Solutions.clear();
farthest_cases.clear();
//solution_path.clear();
bool get_it = false;
for (i = 0; i < List.size(); i++) { //遍历队列中所有元素
Analyse_Code(List[i]);
if (block[0].address == 13) { //若当前布局为有效解
if (get_it == false){
min_steps = Layer_Num[i]; //第一个找到的解为最少步解
first_solution = i;
get_it = true;
}
Solutions.push_back(List[i]); //将找到的有效解加入解集中
Solutions_steps.push_back(Layer_Num[i]);
if (Layer_Num[i] == min_steps) {
min_Solutions.push_back(List[i]); //将找到的最小步有效解加入最小步解集中
}
}
}
farthest_steps = Layer_Num[Layer_Num.size() - 1]; //计算最远布局的步数
for (i = Layer_Num.size() - 1; i > 0; i--) { //找到所有最远的布局
if(Layer_Num[i] != farthest_steps) {break;}
farthest_cases.push_back(List[i]);
}
//if (min_steps != -1) {solution_path = Search_Path(first_solution);}
}
void Split_Layer() {
vector <vector <unsigned int> > temp;
int i, num, index;
num = -1;
index = 0;
for (i = 0; i < Layer_Num.size(); i++) {
if (Layer_Num[i] != num) {
Layer.push_back(int_vector);
Layer_Next.push_back(temp);
num = Layer_Num[i];
index = 0;
}
Layer_Index.push_back(index);
index++;
Layer[num].push_back(List[i]);
Layer_Next[num].push_back(int_vector);
}
list <unsigned int>::iterator poi;
for (i = 1; i < List.size(); i++) {
poi = Source[i].begin();
while (poi != Source[i].end()) {
Layer_Next[Layer_Num[*poi]][Layer_Index[*poi]].push_back(Layer_Index[i]);
++poi;
}
}
}
vector <unsigned int> Search_Path (unsigned int target_num) { //搜索到达目标布局的一条最短路径 返回vector类
vector <unsigned int> path;
int temp = -1;
path.push_back(target_num); //路径中加入目标布局
while (temp != 0) {
temp = path[path.size() - 1];
path.push_back(*Source[temp].begin());
}
path.pop_back(); //去掉重复的根布局
temp = path.size() / 2; //反置整个路径
for (int i = 0; i < temp; i++) {
swap(path[i], path[path.size() - i - 1]);
}
for (int i = 0; i < path.size(); i++){ //将序号改成布局的编码
path[i] = List[path[i]];
}
return path;
}
void Date_Back_quick (int num) {
if (num == -1) {return;}
Solution_quick.push_back(List[num]);
if (num == 0) {return;}
while (Source_quick[num] != 0) {
num = Source_quick[num];
Solution_quick.push_back(List[num]);
}
Solution_quick.push_back(List[0]);
unsigned int i;
for (i = 0; i < Solution_quick.size() / 2 ; i++) {
swap(Solution_quick[i],Solution_quick[Solution_quick.size() - i - 1]);
}
}
void Calculate_quick (unsigned int Start_Code) { //启动计算引擎
unsigned int i;
for (i = 0; i <= 0xFFFF; i++) {Hash[i].clear();} //初始化
List.clear();
Source_quick.clear();
Solution_num_quick = -1;
Hash[(Start_Code>>4) & 0xFFFF].push_back(0); //加入初始布局
List.push_back(Start_Code);
Source_quick.push_back(0);
Now_Move = 0; //搜索目标指向根节点
while (Now_Move != List.size()) { //进行广度优先搜索
Analyse_Code(List[Now_Move]); //解析目标布局
if (block[0].address == 13) {
Solution_num_quick = Now_Move;
return;
}
Find_Next(); //根据解析结果搜索所有子布局
Now_Move++;
}
}
void Calculate (unsigned int Start_Code) { //启动计算引擎
unsigned int i;
for (i = 0; i <= 0xFFFF; i++) {Hash[i].clear();} //初始化
List.clear();
Layer_Num.clear();
Source.clear();
Hash[(Start_Code>>4) & 0xFFFF].push_back(0); //加入初始布局
List.push_back(Start_Code);
Layer_Num.push_back(0);
Source.push_back(int_list);
Now_Move = 0; //搜索目标指向根节点
while (Now_Move != List.size()) { //进行广度优先搜索
Analyse_Code(List[Now_Move]); //解析目标布局
Find_Next(); //根据解析结果搜索所有子布局
Now_Move++;
}
Split_Layer();
}
void Add_Case (unsigned int Code) { //将计算结果加入队列
list <unsigned int>::iterator poi; //定义迭代器
poi = Hash[(Code>>4) & 0xFFFF].begin(); //设置poi为索引表的起始点
while (poi != Hash[(Code>>4) & 0xFFFF].end()) { //遍历索引表
if (Code == List[*poi]) { //若发现重复
if (quick == true) {return;}
if ((Layer_Num[*poi] - Layer_Num[Now_Move]) == 1) { //若高一层
Source[*poi].push_back(Now_Move); //加入父节点列表
}
return; //重复 退出
}
++poi;
}
Hash[(Code>>4) & 0xFFFF].push_back(List.size()); //将计算结果添加至索引表
List.push_back(Code); //将计算结果加入队列
if (quick == false) {
Layer_Num.push_back(Layer_Num[Now_Move] + 1); //添加对应的层数
Source.push_back(int_list); //初始化其父节点列表
Source[Source.size()-1].push_back(Now_Move); //将正在进行搜索的布局添加为父节点
} else {
Source_quick.push_back(Now_Move); //将正在进行搜索的布局添加为父布局
}
}
void Fill_Block (unsigned char addr, unsigned char style, unsigned char filler) { //用指定内容填充table中指定的位置
if (style == 0) {table[addr] = table[addr + 1] = table[addr + 4] = table[addr + 5] = filler;} //2*2
else if (style == 1) {table[addr] = table[addr + 1] = filler;} //2*1
else if (style == 2) {table[addr] = table[addr + 4] = filler;} //1*2
else if (style == 3) {table[addr] = filler;} //1*1
}
void Move_Block (unsigned char num, unsigned char dir_1, unsigned char dir_2) { //按要求移动块并将移动后的编码传给Add_Case
unsigned char i, addr, addr_bak;
addr = block[num].address;
addr_bak = addr;
if (dir_1 == Up) {addr -= 4;} //第一次移动
else if (dir_1==Down) {addr += 4;}
else if (dir_1==Left) {addr--;}
else if (dir_1==Right) {addr++;}
if (dir_2 == Up) {addr -= 4;} //第二次移动
else if (dir_2 == Down) {addr += 4;}
else if (dir_2 == Left) {addr--;}
else if (dir_2 == Right) {addr++;}
Fill_Block(addr_bak, block[num].style, 0xA); //修改 table为移动后的状态
Fill_Block(addr, block[num].style, num);
block[num].address = addr;
Add_Case(Get_Code()); //生成编码并赋予Add_Case
block[num].address = addr_bak;
Fill_Block(addr, block[num].style, 0xA); //还原 table原来的状态
Fill_Block(addr_bak, block[num].style, num);
}
void Find_Next() { //寻找所有移动的方式并提交给Move_Block
bool Can_Move[10];
unsigned char i, addr;
for (i = 0; i < 10; i++) {Can_Move[i] = false;}
for (i = 0; i <= 1; i++) { //寻找位于空格周围的所有块
addr = space[i];
if (addr > 3)
if (table[addr - 4] != 0xA) {Can_Move[table[addr - 4]] = true;}
if (addr < 16)
if (table[addr + 4] != 0xA) {Can_Move[table[addr + 4]] = true;}
if (addr % 4 != 0)
if (table[addr - 1] != 0xA) {Can_Move[table[addr - 1]] = true;}
if (addr % 4 != 3) {
if (table[addr + 1] != 0xA) {Can_Move[table[addr + 1]] = true;}}
}
for (i = 0; i <= 9; i++) {
if (Can_Move[i] == true) { //若该块可能可以移动
addr = block[i].address;
if (block[i].style == 0) { //2*2
if ((Check_Empty(addr, Up, 1) == true) &&
(Check_Empty(addr + 1,Up, 1) == true)) {Move_Block(i, Up, 0);}
if ((Check_Empty(addr, Down, 2) == true) &&
(Check_Empty(addr + 1,Down, 2) == true)) {Move_Block(i, Down, 0);}
if ((Check_Empty(addr, Left, 1) == true) &&
(Check_Empty(addr + 4, Left, 1) == true)) {Move_Block(i, Left, 0);}
if ((Check_Empty(addr, Right, 2) == true) &&
(Check_Empty(addr + 4, Right, 2) == true)) {Move_Block(i, Right, 0);}
}
else if (block[i].style == 1) { //2*1
if ((Check_Empty(addr, Up, 1) == true) &&
(Check_Empty(addr + 1, Up, 1) == true)) {Move_Block(i, Up, 0);}
if ((Check_Empty(addr, Down, 1) == true) &&
(Check_Empty(addr + 1, Down, 1) == true)) {Move_Block(i, Down, 0);}
if (Check_Empty(addr, Left, 1) == true) {
Move_Block(i, Left, 0);
if (Check_Empty(addr, Left, 2) == true) {Move_Block(i, Left, Left);}
}
if (Check_Empty(addr, Right, 2) == true) {
Move_Block(i, Right, 0);
if (Check_Empty(addr, Right, 3) == true) {Move_Block(i, Right, Right);}
}
}
else if (block[i].style == 2) { //1*2
if (Check_Empty(addr, Up, 1) == true) {
Move_Block(i, Up, 0);
if (Check_Empty(addr, Up, 2) == true) {Move_Block(i, Up, Up);}
}
if (Check_Empty(addr, Down, 2) == true) {
Move_Block(i, Down, 0);
if (Check_Empty(addr, Down, 3) == true) {Move_Block(i, Down, Down);}
}
if ((Check_Empty(addr, Left, 1) == true) &&
(Check_Empty(addr + 4, Left, 1) == true)) {Move_Block(i, Left, 0);}
if ((Check_Empty(addr, Right, 1) == true) &&
(Check_Empty(addr + 4, Right, 1) == true)) {Move_Block(i, Right, 0);}
}
else if (block[i].style == 3) { //1*1
if (Check_Empty(addr, Up, 1) == true) {
Move_Block(i, Up, 0);
if (Check_Empty(addr - 4, Up, 1) == true) {Move_Block(i, Up, Up);}
if (Check_Empty(addr - 4, Left, 1) == true) {Move_Block(i, Up, Left);}
if (Check_Empty(addr - 4, Right, 1) == true) {Move_Block(i, Up, Right);}
}
if (Check_Empty(addr, Down, 1) == true) {
Move_Block(i, Down, 0);
if (Check_Empty(addr + 4, Down, 1) == true) {Move_Block(i, Down, Down);}
if (Check_Empty(addr + 4, Left, 1) == true) {Move_Block(i, Down, Left);}
if (Check_Empty(addr + 4, Right, 1) == true) {Move_Block(i, Down, Right);}
}
if (Check_Empty(addr, Left, 1) == true) {
Move_Block(i, Left, 0);
if (Check_Empty(addr - 1, Up, 1) == true) {Move_Block(i, Left, Up);}
if (Check_Empty(addr - 1, Down, 1) == true) {Move_Block(i, Left, Down);}
if (Check_Empty(addr - 1, Left, 1) == true) {Move_Block(i, Left, Left);}
}
if (Check_Empty(addr, Right, 1) == true) {
Move_Block(i, Right, 0);
if (Check_Empty(addr + 1, Up, 1) == true) {Move_Block(i, Right, Up);}
if (Check_Empty(addr + 1, Down, 1) == true) {Move_Block(i, Right, Down);}
if (Check_Empty(addr + 1, Right, 1) == true) {Move_Block(i, Right, Right);}
}
}
}
}
}
bool Check_Empty (unsigned char address, unsigned char dir, unsigned char num) { //判断指定位置是否为空格 若不是空格或者无效返回false
unsigned char x, y, addr;
if (address > 19) {return false;} //输入位置不存在
x = address % 4;
y = (address - x) / 4;
if (dir == Up) { //上方
if (y < num) {return false;}
addr = address - num * 4;
}
if (dir == Down) { //下方
if (y + num > 4) {return false;}
addr = address + num * 4;
}
if (dir == Left) { //左侧
if (x < num) {return false;}
addr = address - num;
}
if (dir == Right) { //右侧
if(x + num > 3){return false;}
addr = address + num;
}
if (table[addr] == 0xA) {
return true;
} else {
return false;
}
}
unsigned int Get_Code() { //生成编码
bool temp[20];
unsigned int Code = 0;
unsigned char i, addr, style;
for (i = 0; i < 20; i++) {temp[i] = false;} //初始化
temp[block[0].address] = temp[block[0].address + 1] =
temp[block[0].address + 4] = temp[block[0].address + 5] = true;
Code |= block[0].address<<24; //2*2块的位置
addr = 0;
for (i = 1; i <= 11; i++) {
while(temp[addr] == true){ //找到下一个未填充的空格
if (addr < 19) {
addr++;
} else {
return 0;
}
}
if (table[addr] == 0xA) { //空格
temp[addr] = true;
} else {
style = block[table[addr]].style;
if (style == 1) { //2*1
temp[addr] = temp[addr + 1] = true;
Code |= 1<<(24 - i * 2);
}
else if (style == 2) { //1*2
temp[addr] = temp[addr + 4] = true;
Code |= 2<<(24 - i * 2);
}
else if (style == 3) { //1*1
temp[addr] = true;
Code |= 3<<(24 - i * 2);
}
}
}
return Code;
}
void Analyse_Code (unsigned int Code) { //解译编码到 table[20] block[10] space[2]中
unsigned char i, addr, style;
unsigned char num_space = 0, num_type_1 = 0, num_type_2 = 5;
space[0] = space[1] = 0xFF; //初始化
for (i = 0; i < 20; i++) {table[i] = 0xFF;}
for (i = 0; i <= 9; i++) {
block[i].address = 0xFF;
block[i].style = 0xFF;
}
block[0].address = 0xF & (Code>>24); //开始解译
if (block[0].address > 14) {goto err;} //2*2块越界 退出
block[0].style = 0; //设置2*2块的参数
Fill_Block(block[0].address, 0, 0x0);
addr = 0;
for (i = 0; i < 11; i++) { //遍历 10个块
while (table[addr] != 0xFF){ //向下搜索空块
if (addr < 19) {
addr++;
} else {
break;
}
}
style = 0x3 & (Code>>(22 - i * 2)); //0:space 1:2*1 2:1*2 3:1*1
if (style == 0) { //space
table[addr] = 0xA;
space[num_space] = addr;
if (num_space == 0) {num_space++;}
}
if (style == 1) { //2*1
if (num_type_1 < 5) {num_type_1++;}
if (addr > 18) {goto err;} //2*1块越界
block[num_type_1].style = 1;
block[num_type_1].address = addr;
table[addr] = table[addr + 1] = num_type_1;
}
if (style == 2) { //1*2
if (num_type_1 < 5) {num_type_1++;}
if (addr > 15) {goto err;} //1*2块越界
block[num_type_1].style = 2;
block[num_type_1].address = addr;
table[addr] = table[addr + 4] = num_type_1;
}
if (style == 3) { //1*1
if (num_type_2 < 9) {num_type_2++;}
block[num_type_2].style = 3;
block[num_type_2].address = addr;
table[addr] = num_type_2;
}
}
err:;
}
bool Check (unsigned int Code) { //检查编码是否合法 正确返回true 错误返回false
bool temp[20];
unsigned char addr, i;
Analyse_Code(Code);
for (i = 0; i < 20; i++){temp[i] = false;} //初始化
for (i = 0; i < 20; i++) { //检查table内容是否合法
if (table[i] > 10) {return false;}
}
if (block[0].style != 0) {return false;} //检查2*2块
for (i = 1; i <= 5; i++) { //检查2*1与1*2块
if ((block[i].style != 1) && (block[i].style != 2)) {return false;}
}
for (i = 6; i <= 9; i++) { //检查1*1块
if (block[i].style != 3) {return false;}
}
for (i = 0; i <= 1; i++) { //检查空格
if (space[i] > 19) {
return false;
} else {
temp[space[i]] = true;
}
}
addr = block[0].address; //检查2*2块
if ((addr > 14) || (addr%4 == 3)) {return false;}
if ((temp[addr] == true) || (temp[addr + 1] == true) ||
(temp[addr + 4] == true) || (temp[addr + 5] == true)) {return false;}
temp[addr] = temp[addr + 1] = temp[addr + 4] = temp[addr + 5] = true;
for (i = 1; i <= 5; i++) { //检查2*1与1*2块
addr = block[i].address;
if (block[i].style == 1) {
if ((addr > 18) || (addr % 4 == 3)) {return false;}
if ((temp[addr] == true) || (temp[addr + 1] == true)) {return false;}
temp[addr] = temp[addr + 1] = true;
}
if (block[i].style == 2) {
if (addr > 15) {return false;}
if ((temp[addr] == true) || (temp[addr + 4] == true)) {return false;}
temp[addr] = temp[addr + 4] = true;
}
}
for (i = 6; i <= 9; i++) { //检查1*1块
addr = block[i].address;
if (addr > 19) {return false;}
if (temp[addr] == true) {return false;}
temp[addr] = true;
}
return true;
}
string Change_str (unsigned int dat) { //将编码数据转化为字符
unsigned char i, bit;
string str = "";
for (i = 0; i < 7; i++) {
bit = 0xF & dat>>(6 - i)*4; //分离单个十六进制位
if ((bit >= 0) && (bit <= 9)) {str += bit + 48;} //0~9
if ((bit >= 0xA) && (bit <= 0xF)) {str += bit + 55;} //A~F
}
return str;
}
unsigned int Change_int (char str[8]) { //将编码字符转化为int
unsigned int i, dat = 0;
for (i = 0; i < 7; i++) {
if ((str[i] >= 48) && (str[i] <= 57)) {dat = dat | (str[i] - 48)<<(24 - i * 4);} //0~9
if ((str[i] >= 65) && (str[i] <= 70)) {dat = dat | (str[i] - 55)<<(24 - i * 4);} //A~F
if ((str[i] >= 97) && (str[i] <= 102)) {dat = dat | (str[i] - 87)<<(24 - i * 4);} //a~f
}
return dat;
}
void Find_All_Case(){ //Right_File's MD5: 4A0179C6AEF266699A73E41ECB4D87C1
File_Output.open("All_Case.txt");
unsigned int i;
for (i = 0; i < 0xFFFFFFF; i += 4) {
if (Check(i) == true) {File_Output << Change_str(i) << endl;}
}
File_Output.close();
}
void Data_Output(string File_name){
unsigned int i, j, layer;
File_Output.open(File_name.c_str());
File_Output << "[Group_size]" << endl << group_size << endl;
File_Output << "[Min_steps]" << endl << min_steps << endl;
File_Output << "[Farthest_steps]" << endl << farthest_steps << endl;
File_Output << "[Min_Solutions]" << endl;
for (i = 0; i < min_Solutions.size(); i++) {
File_Output << Change_str(min_Solutions[i]) << endl;
}
File_Output << "[Farthest_cases]" << endl;
for (i = 0; i < farthest_cases.size(); i++) {
File_Output << Change_str(farthest_cases[i]) << endl;
}
File_Output << "[Solutions]" << endl;
for (i = 0; i < Solutions.size(); i++) {
File_Output << Change_str(Solutions[i]) << " (" << Solutions_steps[i] << ")" << endl;
}
File_Output << "[List]" << endl;
for (i = 0; i < List.size(); i++) {
File_Output << i << " -> " << Change_str(List[i]) << " (" << Layer_Num[i] << "," << Layer_Index[i] << ")" << endl;
}
File_Output << "[Layer]" << endl;
for (layer = 0; layer < Layer.size(); layer++) {
for (i = 0; i < Layer_Next[layer].size(); i++) {
File_Output << "(" << layer << "," << i << ")" << " -> ";
for (j = 0; j < Layer_Next[layer][i].size(); j++) {
File_Output << "(" << (layer+1) << "," << Layer_Next[layer][i][j] << ") ";
}
File_Output << endl;
}
}
File_Output.close();
}

BIN
Engine.exe

Binary file not shown.

358
Form_Detail.frm

@ -0,0 +1,358 @@
VERSION 5.00
Begin VB.Form Form_Detail
AutoRedraw = -1 'True
BorderStyle = 1 'Fixed Single
Caption = "详细信息"
ClientHeight = 4605
ClientLeft = 45
ClientTop = 390
ClientWidth = 7965
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 4605
ScaleWidth = 7965
StartUpPosition = 2 '屏幕中心
Begin VB.CommandButton Command_Analyse
Caption = "全局溯源分析"
Height = 300
Left = 2520
TabIndex = 4
Top = 120
Width = 1695
End
Begin VB.Timer Timer_Debug
Interval = 100
Left = 0
Top = 0
End
Begin VB.TextBox Text_Debug
Height = 4380
Left = 7960
MultiLine = -1 'True
TabIndex = 3
Top = 120
Width = 2415
End
Begin VB.Timer Timer_Get_Data
Interval = 50
Left = 0
Top = 0
End
Begin VB.ListBox List_Data
Height = 4020
ItemData = "Form_Detail.frx":0000
Left = 2520
List = "Form_Detail.frx":0002
TabIndex = 2
Top = 480
Width = 1695
End
Begin VB.ComboBox Combo_Detail
Height = 300
Left = 120
Style = 2 'Dropdown List
TabIndex = 1
Top = 120
Width = 2295
End
Begin VB.ListBox List_Detail
Height = 4020
ItemData = "Form_Detail.frx":0004
Left = 120
List = "Form_Detail.frx":0006
TabIndex = 0
Top = 480
Width = 2295
End
End
Attribute VB_Name = "Form_Detail"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private Type Case_Block
address As Integer
style As Integer
End Type
Private Type Layer_struct
size As Integer
layer_dat() As String
End Type
Dim wait_data As Boolean, loading As Boolean
Dim Block(0 To 9) As Case_Block
Dim start_x As Integer, start_y As Integer, square_width As Integer, gap As Integer
Dim group_size As Long, min_steps As Integer, farthest_steps As Integer
Dim min_solutions() As String, farthest_cases() As String, solutions() As String, layers() As String, layer() As Layer_struct
Private Sub Form_Load()
start_x = 4350
start_y = 135
square_width = 777
gap = 75
loading = False
If debug_mode = True Then
Form_Detail.width = 10575
Text_Debug.Visible = True
Else
Form_Detail.width = 8055
Text_Debug.Visible = False
End If
If on_top = True Then
SetWindowPos Me.hwnd, -1, 0, 0, 0, 0, 1 Or 2
Else
SetWindowPos Me.hwnd, -2, 0, 0, 0, 0, 1 Or 2
End If
ReDim min_solutions(0)
ReDim farthest_cases(0)
ReDim solutions(0)
ReDim layers(0)
ReDim layer(0 To 0)
Combo_Detail.AddItem "最少步解"
Combo_Detail.AddItem "所有的解"
Combo_Detail.AddItem "最远的布局"
Combo_Detail.AddItem "各步数的布局"
wait_file_name = start_code & ".txt"
If Dir(start_code & ".txt") <> "" Then Kill start_code & ".txt"
Shell "Engine.exe -a " & start_code
wait_cancel = False
waiting = True
wait_data = True
Form_Wait.Show 1
Print_Block start_x, start_y, square_width * 4 + gap * 5, square_width * 5 + gap * 6, case_line_width, case_color, case_line_color
End Sub
Private Sub Combo_Detail_Click()
Dim i As Long
List_Detail.Clear
If Combo_Detail.ListIndex = 0 Then
If min_steps = -1 Then
List_Detail.AddItem "无解"
Else
List_Detail.AddItem Combo_Detail.Text & "(" & min_steps & "步,共" & UBound(min_solutions) & "个)"
End If
ElseIf Combo_Detail.ListIndex = 1 Then
List_Detail.AddItem Combo_Detail.Text & "(共" & UBound(solutions) & "个)"
ElseIf Combo_Detail.ListIndex = 2 Then
List_Detail.AddItem Combo_Detail.Text & "(" & farthest_steps & "步,共" & UBound(farthest_cases) & "个)"
ElseIf Combo_Detail.ListIndex = 3 Then
For i = 0 To UBound(layer)
List_Detail.AddItem "第" & i & "步(共" & layer(i).size & "个)"
Next i
End If
List_Detail.ListIndex = 0
End Sub
Private Sub List_Detail_Click()
Dim i As Long, n As Integer
loading = True
List_Data.Clear
If Combo_Detail.ListIndex = 0 Then
For i = 1 To UBound(min_solutions)
If Not min_steps = -1 Then List_Data.AddItem min_solutions(i) & "(" & min_steps & "步)"
Next i
ElseIf Combo_Detail.ListIndex = 1 Then
For i = 1 To UBound(solutions)
n = n + 1
If n = 200 Then n = 0: DoEvents
List_Data.AddItem Left(solutions(i), 7) & Mid(solutions(i), 9, Len(solutions(i)) - 9) & "步)"
Next i
ElseIf Combo_Detail.ListIndex = 2 Then
For i = 1 To UBound(farthest_cases)
List_Data.AddItem farthest_cases(i) & "(" & farthest_steps & "步)"
Next i
ElseIf Combo_Detail.ListIndex = 3 Then
For i = 0 To UBound(layer(List_Detail.ListIndex).layer_dat)
List_Data.AddItem layer(List_Detail.ListIndex).layer_dat(i) & "(" & List_Detail.ListIndex & "步)"
Next i
End If
If Not min_steps = -1 Then
List_Data.ListIndex = 0
Else
If Combo_Detail.ListIndex = 2 Or Combo_Detail.ListIndex = 3 Then List_Data.ListIndex = 0
End If
loading = False
End Sub
Private Sub List_Data_Click()
Call Analyse_Code(Left(List_Data.List(List_Data.ListIndex), 7))
Call Output_Graph
End Sub
Private Sub Timer_Get_Data_Timer()
Dim dat As String
Combo_Detail.Enabled = Not loading
If wait_data = True And waiting = False Then
wait_data = False
MsgBox Form_Game.Label_Title, , "> _ <"
Call Get_Data(start_code & ".txt")
dat = "共衍生出" & group_size & "种布局" & vbCrLf & "最远为" & farthest_steps & "步" & vbCrLf
If min_steps = -1 Then dat = dat & "无解" Else dat = dat & "最少需要" & min_steps & "步"
MsgBox dat, , "> _ <"
Combo_Detail.ListIndex = 0
End If
End Sub
Private Sub Command_Analyse_Click()
MsgBox "还没做好呢QAQ", , "> _ <"
End Sub
Private Sub Get_Data(file_name As String)
Dim temp As String
ReDim min_solutions(0)
ReDim farthest_cases(0)
ReDim solutions(0)
ReDim layers(0)
Open file_name For Input As #1
Line Input #1, temp: Line Input #1, temp
group_size = temp
Line Input #1, temp: Line Input #1, temp
min_steps = temp
Line Input #1, temp: Line Input #1, temp
farthest_steps = temp
Line Input #1, temp: Line Input #1, temp
While (temp <> "[Farthest_cases]")
ReDim Preserve min_solutions(UBound(min_solutions) + 1)
min_solutions(UBound(min_solutions)) = temp
Line Input #1, temp
Wend
Line Input #1, temp
While (temp <> "[Solutions]")
ReDim Preserve farthest_cases(UBound(farthest_cases) + 1)
farthest_cases(UBound(farthest_cases)) = temp
Line Input #1, temp
Wend
Line Input #1, temp
While (temp <> "[List]")
ReDim Preserve solutions(UBound(solutions) + 1)
solutions(UBound(solutions)) = temp
Line Input #1, temp
Wend
Line Input #1, temp
While (temp <> "[Layer]")
ReDim Preserve layers(UBound(layers) + 1)
layers(UBound(layers)) = temp
Line Input #1, temp
Wend
Close #1
Call split_layer
End Sub
Private Sub split_layer()
Dim i As Long, code As String, num As Integer, index As Integer
For i = 1 To UBound(layers)
code = Mid(layers(i), InStr(1, layers(i), ">") + 2, 7)
num = Mid(layers(i), InStr(1, layers(i), "(") + 1, InStr(1, layers(i), ",") - InStr(1, layers(i), "(") - 1)
index = Mid(layers(i), InStr(1, layers(i), ",") + 1, Len(layers(i)) - InStr(1, layers(i), ",") - 1)
ReDim Preserve layer(0 To num)
ReDim Preserve layer(num).layer_dat(0 To index)
layer(num).layer_dat(index) = code
layer(num).size = index + 1
Next i
End Sub
Private Sub Output_Graph()
Dim m, X, Y As Integer
Dim width As Integer, height As Integer
Print_Block start_x, start_y, square_width * 4 + gap * 5, square_width * 5 + gap * 6, case_line_width, case_color, case_line_color
For m = 0 To 9
If Block(m).address <> 25 Then
X = (Block(m).address Mod 4) * (square_width + gap) + gap + start_x
Y = Int(Block(m).address / 4) * (square_width + gap) + gap + start_y
If Block(m).style = 0 Or Block(m).style = 1 Then
width = square_width * 2 + gap
Else
width = square_width
End If
If Block(m).style = 0 Or Block(m).style = 2 Then
height = square_width * 2 + gap
Else
height = square_width
End If
Print_Block X, Y, width, height, block_line_width, block_color, block_line_color
End If
Next m
End Sub
Private Sub Print_Block(print_start_x, print_start_y, print_width, print_height, print_line_width, print_color, print_line_color)
If print_width < 0 Or print_height < 0 Then Exit Sub
FillStyle = 0
DrawWidth = print_line_width
FillColor = print_color
Line (print_start_x, print_start_y)-(print_start_x + print_width, print_start_y + print_height), print_color, B
Line (print_start_x, print_start_y)-(print_start_x + print_width, print_start_y + print_height), print_line_color, B
End Sub
Private Sub Analyse_Code(code As String)
On Error Resume Next
Dim temp(1 To 12) As Integer
Dim i, addr, style As Integer
Dim type_1, type_2, type_3 As Integer
Dim Table(0 To 19) As Integer
Dim num As Integer, b1 As Integer, b2 As Integer
Dim dat As String
For i = 1 To 6
dat = Mid(code, i + 1, 1)
If Asc(dat) >= 48 And Asc(dat) <= 57 Then num = Int(dat)
If Asc(dat) >= 65 And Asc(dat) <= 70 Then num = Asc(dat) - 55
b1 = num Mod 4
b2 = (num - b1) / 4 Mod 4
temp(i * 2 - 1) = b2
temp(i * 2) = b1
Next i
type_1 = 0: type_2 = 0: type_3 = 5
For i = 0 To 19
Table(i) = 69
Next i
For i = 0 To 9
Block(i).address = 69
Block(i).style = 69
Next i
dat = Left(code, 1)
If Asc(dat) >= 48 And Asc(dat) <= 57 Then num = Int(dat)
If Asc(dat) >= 65 And Asc(dat) <= 70 Then num = Asc(dat) - 55
Block(0).address = num
Block(0).style = 0
If Block(0).address > 14 Then GoTo err
Table(Block(0).address) = 0
Table(Block(0).address + 1) = 0
Table(Block(0).address + 4) = 0
Table(Block(0).address + 5) = 0
addr = 0
For i = 1 To 11
Do While Table(addr) <> 69
If addr < 19 Then
addr = addr + 1
Else
Exit Do
End If
Loop
style = temp(i)
If style = 0 Then
Table(addr) = 10
ElseIf style = 1 Then
If type_2 < 5 Then type_2 = type_2 + 1
If addr > 18 Then GoTo err
Block(type_2).style = 1
Block(type_2).address = addr
Table(addr) = type_2
Table(addr + 1) = type_2
ElseIf style = 2 Then
If type_2 < 5 Then type_2 = type_2 + 1
If addr > 15 Then GoTo err
Block(type_2).style = 2
Block(type_2).address = addr
Table(addr) = type_2
Table(addr + 4) = type_2
ElseIf style = 3 Then
If type_3 < 9 Then type_3 = type_3 + 1
Block(type_3).style = 3
Block(type_3).address = addr
Table(addr) = type_3
End If
Next i
err:
End Sub
Private Sub Timer_Debug_Timer()
Dim debug_dat As String
debug_dat = debug_dat & "group_size=" & group_size & vbCrLf
debug_dat = debug_dat & "min_steps=" & min_steps & vbCrLf
debug_dat = debug_dat & "farthest_steps=" & farthest_steps & vbCrLf
debug_dat = debug_dat & vbCrLf
debug_dat = debug_dat & "min_solutions->" & UBound(min_solutions) & vbCrLf
debug_dat = debug_dat & "farthest_cases->" & UBound(farthest_cases) & vbCrLf
debug_dat = debug_dat & "solutions->" & UBound(solutions) & vbCrLf
debug_dat = debug_dat & "layers->" & UBound(layers) & vbCrLf
debug_dat = debug_dat & "layer->" & UBound(layer) & vbCrLf
Text_Debug = debug_dat
End Sub

BIN
Form_Detail.frx

Binary file not shown.

13
Form_Game.frm

@ -2,7 +2,7 @@ VERSION 5.00
Begin VB.Form Form_Game
AutoRedraw = -1 'True
BorderStyle = 1 'Fixed Single
Caption = "HRD Game v1.7 by Dnomd343"
Caption = "HRD Game v1.8 by Dnomd343"
ClientHeight = 7305
ClientLeft = 45
ClientTop = 690
@ -14,6 +14,14 @@ Begin VB.Form Form_Game
ScaleHeight = 7305
ScaleWidth = 7290
StartUpPosition = 2 'ÆÁÄ»ÖÐÐÄ
Begin VB.CommandButton Command_Detail
Caption = "Ïêϸ½âÎö"
Height = 495
Left = 5760
TabIndex = 15
Top = 6360
Width = 1335
End
Begin VB.CommandButton Command_Prompt
Caption = "ÌáʾÏÂÒ»²½"
Height = 495
@ -319,6 +327,9 @@ End Sub
Private Sub Command_Solution_Click()
Form_Solution.Show 1
End Sub
Private Sub Command_Detail_Click()
Form_Detail.Show 1
End Sub
Private Sub Command_Add_Favourite_Click()
favourite_add_save = True
favourite_add_init_code = Label_Code

3
HRD_Game.vbp

@ -9,6 +9,7 @@ Form=Form_Favourite.frm
Form=Form_Favourite_Add.frm
Form=Form_Solution.frm
Form=Form_Wait.frm
Form=Form_Detail.frm
IconForm="Form_Game"
Startup="Form_Game"
HelpFile=""
@ -19,7 +20,7 @@ Name="HRD_Game"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=7
MinorVer=8
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0

3
HRD_Game.vbw

@ -1,9 +1,10 @@
Form_Game = 52, 52, 883, 479, , 26, 28, 857, 453, C
Module = 52, 52, 883, 479,
Form_Classic_Cases = 104, 104, 891, 531, Z, 104, 104, 937, 531, C
Form_Classic_Cases = 104, 104, 891, 531, , 104, 104, 937, 531, C
Form_Creator = 130, 130, 917, 557, , 104, 104, 891, 531, C
Form_Rand_Case = 78, 78, 855, 505, , 156, 156, 933, 583, C
Form_Favourite = 52, 52, 829, 479, , 26, 26, 803, 453, C
Form_Favourite_Add = 156, 156, 933, 583, , 182, 182, 959, 609, C
Form_Solution = 104, 104, 862, 531, , 0, 0, 758, 427, C
Form_Wait = 104, 104, 862, 531, , 78, 78, 836, 505, C
Form_Detail = 26, 26, 784, 453, , 78, 78, 836, 505, C

1
Module.bas

@ -5,6 +5,7 @@ Public Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal
Public Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hkey As Long) As Long
Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public Declare Function SHDeleteKey Lib "shlwapi.dll" Alias "SHDeleteKeyA" (ByVal hkey As Long, ByVal pszSubKey As String) As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long

Loading…
Cancel
Save