数回游戏的自动求解 金牌收录

程序简介

数回是一种逻辑解谜游戏,它规则简单,解题过程富有挑战性。游戏规则很简单。游戏目标是画线连接棋盘上的点形成一条唯一的回路,所画的线不能出现交叉或分枝的情况。棋盘中的数字代表其被多少条线段所包围。简单的数回可以出现在小学数学题里,复杂的异形数回也可以出现在最强大脑节目上。边长较大的题目更考验耐心和细心。

本程序是数回游戏的自动求解程序。测试素材的来源是数回网站,它生成的普通题目绝大部分是可以层层推理出来的,信息冗余的格子是空白,而不是单纯的把所有格子的数字都保留。数回的推理过程有点类似数独,都是线性的,0 格是线头,其他数字格是线索,唯一回路是辅助。

程序逻辑在初始化函数里:

  1. 量边,数清楚是几乘几的题目,根据边长放大题目方便识别。
  2. 识别,对放大后的题目每个格子进行数字识别。
  3. 解题,根据基本规则反复对符合条件的格子进行判断。

程序的主程序函数里初始化了图片地址,初始地址没有图片也问题也不大。

测试素材我自己测试都能解出来,基本可以满足在网站截图的题都能解,不过小概率会出现问题。需要强调的是有些题目可能因为种种原因没解出来,本质是数字识别错误,因为错一个格子就解不出来了。可能是:

  1. 截图问题,不要截到蓝边,还要把题目截全。
  2. 题目问题,该网站的普通题目有小概率多解,程序只能算到多解的重复部分,我测试百张图出现了一张。
  3. 程序问题,这种可以试一下把该题目作为初始图片地址让程序解。
  4. 其他图像识别问题,这就和阈值和放大比例有关了,在定位函数里面,不排除特殊情况需要调整放大比例,因为我也是不断调整才满足我的设备,固定比例也不会是最合适的比例应用到每次截图,目前应该是满足大部分情况的比例。
  5. 最最重要的是,待解的题目图片要和数据集的图片在同一目录下哈!即待解的题目图片要和 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;
}