数回游戏的自动求解
2025-4-13 ~ 2025-6-8
(0)
程序简介
数回是一种逻辑解谜游戏,它规则简单,解题过程富有挑战性。游戏规则很简单。游戏目标是画线连接棋盘上的点形成一条唯一的回路,所画的线不能出现交叉或分枝的情况。棋盘中的数字代表其被多少条线段所包围。简单的数回可以出现在小学数学题里,复杂的异形数回也可以出现在最强大脑节目上。边长较大的题目更考验耐心和细心。
本程序是数回游戏的自动求解程序。测试素材的来源是数回网站,它生成的普通题目绝大部分是可以层层推理出来的,信息冗余的格子是空白,而不是单纯的把所有格子的数字都保留。数回的推理过程有点类似数独,都是线性的,0 格是线头,其他数字格是线索,唯一回路是辅助。
程序逻辑在初始化函数里:
- 量边,数清楚是几乘几的题目,根据边长放大题目方便识别。
- 识别,对放大后的题目每个格子进行数字识别。
- 解题,根据基本规则反复对符合条件的格子进行判断。
程序的主程序函数里初始化了图片地址,初始地址没有图片也问题也不大。
测试素材我自己测试都能解出来,基本可以满足在网站截图的题都能解,不过小概率会出现问题。需要强调的是有些题目可能因为种种原因没解出来,本质是数字识别错误,因为错一个格子就解不出来了。可能是:
- 截图问题,不要截到蓝边,还要把题目截全。
- 题目问题,该网站的普通题目有小概率多解,程序只能算到多解的重复部分,我测试百张图出现了一张。
- 程序问题,这种可以试一下把该题目作为初始图片地址让程序解。
- 其他图像识别问题,这就和阈值和放大比例有关了,在定位函数里面,不排除特殊情况需要调整放大比例,因为我也是不断调整才满足我的设备,固定比例也不会是最合适的比例应用到每次截图,目前应该是满足大部分情况的比例。
- 最最重要的是,待解的题目图片要和数据集的图片在同一目录下哈!即待解的题目图片要和 p0~3 的图片在同一目录下哈!不然全识别成 3。
本程序是用来解网站的普通题目,截图保存题目,然后按图片按钮选择题目。15 乘 15、20 乘 20 的题目可以把墙关闭,方便观察。
有关链接
程序运行展示
完整源代码
////////////////////////////////////////
// 程序:数回游戏的自动求解
// 作者:Gary
// 编译环境:Visual C++ 2010,EasyX_20211109
// 编写日期:2025.4.19
# include <math.h>
# include <graphics.h>
# include <string>
static HWND hOut; // 画布
// 格子
struct Node1
{
int num_box; // 初始状态
int num_top, num_bottom, num_left, num_right; // 四格位置的值
int num_type; // 状态
};
Node1 box_start[40][40];
// 按钮
struct Node2
{
int posx1, posy1, posx2, posy2; // 坐标
LPTSTR text; // 文字
};
Node2 box_button[3];
// 定义一个类
class Gary
{
public:
void carry(); // 主进程
void initialization(); // 初始化
void move(); // 窗口主视角函数
void locate(int mod); // 定位函数
void solve(); // 解题函数
void recognize(); // 识别函数
void draw(); // 绘制函数
void test(int length, int wight, IMAGE* img_input, int x, int y); // 对照函数
int exit_carry; // 主循函数控制参数
int exit_move; // 开始界面控制参数
int num_length; // 图片长度
int num_height; // 图片宽度
int pot_x, pot_y; // 横、纵向点数
double posx_origin; // 左上点横坐标
double posy_origin; // 左上点纵坐标
double length_x; // 横向间隔
double length_y; // 纵向间隔
IMAGE* img_output; // 输出图像
IMAGE* img_temporary; // 临时图像
IMAGE* img_num; // 数字图像
ExMessage m; // 鼠标
TCHAR s[10]; // 字符串
TCHAR address_load[MAX_PATH]; // 加载地址
TCHAR address_save[MAX_PATH]; // 保存地址
int pic_num[300][300]; // 识别数字图像
IMAGE img[4]; // 对照数字图像
int threshold_locate; // 定位阈值
int threshold_mod; // 量点阈值
int threshold_recognize; // 识别阈值
int threshold_test; // 对照阈值
int diameter_x; // 文字横坐标偏移
int diameter_y; // 文字纵坐标偏移
int size_num; // 数字尺寸
int size_text; // 文字尺寸
};
static double pi = acos(-1.0); // 圆周率 π
// 绘制函数
void Gary::draw()
{
int i, j;
SetWorkingImage();
cleardevice();
// 绘制按钮
settextstyle(size_text, 0, _T("Consolas"));
setlinecolor(BLACK);
for(i = 0; i < 3; i++)
{
// 边框
rectangle(box_button[i].posx1, box_button[i].posy1, box_button[i].posx2, box_button[i].posy2);
outtextxy(box_button[i].posx1 + 17, box_button[i].posy1 + 13, box_button[i].text);
}
// 绘制数字
settextstyle(size_num, 0, _T("Consolas"));
setlinecolor(RED);
for(j = 0; j < pot_y; j++)
{
for(i = 0; i < pot_x; i++)
{
fillcircle(int(50 + double(i) * 500.0 / double(pot_x)), int(50 + double(j) * 500.0 / double(pot_y)), 5);
fillcircle(int(50 + double(i) * 500.0 / double(pot_x)), int(50 + double(j + 1) * 500.0 / double(pot_y)), 5);
fillcircle(int(50 + double(i + 1) * 500.0 / double(pot_x)), int(50 + double(j) * 500.0 / double(pot_y)), 5);
fillcircle(int(50 + double(i + 1) * 500.0 / double(pot_x)), int(50 + double(j + 1) * 500.0 / double(pot_y)), 5);
if(box_start[i + 1][j + 1].num_box < 4)
{
// 字体绘制
_stprintf_s(s, _T("%0d"), box_start[i + 1][j + 1].num_box);
outtextxy(int(50 + double(i) * 500.0 / double(pot_x) + diameter_x), int(50 + double(j) * 500.0 / double(pot_y) + diameter_y), s);
}
}
}
// 绘制答案
setlinestyle(PS_SOLID, 2);
for(j = 0; j < pot_y; j++)
{
for(i = 0; i < pot_x; i++)
{
// 画线
if(box_start[i + 1][j + 1].num_top == 2) { line(int(50 + double(i) * 500.0 / double(pot_x)), int(50 + double(j) * 500.0 / double(pot_y)), int(50 + double(i + 1) * 500.0 / double(pot_x)), int(50 + double(j) * 500.0 / double(pot_y))); }
if(box_start[i + 1][j + 1].num_bottom == 2) { line(int(50 + double(i) * 500.0 / double(pot_x)), int(50 + double(j + 1) * 500.0 / double(pot_y)), int(50 + double(i + 1) * 500.0 / double(pot_x)), int(50 + double(j + 1) * 500.0 / double(pot_y))); }
if(box_start[i + 1][j + 1].num_left == 2) { line(int(50 + double(i) * 500.0 / double(pot_x)), int(50 + double(j) * 500.0 / double(pot_y)), int(50 + double(i) * 500.0 / double(pot_x)), int(50 + double(j + 1) * 500.0 / double(pot_y))); }
if(box_start[i + 1][j + 1].num_right == 2) { line(int(50 + double(i + 1) * 500.0 / double(pot_x)), int(50 + double(j) * 500.0 / double(pot_y)), int(50 + double(i + 1) * 500.0 / double(pot_x)), int(50 + double(j + 1) * 500.0 / double(pot_y))); }
// 画墙
if(box_button[1].text == _T("墙开"))
{
if(box_start[i + 1][j + 1].num_top == 1) { circle(int(50 + double(i) * 500.0 / double(pot_x) + 500.0 / double(pot_x) / 2.0), int(50 + double(j) * 500.0 / double(pot_y)), 5); }
if(box_start[i + 1][j + 1].num_bottom == 1) { circle(int(50 + double(i) * 500.0 / double(pot_x) + 500.0 / double(pot_x) / 2.0), int(50 + double(j + 1) * 500.0 / double(pot_y)), 5); }
if(box_start[i + 1][j + 1].num_left == 1) { circle(int(50 + double(i) * 500.0 / double(pot_x)), int(50 + double(j) * 500.0 / double(pot_y) + 500.0 / double(pot_y) / 2.0), 5); }
if(box_start[i + 1][j + 1].num_right == 1) { circle(int(50 + double(i + 1) * 500.0 / double(pot_x)), int(50 + double(j) * 500.0 / double(pot_y) + 500.0 / double(pot_y) / 2.0), 5); }
}
}
}
setlinestyle(PS_SOLID, 1);
FlushBatchDraw();
}
// 初始化函数
void Gary::initialization()
{
int i;
// 初始大小,用于格子数
num_length = 600;
num_height = 600;
threshold_locate = 10;
threshold_mod = 50;
size_text = 29;
// 画板属性初始化
SetWorkingImage();
setbkcolor(WHITE);
setfillcolor(BLACK);
settextcolor(BLACK);
settextstyle(size_text, 0, _T("Consolas"));
cleardevice();
// 绘制界面
setlinecolor(BLACK);
for(i = 0; i < 3; i++)
{
// 边框
rectangle(box_button[i].posx1, box_button[i].posy1, box_button[i].posx2, box_button[i].posy2);
outtextxy(box_button[i].posx1 + 17, box_button[i].posy1 + 13, box_button[i].text);
}
setlinecolor(RED);
FlushBatchDraw();
// 量边
locate(1);
// 定位,裁剪,识别
locate(2);
// 解题
solve();
// 绘制
draw();
}
// 识别函数
void Gary::recognize()
{
int i, j, k, t;
// 上下左右
int top, bottom, left, right;
// 裁剪
for(j = 0; j < pot_y; j++)
{
for(i = 0; i < pot_x; i++)
{
// 初始中心点
top = int(posy_origin + double(j) * length_y + length_y / 2.0);
bottom = int(posy_origin + double(j) * length_y + length_y / 2.0);
left = int(posx_origin + double(i) * length_x + length_x / 2.0);
right = int(posx_origin + double(i) * length_x + length_x / 2.0);
// 裁剪
// 上
for(k = 0; k < length_x; k++)
{
// 有黑
if(int(RGBtoGRAY(getpixel(int(posx_origin + double(i) * length_x + k), top)) / 256 / 256) <= threshold_recognize)
{
top--;
k = 0;
}
}
// 下
for(k = 0; k < length_x; k++)
{
// 有黑
if(int(RGBtoGRAY(getpixel(int(posx_origin + double(i) * length_x + k), bottom)) / 256 / 256) <= threshold_recognize)
{
bottom++;
k = 0;
}
}
// 左
for(k = 0; k < length_x; k++)
{
// 有黑
if(int(RGBtoGRAY(getpixel(left, int(posy_origin + double(j) * length_y + k))) / 256 / 256) <= threshold_recognize)
{
left--;
k = 0;
}
}
// 右
for(k = 0; k < length_x; k++)
{
// 有黑
if(int(RGBtoGRAY(getpixel(right, int(posy_origin + double(j) * length_y + k))) / 256 / 256) <= threshold_recognize)
{
right++;
k = 0;
}
}
// 存储
for(k = 0; k < bottom - top + 1; k++)
{
for(t = 0; t < right - left + 1; t++)
{
pic_num[t][k] = RGBtoGRAY(getpixel(left + t, top + k)) / 256 / 256;
}
}
// 格子绘制
SetWorkingImage();
fillcircle(int(50 + double(i) * 500.0 / double(pot_x)), int(50 + double(j) * 500.0 / double(pot_y)), 5);
fillcircle(int(50 + double(i) * 500.0 / double(pot_x)), int(50 + double(j + 1) * 500.0 / double(pot_y)), 5);
fillcircle(int(50 + double(i + 1) * 500.0 / double(pot_x)), int(50 + double(j) * 500.0 / double(pot_y)), 5);
fillcircle(int(50 + double(i + 1) * 500.0 / double(pot_x)), int(50 + double(j + 1) * 500.0 / double(pot_y)), 5);
FlushBatchDraw();
SetWorkingImage(img_temporary);
// 识别
// 无数字
if(top == bottom || left == right)
{
box_start[i + 1][j + 1].num_box = 4;
box_start[i + 1][j + 1].num_type = 4;
}
// 有数字
else
{
img_num = new IMAGE(right - left + 1, bottom - top + 1);
// 初始化处理区域
SetWorkingImage(img_num);
setbkcolor(WHITE);
cleardevice();
// 绘制
for(k = 0; k < bottom - top + 1; k++)
{
for(t = 0; t < right - left + 1; t++)
{
putpixel(t, k, pic_num[t][k] * ( 256 * 256 + 256 + 1 ));
}
}
// 识别
test(right - left + 1, bottom - top + 1, img_num, i, j);
}
}
}
}
// 定位函数
void Gary::locate(int mod)
{
// 初始化处理区域
img_temporary = new IMAGE(num_length, num_height);
SetWorkingImage(img_temporary);
setbkcolor(WHITE);
cleardevice();
// 加载
loadimage(img_temporary, address_load, num_length, num_height);
// 图片显示
putimage(0, 0, img_temporary);
int k, t;
double radius, angle;
// 定位
COLORREF color;
// 左上
double angle_origin;
// 半径
for(radius = 1; ; radius++)
{
// 角度
for(angle_origin = 0; angle_origin < 90; angle_origin++)
{
color = getpixel(int(radius * sin(pi / 180.0 * angle_origin)), int(radius * cos(pi / 180.0 * angle_origin)));
if(int(RGBtoGRAY(color) / 256 / 256) < threshold_locate)
{
break;
}
}
if(int(RGBtoGRAY(color) / 256 / 256) < threshold_locate)
{
break;
}
}
posx_origin = radius * sin(pi / 180.0 * angle_origin);
posy_origin = radius * cos(pi / 180.0 * angle_origin);
// 偏移
double diameter_point;
for(diameter_point = 1; ; diameter_point++)
{
k = 0;
for(angle = 0; angle < 360; angle++)
{
color = getpixel(int(posx_origin + diameter_point * sin(pi / 180.0 * angle)), int(posy_origin + diameter_point * cos(pi / 180.0 * angle)));
if(int(RGBtoGRAY(color) / 256 / 256) < threshold_locate) { k++; }
}
if(k == 0) { break; }
}
// 修正
posx_origin = posx_origin + diameter_point / 2.0 * sin(pi / 180.0 * angle_origin);
posy_origin = posy_origin + diameter_point / 2.0 * cos(pi / 180.0 * angle_origin);
// 右下
double posx_end, posy_end, angle_end;
for(radius = 1; ; radius++)
{
for(angle_end = 0; angle_end < 90; angle_end++)
{
color = getpixel(int(num_length - radius * sin(pi / 180.0 * angle_end)), int(num_height - radius * cos(pi / 180.0 * angle_end)));
if(int(RGBtoGRAY(color) / 256 / 256) < threshold_locate)
{
break;
}
}
if(int(RGBtoGRAY(color) / 256 / 256) < threshold_locate)
{
break;
}
}
posx_end = num_length - radius * sin(pi / 180.0 * angle_end);
posy_end = num_height - radius * cos(pi / 180.0 * angle_end);
// 偏移
for(diameter_point = 1; ; diameter_point++)
{
k = 0;
for(angle = 0; angle < 360; angle++)
{
color = getpixel(int(posx_end + diameter_point * sin(pi / 180.0 * angle)), int(posy_end + diameter_point * cos(pi / 180.0 * angle)));
if(int(RGBtoGRAY(color) / 256 / 256) < threshold_locate) { k++; }
}
if(k == 0) { break; }
}
// 修正
posx_end = posx_end - diameter_point / 2.0 * sin(pi / 180.0 * angle_end);
posy_end = posy_end - diameter_point / 2.0 * cos(pi / 180.0 * angle_end);
// 量边
if(mod == 1)
{
t = 0;
for(k = int(posx_origin); k < posx_end; k++)
{
// 有黑
if(t % 2 == 1 && int(RGBtoGRAY(getpixel(k, int(posy_origin))) / 256 / 256) <= threshold_mod)
{
t++;
}
// 白
if(t % 2 == 0 && int(RGBtoGRAY(getpixel(k, int(posy_origin))) / 256 / 256) > threshold_mod)
{
t++;
}
}
pot_x = t / 2;
t = 0;
for(k = int(posy_origin); k < posy_end; k++)
{
// 有黑
if(t % 2 == 1 && int(RGBtoGRAY(getpixel(int(posx_origin), k)) / 256 / 256) <= threshold_mod)
{
t++;
}
// 白
if(t % 2 == 0 && int(RGBtoGRAY(getpixel(int(posx_origin), k)) / 256 / 256) > threshold_mod)
{
t++;
}
}
pot_y = t / 2;
// 根据边的大小放大图片和字体
// 出现错误多半是识别错误,需要调整放大的比例
SetWorkingImage();
if(pot_x == 5 && pot_y == 5)
{
num_length = 500;
num_height = 500;
size_num = 50;
threshold_locate = 10;
threshold_mod = 50;
threshold_recognize = 220;
threshold_test = 160;
diameter_x = 40;
diameter_y = 20;
}
else if(pot_x == 7 && pot_y == 7)
{
num_length = 1000;
num_height = 1000;
size_num = 40;
threshold_locate = 10;
threshold_mod = 50;
threshold_recognize = 200;
threshold_test = 160;
diameter_x = 30;
diameter_y = 15;
}
else if(pot_x == 10 && pot_y == 10)
{
num_length = 1500;
num_height = 1500;
size_num = 29;
threshold_locate = 10;
threshold_mod = 50;
threshold_recognize = 200;
threshold_test = 160;
diameter_x = 20;
diameter_y = 10;
}
else if(pot_x == 15 && pot_y == 15)
{
num_length = 2100;
num_height = 2100;
size_num = 21;
threshold_locate = 10;
threshold_mod = 50;
threshold_recognize = 200;
threshold_test = 160;
diameter_x = 11;
diameter_y = 5;
}
else if(pot_x == 20 && pot_y == 20)
{
num_length = 2600;
num_height = 2600;
size_num = 21;
threshold_locate = 10;
threshold_mod = 50;
threshold_recognize = 200;
threshold_test = 160;
diameter_x = 7;
diameter_y = 2;
}
settextstyle(size_num, 0, _T("Consolas"));
}
// 识别
else if(mod == 2)
{
length_x = ( posx_end - posx_origin ) / double(pot_x);
length_y = ( posy_end - posy_origin ) / double(pot_y);
// 裁剪并识别
recognize();
}
}
// 识别函数
void Gary::test(int length, int wight, IMAGE* img_input, int x, int y)
{
int box_length[5][1000];
int box_wight[5][1000];
// 对照组
loadimage(&img[0], _T("p0.JPG"), length, wight);
loadimage(&img[1], _T("p1.JPG"), length, wight);
loadimage(&img[2], _T("p2.JPG"), length, wight);
loadimage(&img[3], _T("p3.JPG"), length, wight);
int i, k, t;
double j;
// 初始化识别区域
img_num = new IMAGE(length, wight);
SetWorkingImage(img_num);
setbkcolor(WHITE);
cleardevice();
// 绘制
putimage(0, 0, img_input);
// 识别对象
i = 4;
// 初始化
for(k = 0; k < length; k++)
{
box_length[i][k] = 0;
}
for(t = 0; t < wight; t++)
{
box_wight[i][t] = 0;
}
// 记录
for(k = 0; k < length; k++)
{
for(t = 0; t < wight; t++)
{
if(int(RGBtoGRAY(getpixel(k, t)) / 256 / 256) <= threshold_test) { box_length[i][k]++; }
}
}
for(t = 0; t < wight; t++)
{
for(k = 0; k < length; k++)
{
if(int(RGBtoGRAY(getpixel(k, t)) / 256 / 256) <= threshold_test) { box_wight[i][t]++; }
}
}
// 对照组
for(i = 0; i < 4; i++)
{
// 绘制
putimage(0, 0, &img[i]);
// 初始化
for(k = 0; k < length; k++)
{
box_length[i][k] = 0;
}
for(t = 0; t < wight; t++)
{
box_wight[i][t] = 0;
}
// 记录
for(k = 0; k < length; k++)
{
for(t = 0; t < wight; t++)
{
if(int(RGBtoGRAY(getpixel(k, t)) / 256 / 256) <= threshold_test) { box_length[i][k]++; }
}
}
for(t = 0; t < wight; t++)
{
for(k = 0; k < length; k++)
{
if(int(RGBtoGRAY(getpixel(k, t)) / 256 / 256) <= threshold_test) { box_wight[i][t]++; }
}
}
}
// 比较
int a;
k = 0; t = 0xffffff;
for(i = 0; i < 4; i++)
{
j = 0;
for(a = 0; a < length; a++)
{
j += pow(double(box_length[i][a] - box_length[4][a]), 2);
}
for(a = 0; a < wight; a++)
{
j += pow(double(box_wight[i][a] - box_wight[4][a]), 2);
}
if(j <= t) { k = i; t = int(j); }
}
// 赋值
box_start[x + 1][y + 1].num_box = k;
box_start[x + 1][y + 1].num_type = k;
// 字体绘制
SetWorkingImage();
_stprintf_s(s, _T("%0d"), k);
outtextxy(int(50 + double(x) * 500.0 / double(pot_x) + diameter_x), int(50 + double(y) * 500.0 / double(pot_y) + diameter_y), s);
FlushBatchDraw();
SetWorkingImage(img_temporary);
}
// 解题
void Gary::solve()
{
int i, j, a, b, x, y, z, h1, h2;
int box_end[80][80]; // 回路测试,存储点与点之间的值
int box_num[3000]; // 回路测试,存储线
// 初始化:0 空、1 墙、2 线
for(j = 0; j < pot_y + 2; j++)
{
for(i = 0; i < pot_x + 2; i++)
{
// 角为 1111
if(( i == 0 || i == pot_x + 1 ) && ( j == 0 || j == pot_y + 1 ))
{
box_start[i][j].num_type = 5;
box_start[i][j].num_top = 1;
box_start[i][j].num_bottom = 1;
box_start[i][j].num_left = 1;
box_start[i][j].num_right = 1;
}
// 边为 0111
else if(i == 0 || i == pot_x + 1 || j == 0 || j == pot_y + 1)
{
box_start[i][j].num_type = 5;
box_start[i][j].num_top = 1;
box_start[i][j].num_bottom = 1;
box_start[i][j].num_left = 1;
box_start[i][j].num_right = 1;
if(i == 0) { box_start[i][j].num_right = 0; }
if(i == pot_x + 1) { box_start[i][j].num_left = 0; }
if(j == 0) { box_start[i][j].num_bottom = 0; }
if(j == pot_y + 1) { box_start[i][j].num_top = 0; }
}
// 中间为 0000
else
{
box_start[i][j].num_top = 0;
box_start[i][j].num_bottom = 0;
box_start[i][j].num_left = 0;
box_start[i][j].num_right = 0;
}
}
}
// 解题
int k = 0; // 结束循环检测
int time_solve = 0; // 循环次数
int num_box; // 回路测试,存储格子周边线、墙数
int num_line_box; // 回路测试,存储格子空位变更为线的方向数
int flag_x, flag_y; // 回路测试,存储点的坐标
while(k == 0 && time_solve < 2000)
{
k = 1; time_solve++;
// 中间的格子根据定式判断:0、1、2、3 为周边线数,4 为周边不确定线数、5 为边缘、6 为周边已全部确定
for(j = 1; j < pot_y + 1; j++)
{
for(i = 1; i < pot_x + 1; i++)
{
// 0 格
if(box_start[i][j].num_type == 0)
{
// 四周为墙
box_start[i][j].num_top = 1;
box_start[i][j].num_bottom = 1;
box_start[i][j].num_left = 1;
box_start[i][j].num_right = 1;
k = 0;
}
// 1 格
if(box_start[i][j].num_type == 1)
{
// 1|
// 已确定一边为线,则其余边为墙
if(box_start[i][j].num_top == 2) { box_start[i][j].num_bottom = 1; box_start[i][j].num_left = 1; box_start[i][j].num_right = 1; k = 0; }
if(box_start[i][j].num_bottom == 2) { box_start[i][j].num_top = 1; box_start[i][j].num_left = 1; box_start[i][j].num_right = 1; k = 0; }
if(box_start[i][j].num_left == 2) { box_start[i][j].num_bottom = 1; box_start[i][j].num_top = 1; box_start[i][j].num_right = 1; k = 0; }
if(box_start[i][j].num_right == 2) { box_start[i][j].num_bottom = 1; box_start[i][j].num_left = 1; box_start[i][j].num_top = 1; k = 0; }
// 1xxx
// 已确定三边为墙,则余边为线
if(box_start[i][j].num_top == 0 && box_start[i][j].num_bottom == 1 && box_start[i][j].num_left == 1 && box_start[i][j].num_right == 1) { box_start[i][j].num_top = 2; k = 0; }
if(box_start[i][j].num_top == 1 && box_start[i][j].num_bottom == 0 && box_start[i][j].num_left == 1 && box_start[i][j].num_right == 1) { box_start[i][j].num_bottom = 2; k = 0; }
if(box_start[i][j].num_top == 1 && box_start[i][j].num_bottom == 1 && box_start[i][j].num_left == 0 && box_start[i][j].num_right == 1) { box_start[i][j].num_left = 2; k = 0; }
if(box_start[i][j].num_top == 1 && box_start[i][j].num_bottom == 1 && box_start[i][j].num_left == 1 && box_start[i][j].num_right == 0) { box_start[i][j].num_right = 2; k = 0; }
}
// 2 格
if(box_start[i][j].num_type == 2)
{
// |2|
// 已确定两边为线,则其余边为墙
if(box_start[i][j].num_top == 2 && box_start[i][j].num_bottom == 2) { box_start[i][j].num_left = 1; box_start[i][j].num_right = 1; k = 0; }
if(box_start[i][j].num_top == 2 && box_start[i][j].num_left == 2) { box_start[i][j].num_bottom = 1; box_start[i][j].num_right = 1; k = 0; }
if(box_start[i][j].num_bottom == 2 && box_start[i][j].num_left == 2) { box_start[i][j].num_top = 1; box_start[i][j].num_right = 1; k = 0; }
if(box_start[i][j].num_top == 2 && box_start[i][j].num_right == 2) { box_start[i][j].num_bottom = 1; box_start[i][j].num_left = 1; k = 0; }
if(box_start[i][j].num_bottom == 2 && box_start[i][j].num_right == 2) { box_start[i][j].num_top = 1; box_start[i][j].num_left = 1; k = 0; }
if(box_start[i][j].num_left == 2 && box_start[i][j].num_right == 2) { box_start[i][j].num_top = 1; box_start[i][j].num_bottom = 1; k = 0; }
// x2x
// 已确定两边为墙,则其余边为线
if(box_start[i][j].num_top == 1 && box_start[i][j].num_bottom == 1) { box_start[i][j].num_left = 2; box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_top == 1 && box_start[i][j].num_left == 1) { box_start[i][j].num_bottom = 2; box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_bottom == 1 && box_start[i][j].num_left == 1) { box_start[i][j].num_top = 2; box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_top == 1 && box_start[i][j].num_right == 1) { box_start[i][j].num_bottom = 2; box_start[i][j].num_left = 2; k = 0; }
if(box_start[i][j].num_bottom == 1 && box_start[i][j].num_right == 1) { box_start[i][j].num_top = 2; box_start[i][j].num_left = 2; k = 0; }
if(box_start[i][j].num_left == 1 && box_start[i][j].num_right == 1) { box_start[i][j].num_top = 2; box_start[i][j].num_bottom = 2; k = 0; }
}
// 3 格
if(box_start[i][j].num_type == 3)
{
// 3x
// 已确定一边为墙,则其余边为线
if(box_start[i][j].num_top == 1) { box_start[i][j].num_bottom = 2; box_start[i][j].num_left = 2; box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_bottom == 1) { box_start[i][j].num_top = 2; box_start[i][j].num_left = 2; box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_left == 1) { box_start[i][j].num_bottom = 2; box_start[i][j].num_top = 2; box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_right == 1) { box_start[i][j].num_bottom = 2; box_start[i][j].num_left = 2; box_start[i][j].num_top = 2; k = 0; }
// 一些 3 的定式,不加也可以解
// 3xx
if(box_start[i + 1][j + 1].num_top == 1 && box_start[i + 1][j + 1].num_left == 1)
{
if(box_start[i][j].num_right == 0) { box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = 2; k = 0; }
}
if(box_start[i - 1][j + 1].num_top == 1 && box_start[i - 1][j + 1].num_right == 1)
{
if(box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = 2; k = 0; }
if(box_start[i][j].num_left == 0) { box_start[i][j].num_left = 2; k = 0; }
}
if(box_start[i + 1][j - 1].num_bottom == 1 && box_start[i + 1][j - 1].num_left == 1)
{
if(box_start[i][j].num_top == 0) { box_start[i][j].num_top = 2; k = 0; }
if(box_start[i][j].num_right == 0) { box_start[i][j].num_right = 2; k = 0; }
}
if(box_start[i - 1][j - 1].num_bottom == 1 && box_start[i - 1][j - 1].num_right == 1)
{
if(box_start[i][j].num_top == 0) { box_start[i][j].num_top = 2; k = 0; }
if(box_start[i][j].num_left == 0) { box_start[i][j].num_left = 2; k = 0; }
}
// |3|3|
if(box_start[i - 1][j].num_type == 3)
{
if(box_start[i][j].num_right == 0) { box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_left == 0) { box_start[i][j].num_left = 2; k = 0; }
if(box_start[i - 1][j].num_left == 0) { box_start[i - 1][j].num_left = 2; k = 0; }
}
if(box_start[i + 1][j].num_type == 3)
{
if(box_start[i][j].num_right == 0) { box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_left == 0) { box_start[i][j].num_left = 2; k = 0; }
if(box_start[i + 1][j].num_right == 0) { box_start[i + 1][j].num_right = 2; k = 0; }
}
if(box_start[i][j - 1].num_type == 3)
{
if(box_start[i][j].num_top == 0) { box_start[i][j].num_top = 2; k = 0; }
if(box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = 2; k = 0; }
if(box_start[i][j - 1].num_bottom == 0) { box_start[i][j - 1].num_bottom = 2; k = 0; }
}
if(box_start[i][j + 1].num_type == 3)
{
if(box_start[i][j].num_top == 0) { box_start[i][j].num_top = 2; k = 0; }
if(box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = 2; k = 0; }
if(box_start[i][j + 1].num_top == 0) { box_start[i][j + 1].num_top = 2; k = 0; }
}
// 3|
// |3
if(box_start[i - 1][j - 1].num_type == 3)
{
if(box_start[i][j].num_right == 0) { box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = 2; k = 0; }
if(box_start[i - 1][j - 1].num_left == 0) { box_start[i - 1][j - 1].num_left = 2; k = 0; }
if(box_start[i - 1][j - 1].num_top == 0) { box_start[i - 1][j - 1].num_top = 2; k = 0; }
}
if(box_start[i + 1][j - 1].num_type == 3)
{
if(box_start[i][j].num_left == 0) { box_start[i][j].num_left = 2; k = 0; }
if(box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = 2; k = 0; }
if(box_start[i + 1][j - 1].num_right == 0) { box_start[i + 1][j - 1].num_right = 2; k = 0; }
if(box_start[i + 1][j - 1].num_top == 0) { box_start[i + 1][j - 1].num_top = 2; k = 0; }
}
if(box_start[i - 1][j + 1].num_type == 3)
{
if(box_start[i][j].num_right == 0) { box_start[i][j].num_right = 2; k = 0; }
if(box_start[i][j].num_top == 0) { box_start[i][j].num_top = 2; k = 0; }
if(box_start[i - 1][j + 1].num_left == 0) { box_start[i - 1][j + 1].num_left = 2; k = 0; }
if(box_start[i - 1][j + 1].num_bottom == 0) { box_start[i - 1][j + 1].num_bottom = 2; k = 0; }
}
if(box_start[i + 1][j + 1].num_type == 3)
{
if(box_start[i][j].num_left == 0) { box_start[i][j].num_left = 2; k = 0; }
if(box_start[i][j].num_top == 0) { box_start[i][j].num_top = 2; k = 0; }
if(box_start[i + 1][j + 1].num_right == 0) { box_start[i + 1][j + 1].num_right = 2; k = 0; }
if(box_start[i + 1][j + 1].num_bottom == 0) { box_start[i + 1][j + 1].num_bottom = 2; k = 0; }
}
}
// 4 格(3 格)
if(box_start[i][j].num_type == 4 || box_start[i][j].num_type == 3)
{
// 已确定三边为线,则余边为墙
if(box_start[i][j].num_top == 0 && box_start[i][j].num_bottom == 2 && box_start[i][j].num_left == 2 && box_start[i][j].num_right == 2) { box_start[i][j].num_top = 1; k = 0; }
if(box_start[i][j].num_top == 2 && box_start[i][j].num_bottom == 0 && box_start[i][j].num_left == 2 && box_start[i][j].num_right == 2) { box_start[i][j].num_bottom = 1; k = 0; }
if(box_start[i][j].num_top == 2 && box_start[i][j].num_bottom == 2 && box_start[i][j].num_left == 0 && box_start[i][j].num_right == 2) { box_start[i][j].num_left = 1; k = 0; }
if(box_start[i][j].num_top == 2 && box_start[i][j].num_bottom == 2 && box_start[i][j].num_left == 2 && box_start[i][j].num_right == 0) { box_start[i][j].num_right = 1; k = 0; }
}
// all
// 5 格以外的格子
if(box_start[i][j].num_type != 5)
{
// 定式,一个点最多连两条线:当一个点已连接两条线,其余边为墙
// |_
// 两条线是某一格的临边
if(box_start[i][j].num_top == 2 && box_start[i][j].num_left == 2)
{
if(box_start[i - 1][j - 1].num_bottom == 0) { box_start[i - 1][j - 1].num_bottom = 1; k = 0; }
if(box_start[i - 1][j - 1].num_right == 0) { box_start[i - 1][j - 1].num_right = 1; k = 0; }
}
if(box_start[i][j].num_top == 2 && box_start[i][j].num_right == 2)
{
if(box_start[i + 1][j - 1].num_bottom == 0) { box_start[i + 1][j - 1].num_bottom = 1; k = 0; }
if(box_start[i + 1][j - 1].num_left == 0) { box_start[i + 1][j - 1].num_left = 1; k = 0; }
}
if(box_start[i][j].num_bottom == 2 && box_start[i][j].num_left == 2)
{
if(box_start[i - 1][j + 1].num_top == 0) { box_start[i - 1][j + 1].num_top = 1; k = 0; }
if(box_start[i - 1][j + 1].num_right == 0) { box_start[i - 1][j + 1].num_right = 1; k = 0; }
}
if(box_start[i][j].num_bottom == 2 && box_start[i][j].num_right == 2)
{
if(box_start[i + 1][j + 1].num_top == 0) { box_start[i + 1][j + 1].num_top = 1; k = 0; }
if(box_start[i + 1][j + 1].num_left == 0) { box_start[i + 1][j + 1].num_left = 1; k = 0; }
}
// _ _
// 两条线是连续两格的同边
if(box_start[i][j].num_top == 2 && box_start[i + 1][j].num_top == 2)
{
if(box_start[i][j].num_right == 0) { box_start[i][j].num_right = 1; k = 0; }
if(box_start[i][j - 1].num_right == 0) { box_start[i][j - 1].num_right = 1; k = 0; }
}
if(box_start[i][j].num_bottom == 2 && box_start[i + 1][j].num_bottom == 2)
{
if(box_start[i][j].num_right == 0) { box_start[i][j].num_right = 1; k = 0; }
if(box_start[i][j + 1].num_right == 0) { box_start[i][j + 1].num_right = 1; k = 0; }
}
if(box_start[i][j].num_right == 2 && box_start[i][j + 1].num_right == 2)
{
if(box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = 1; k = 0; }
if(box_start[i + 1][j].num_bottom == 0) { box_start[i + 1][j].num_bottom = 1; k = 0; }
}
if(box_start[i][j].num_left == 2 && box_start[i][j + 1].num_left == 2)
{
if(box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = 1; k = 0; }
if(box_start[i - 1][j].num_bottom == 0) { box_start[i - 1][j].num_bottom = 1; k = 0; }
}
// 定式,一个点不存在三面为墙,一面为线:当一个点已存在两面墙,加一条线/墙,则余边同时为线/墙
// x
// x
// 两面墙是某一格的临边
if(box_start[i][j].num_top == 1 && box_start[i][j].num_left == 1)
{
if(box_start[i - 1][j - 1].num_bottom != 0 && box_start[i - 1][j - 1].num_right == 0) { box_start[i - 1][j - 1].num_right = box_start[i - 1][j - 1].num_bottom; k = 0; }
else if(box_start[i - 1][j - 1].num_right != 0 && box_start[i - 1][j - 1].num_bottom == 0) { box_start[i - 1][j - 1].num_bottom = box_start[i - 1][j - 1].num_right; k = 0; }
}
if(box_start[i][j].num_top == 1 && box_start[i][j].num_right == 1)
{
if(box_start[i + 1][j - 1].num_bottom != 0 && box_start[i + 1][j - 1].num_left == 0) { box_start[i + 1][j - 1].num_left = box_start[i + 1][j - 1].num_bottom; k = 0; }
else if(box_start[i + 1][j - 1].num_left != 0 && box_start[i + 1][j - 1].num_bottom == 0) { box_start[i + 1][j - 1].num_bottom = box_start[i + 1][j - 1].num_left; k = 0; }
}
if(box_start[i][j].num_bottom == 1 && box_start[i][j].num_left == 1)
{
if(box_start[i - 1][j + 1].num_top != 0 && box_start[i - 1][j + 1].num_right == 0) { box_start[i - 1][j + 1].num_right = box_start[i - 1][j + 1].num_top; k = 0; }
else if(box_start[i - 1][j + 1].num_right != 0 && box_start[i - 1][j + 1].num_top == 0) { box_start[i - 1][j + 1].num_top = box_start[i - 1][j + 1].num_right; k = 0; }
}
if(box_start[i][j].num_bottom == 1 && box_start[i][j].num_right == 1)
{
if(box_start[i + 1][j + 1].num_top != 0 && box_start[i + 1][j + 1].num_left == 0) { box_start[i + 1][j + 1].num_left = box_start[i + 1][j + 1].num_top; k = 0; }
else if(box_start[i + 1][j + 1].num_left != 0 && box_start[i + 1][j + 1].num_top == 0) { box_start[i + 1][j + 1].num_top = box_start[i + 1][j + 1].num_left; k = 0; }
}
// 考虑边缘和角落的情况
if(box_start[i + 1][j + 1].num_top == 1 && box_start[i + 1][j + 1].num_left == 1)
{
if(box_start[i][j].num_bottom != 0 && box_start[i][j].num_right == 0) { box_start[i][j].num_right = box_start[i][j].num_bottom; k = 0; }
else if(box_start[i][j].num_right != 0 && box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = box_start[i][j].num_right; k = 0; }
}
if(box_start[i - 1][j + 1].num_top == 1 && box_start[i - 1][j + 1].num_right == 1)
{
if(box_start[i][j].num_bottom != 0 && box_start[i][j].num_left == 0) { box_start[i][j].num_left = box_start[i][j].num_bottom; k = 0; }
else if(box_start[i][j].num_left != 0 && box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = box_start[i][j].num_left; k = 0; }
}
if(box_start[i + 1][j - 1].num_bottom == 1 && box_start[i + 1][j - 1].num_left == 1)
{
if(box_start[i][j].num_top != 0 && box_start[i][j].num_right == 0) { box_start[i][j].num_right = box_start[i][j].num_top; k = 0; }
else if(box_start[i][j].num_right != 0 && box_start[i][j].num_top == 0) { box_start[i][j].num_top = box_start[i][j].num_right; k = 0; }
}
if(box_start[i - 1][j - 1].num_bottom == 1 && box_start[i - 1][j - 1].num_right == 1)
{
if(box_start[i][j].num_top != 0 && box_start[i][j].num_left == 0) { box_start[i][j].num_left = box_start[i][j].num_top; k = 0; }
else if(box_start[i][j].num_left != 0 && box_start[i][j].num_top == 0) { box_start[i][j].num_top = box_start[i][j].num_left; k = 0; }
}
// 两面墙是连续两格的同边,考虑边缘和角落的情况
// x x
if(box_start[i][j].num_top == 1 && box_start[i - 1][j].num_top == 1)
{
if(box_start[i][j].num_left != 0 && box_start[i][j - 1].num_left == 0) { box_start[i][j - 1].num_left = box_start[i][j].num_left; k = 0; }
else if(box_start[i][j - 1].num_left != 0 && box_start[i][j].num_left == 0) { box_start[i][j].num_left = box_start[i][j - 1].num_left; k = 0; }
}
if(box_start[i][j].num_top == 1 && box_start[i + 1][j].num_top == 1)
{
if(box_start[i][j].num_right != 0 && box_start[i][j - 1].num_right == 0) { box_start[i][j - 1].num_right = box_start[i][j].num_right; k = 0; }
else if(box_start[i][j - 1].num_right != 0 && box_start[i][j].num_right == 0) { box_start[i][j].num_right = box_start[i][j - 1].num_right; k = 0; }
}
//
if(box_start[i][j].num_bottom == 1 && box_start[i - 1][j].num_bottom == 1)
{
if(box_start[i][j].num_left != 0 && box_start[i][j + 1].num_left == 0) { box_start[i][j + 1].num_left = box_start[i][j].num_left; k = 0; }
else if(box_start[i][j + 1].num_left != 0 && box_start[i][j].num_left == 0) { box_start[i][j].num_left = box_start[i][j + 1].num_left; k = 0; }
}
if(box_start[i][j].num_bottom == 1 && box_start[i + 1][j].num_bottom == 1)
{
if(box_start[i][j].num_right != 0 && box_start[i][j + 1].num_right == 0) { box_start[i][j + 1].num_right = box_start[i][j].num_right; k = 0; }
else if(box_start[i][j + 1].num_right != 0 && box_start[i][j].num_right == 0) { box_start[i][j].num_right = box_start[i][j + 1].num_right; k = 0; }
}
//
if(box_start[i][j].num_left == 1 && box_start[i][j - 1].num_left == 1)
{
if(box_start[i][j].num_top != 0 && box_start[i - 1][j].num_top == 0) { box_start[i - 1][j].num_top = box_start[i][j].num_top; k = 0; }
else if(box_start[i - 1][j].num_top != 0 && box_start[i][j].num_top == 0) { box_start[i][j].num_top = box_start[i - 1][j].num_top; k = 0; }
}
if(box_start[i][j].num_left == 1 && box_start[i][j + 1].num_left == 1)
{
if(box_start[i][j].num_bottom != 0 && box_start[i - 1][j].num_bottom == 0) { box_start[i - 1][j].num_bottom = box_start[i][j].num_bottom; k = 0; }
else if(box_start[i - 1][j].num_bottom != 0 && box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = box_start[i - 1][j].num_bottom; k = 0; }
}
//
if(box_start[i][j].num_right == 1 && box_start[i][j - 1].num_right == 1)
{
if(box_start[i][j].num_top != 0 && box_start[i + 1][j].num_top == 0) { box_start[i + 1][j].num_top = box_start[i][j].num_top; k = 0; }
else if(box_start[i + 1][j].num_top != 0 && box_start[i][j].num_top == 0) { box_start[i][j].num_top = box_start[i + 1][j].num_top; k = 0; }
}
if(box_start[i][j].num_right == 1 && box_start[i][j + 1].num_right == 1)
{
if(box_start[i][j].num_bottom != 0 && box_start[i + 1][j].num_bottom == 0) { box_start[i + 1][j].num_bottom = box_start[i][j].num_bottom; k = 0; }
else if(box_start[i + 1][j].num_bottom != 0 && box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = box_start[i + 1][j].num_bottom; k = 0; }
}
}
}
}
// 回路判断,其他情况不能推进进度时进行回路判断
if(k == 1)
{
// 格子
for(j = 1; j < pot_y + 1; j++)
{
for(i = 1; i < pot_x + 1; i++)
{
// 4 格
if(box_start[i][j].num_type == 4)
{
// 已确定二边为线/墙,一边为墙/线,余边不确定,进行回路判断
num_box = 0;
if(box_start[i][j].num_top != 0) { num_box++; }
if(box_start[i][j].num_bottom != 0) { num_box++; }
if(box_start[i][j].num_left != 0) { num_box++; }
if(box_start[i][j].num_right != 0) { num_box++; }
if(num_box == 3)
{
// 有不确定格进行了判断
k = 0;
// 记录初始,并假设为线
if(box_start[i][j].num_top == 0) { box_start[i][j].num_top = 2; num_line_box = 1; }
if(box_start[i][j].num_bottom == 0) { box_start[i][j].num_bottom = 2; num_line_box = 2; }
if(box_start[i][j].num_left == 0) { box_start[i][j].num_left = 2; num_line_box = 3; }
if(box_start[i][j].num_right == 0) { box_start[i][j].num_right = 2; num_line_box = 4; }
// 初始化
for(b = 0; b < 80; b++)
{
for(a = 0; a < 80; a++)
{
box_end[a][b] = 0;
}
}
for(a = 0; a < 3000; a++)
{
box_num[a] = -1;
}
// 赋值
for(b = 1; b < pot_y + 1; b++)
{
for(a = 1; a < pot_x + 1; a++)
{
if(box_start[a][b].num_top == 2) { box_end[a][2 * b - 1] = 1; }
if(box_start[a][b].num_bottom == 2) { box_end[a][2 * b + 1] = 1; }
if(box_start[a][b].num_left == 2) { box_end[a - 1][2 * b] = 1; }
if(box_start[a][b].num_right == 2) { box_end[a][2 * b] = 1; }
}
}
// 记录
if(num_line_box == 1) { box_num[0] = i + ( 2 * j - 1 ) * 40; }
if(num_line_box == 2) { box_num[0] = i + ( 2 * j + 1 ) * 40; }
if(num_line_box == 3) { box_num[0] = i - 1 + ( 2 * j ) * 40; }
if(num_line_box == 4) { box_num[0] = i + ( 2 * j ) * 40; }
// 遍历
y = 1; x = 0;
while(x != y)
{
x = y;
// 找所有 box_num 连接的不重复线
for(z = 0; z < y; z++)
{
flag_x = box_num[z] % 40; flag_y = box_num[z] / 40;
// 横向
if(flag_y % 2 == 0)
{
if(box_end[flag_x][flag_y - 2] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x + ( flag_y - 2 ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x + ( flag_y - 2 ) * 40; y++; }
}
if(box_end[flag_x][flag_y - 1] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x + ( flag_y - 1 ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x + ( flag_y - 1 ) * 40; y++; }
}
if(box_end[flag_x][flag_y + 1] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x + ( flag_y + 1 ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x + ( flag_y + 1 ) * 40; y++; }
}
if(box_end[flag_x][flag_y + 2] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x + ( flag_y + 2 ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x + ( flag_y + 2 ) * 40; y++; }
}
if(box_end[flag_x + 1][flag_y + 1] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x + 1 + ( flag_y + 1 ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x + 1 + ( flag_y + 1 ) * 40; y++; }
}
if(box_end[flag_x + 1][flag_y - 1] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x + 1 + ( flag_y - 1 ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x + 1 + ( flag_y - 1 ) * 40; y++; }
}
}
// 纵向
if(flag_y % 2 == 1)
{
if(box_end[flag_x - 1][flag_y - 1] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x - 1 + ( flag_y - 1 ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x - 1 + ( flag_y - 1 ) * 40; y++; }
}
if(box_end[flag_x - 1][flag_y] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x - 1 + ( flag_y ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x - 1 + ( flag_y ) * 40; y++; }
}
if(box_end[flag_x - 1][flag_y + 1] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x - 1 + ( flag_y + 1 ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x - 1 + ( flag_y + 1 ) * 40; y++; }
}
if(box_end[flag_x][flag_y - 1] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x + ( flag_y - 1 ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x + ( flag_y - 1 ) * 40; y++; }
}
if(box_end[flag_x][flag_y + 1] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x + ( flag_y + 1 ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x + ( flag_y + 1 ) * 40; y++; }
}
if(box_end[flag_x + 1][flag_y] == 1)
{
h1 = 0; for(h2 = 0; h2 < y; h2++) { if(box_num[h2] == flag_x + 1 + ( flag_y ) * 40) { h1 = 1; break; } }
if(h1 == 0) { box_num[y] = flag_x + 1 + ( flag_y ) * 40; y++; }
}
}
}
}
// 找完后进行回路检测
h2 = 0;
// 遍历
for(a = 0; a < y; a++)
{
h1 = 0;
flag_x = box_num[a] % 40; flag_y = box_num[a] / 40;
// 横向
if(flag_y % 2 == 0)
{
if(box_end[flag_x][flag_y - 2] == 1) { h1++; }
if(box_end[flag_x][flag_y - 1] == 1) { h1++; }
if(box_end[flag_x][flag_y + 1] == 1) { h1++; }
if(box_end[flag_x][flag_y + 2] == 1) { h1++; }
if(box_end[flag_x + 1][flag_y + 1] == 1) { h1++; }
if(box_end[flag_x + 1][flag_y - 1] == 1) { h1++; }
}
// 纵向
if(flag_y % 2 == 1)
{
if(box_end[flag_x - 1][flag_y - 1] == 1) { h1++; }
if(box_end[flag_x - 1][flag_y] == 1) { h1++; }
if(box_end[flag_x - 1][flag_y + 1] == 1) { h1++; }
if(box_end[flag_x][flag_y - 1] == 1) { h1++; }
if(box_end[flag_x][flag_y + 1] == 1) { h1++; }
if(box_end[flag_x + 1][flag_y] == 1) { h1++; }
}
// 断路
if(h1 == 1) { h2 = 1; break; }
}
// 构成回路赋墙
if(h2 == 0 && y > 1)
{
if(num_line_box == 1) { box_start[i][j].num_top = 1; }
if(num_line_box == 2) { box_start[i][j].num_bottom = 1; }
if(num_line_box == 3) { box_start[i][j].num_left = 1; }
if(num_line_box == 4) { box_start[i][j].num_right = 1; }
}
// 不构成则不确定
else
{
if(num_line_box == 1) { box_start[i][j].num_top = 0; }
if(num_line_box == 2) { box_start[i][j].num_bottom = 0; }
if(num_line_box == 3) { box_start[i][j].num_left = 0; }
if(num_line_box == 4) { box_start[i][j].num_right = 0; }
}
}
}
}
}
}
// 不为空的边扩散,考虑边缘和角落的情况
for(j = 0; j < pot_y + 2; j++)
{
for(i = 0; i < pot_x + 2; i++)
{
if(i > 0 && box_start[i][j].num_left == 0 && box_start[i - 1][j].num_right != 0) { box_start[i][j].num_left = box_start[i - 1][j].num_right; }
if(i < 6 && box_start[i][j].num_right == 0 && box_start[i + 1][j].num_left != 0) { box_start[i][j].num_right = box_start[i + 1][j].num_left; }
if(j > 0 && box_start[i][j].num_top == 0 && box_start[i][j - 1].num_bottom != 0) { box_start[i][j].num_top = box_start[i][j - 1].num_bottom; }
if(j < 6 && box_start[i][j].num_bottom == 0 && box_start[i][j + 1].num_top != 0) { box_start[i][j].num_bottom = box_start[i][j + 1].num_top; }
//
if(i > 0 && box_start[i][j].num_left != 0 && box_start[i - 1][j].num_right == 0) { box_start[i - 1][j].num_right = box_start[i][j].num_left; }
if(i < 6 && box_start[i][j].num_right != 0 && box_start[i + 1][j].num_left == 0) { box_start[i + 1][j].num_left = box_start[i][j].num_right; }
if(j > 0 && box_start[i][j].num_top != 0 && box_start[i][j - 1].num_bottom == 0) { box_start[i][j - 1].num_bottom = box_start[i][j].num_top; }
if(j < 6 && box_start[i][j].num_bottom != 0 && box_start[i][j + 1].num_top == 0) { box_start[i][j + 1].num_top = box_start[i][j].num_bottom; }
// 四边都确定后修改状态
if(box_start[i][j].num_bottom != 0 && box_start[i][j].num_top != 0 && box_start[i][j].num_right != 0 && box_start[i][j].num_left != 0)
{
box_start[i][j].num_type = 6;
}
}
}
}
}
// 窗口主视角函数
void Gary::move()
{
int k;
// 主视角控量
exit_move = 0;
// 无尽模式
while(exit_move == 0)
{
if(peekmessage(&m, EM_MOUSE | EM_KEY))
{
// 左键单击判断
if(m.message == WM_LBUTTONDOWN)
{
for(k = 0; k < 3; k++)
{
// 矩形按钮
if(m.x > box_button[k].posx1 && m.y > box_button[k].posy1 && m.x < box_button[k].posx2 && m.y < box_button[k].posy2)
{
break;
}
}
switch(k)
{
// 新加载图片
case 0:
{
// 打开文件对话框
OPENFILENAME ofn;
// 保存文件完整路径
TCHAR szFileName[MAX_PATH] = { 0 };
// 设置过滤条件
TCHAR szFilter[] = TEXT("All Files (*.*)\0*.*\0\0");
ZeroMemory(&ofn, sizeof(ofn));
// 保存文件完整路径
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
// 保存文件名
ofn.lpstrFileTitle = address_load;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrFilter = szFilter;
// 默认扩展名
ofn.lpstrTitle = NULL;
ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
ofn.lStructSize = sizeof(OPENFILENAME);
// 拥有该对话框的窗口句柄
ofn.hwndOwner = hOut;
GetOpenFileName(&ofn);
// 结束
exit_move = 1;
break;
}
// 墙开关
case 1:
{
if(box_button[1].text == _T("墙开"))
{
box_button[1].text = _T("墙关");
}
else if(box_button[1].text == _T("墙关"))
{
box_button[1].text = _T("墙开");
}
draw();
break;
}
// 退出
case 2: { exit_move = 1; exit_carry = 1; break; }
default: break;
}
}
}
}
}
// 主进程
void Gary::carry()
{
// 窗口定义
hOut = initgraph(700, 600);
SetWindowText(hOut, _T("数回"));
// 初始图片地址
int i;
TCHAR s1[30] = _T("1.JPG");
for(i = 0; i < 30; i++) { address_load[i] = s1[i]; }
// 按钮初始化
box_button[0].posx1 = 580; box_button[0].posy1 = 100; box_button[0].posx2 = 670; box_button[0].posy2 = 150; box_button[0].text = _T("图片");
box_button[1].posx1 = 580; box_button[1].posy1 = 300; box_button[1].posx2 = 670; box_button[1].posy2 = 350; box_button[1].text = _T("墙开");
box_button[2].posx1 = 580; box_button[2].posy1 = 500; box_button[2].posx2 = 670; box_button[2].posy2 = 550; box_button[2].text = _T("退出");
// 进程控制
exit_carry = 0;
BeginBatchDraw();
while(exit_carry == 0)
{
initialization();
move();
}
EndBatchDraw();
closegraph();
}
// 主函数
int main(void)
{
Gary G;
G.carry();
return 0;
}