妙妙小豆子

胆子大一点,想开一点。长风破浪会有时,直挂云帆济沧海

宝石迷阵 银牌收录

程序简介

宝石迷阵,三消类游戏是十分经典的游戏。也是除了矩形,我设计了一个六边形格子。

这个程序没用图片素材,换成系统自带的字符映射表中的图案,省去了大量绘制棋子样式的时间。

玩法:选择相邻两个棋子,交换位置,若满足三消条件则消除,否则换回来。

平常的消消乐,它们也只是不规则棋盘,本质还是矩形,只有四个方向-上下左右,两类消除-横纵。我这个六边形是六个方向,三类消除。

第一次更新:主要是针对矩形棋盘的更新。
1. 点击棋子后,时间闪烁的 bug。
2. 下落功能的增加,还原了下落的游戏设定。
3. 连环消除功能的增加,这是增加了下落功能后的伴生功能。
4. 炸弹功能的增加,也包括引爆炸弹功能的增加,同色 5 个同时消除会生成一个引爆周边 1 格的炸弹。
5. 自动刷新功能的增加,如果出现无法消除的情况,现在会自动刷新,刷新前会有全屏闪烁的提醒,这个功能也包含在开局生成初始棋盘前。

第二次更新:
1. 图片更新,减小边框
2. 代码更新,现在兼容 vc2010,不兼容 vc6.0
vc2010:_stscanf_s,vc6.0:_stscanf
vc2010:_stprintf_s,vc6.0:_stprintf

程序运行展示

完整源代码

////////////////////////////////////////
// 程序:宝石迷阵
// 作者:Gary
// 编译环境:Visual C++ 2010,EasyX_20211109
// 编写日期:2020-7-13

////////////////////////////// 游戏进程头文件 //////////////////////////////

# include <math.h>
# include <graphics.h>
# include <string>
# include <time.h>
# include <stdlib.h>

// 头文件
// 头文件编译开始
#ifndef CIRCLE_H
#define CIRCLE_H

// 定义变量
static HWND hOut;					// 画布

// 定义一个结构体,格子
struct Node1
{
	int i, j, k;					// 矩形格子二维坐标,六边形格子三维坐标
	int boxnum;						// 格子编号
	int posx, posy;					// 物理坐标
	int type;						// 格子上棋子类型
};

// 定义一个结构体,临时存放格子
struct Node2
{
	int num;						// 编号
	int boxnum;						// 存放正式格子编号
};

// 定义一个结构体,按钮
struct Node3
{
	int posx1, posy1, posx2, posy2;	// 坐标
	double r;						// 圆按钮半径
	LPTSTR text;					// 按钮文本
	int type;						// 按钮激活状态
};

// 定义一个结构体,交换对
struct Node4
{
	int boxnum1;					// 交换对格子编号 1
	int boxnum2;					// 交换对格子编号 2
	int type;						// 交换对状态
};

// 定义一个类,game
class game
{
public:
	// 函数
	// 游戏进程源文件
	int carry_main ();												// 游戏进程主循函数
	void draw_button ();											// 按钮绘制函数
	void draw_piece (int posx, int posy, int type);					// 棋子绘制函数
	void draw_word (double size, int posx, int posy, LPTSTR text);	// 标题绘制函数
	int check_hexagon (int x, int y);								// 六边形判断函数
	int check_square (int x, int y);								// 矩形判断函数
	void check_bomb ();												// 炸弹判断函数
	void creact_piece (int boxnum);									// 生成棋子函数
	void carry_prepare ();											// 准备进程主循函数
	void initialization_prepare ();									// 准备进程初始化函数	
	void draw_scene_prepare ();										// 准备进程绘制函数
	void carry_start ();											// 开始进程主循函数
	void initialization_start ();									// 开始进程初始化函数
	void draw_scene_start ();										// 开始进程绘制函数

	Node1 box[1000];												// 格子,预制
	Node2 eat[500];													// 临时存放格子
	Node3 boxm[20];													// 按钮,预制二十个
	Node4 box_change[100];											// 交换对,预制一百个

	int num_button;													// 按钮数量
	int exit_carry;													// 主进程主循函数控制参数
	int exit_start;													// 开始进程主循函数控制参数
	int mod_shape;													// 棋盘模式参数,两种
	int mod_start;													// 游戏模式参数,三种
	int size_shape;													// 棋盘尺寸
	int flag;														// 临时存放格子数量参数
	int selected_boxnum;											// 选择格子参数
	int selected_or_not;											// 是否选择参数
	int start_endtime;												// 结束时间
	int start_point;												// 分数
	wchar_t c[10];													// 绘制棋子参数
	COLORREF color1[10], color2[10];									// 绘制棋子参数
	clock_t start_t1, start_t2;										// 时间参数
};

// 头文件编译结束
#endif



////////////////////////////// 主程序源文件 //////////////////////////////



// 窗口初始化
void initialization ()
{
	// 窗口定义,整个程序仅定义一次
	hOut = initgraph (601, 501);
	// 窗口标题
	SetWindowText (hOut, _T ("消消乐"));
}

// 总进程主循函数
void carry ()
{
	// 总进程参数初始化
	int exit_carry = 0;
	// 进程控制
	BeginBatchDraw ();
	// 创建游戏类对象
	game G;
	// 游戏进程
	while (exit_carry == 0)
	{
		// 执行游戏总进程,并接收游戏进程结束时返回值
		// 准备进程时,点击退出按钮结束返回 1
		// 开始进程时,点击返回按钮结束返回 0
		exit_carry = G.carry_main ();
	}
	EndBatchDraw ();
	// 关闭窗口
	closegraph ();
}

// 主函数
int main (void)
{
	// 初始化
	initialization ();
	// 总进程主循函数
	carry ();
	return 0;
}



////////////////////////////// 游戏进程源文件 //////////////////////////////



// 游戏进程主循函数
int game::carry_main ()
{
	// 游戏进程参数初始化
	exit_carry = 0;
	// 随机种子初始化
	srand ((unsigned)time (NULL));
	// 准备进程初始化函数
	initialization_prepare ();
	// 准备进程主循函数
	carry_prepare ();
	// 准备进程结束
	// 准备进程时,点击退出按钮结束,游戏进程参数为 1
	// 准备进程时,正常进入游戏,游戏进程参数为 0
	if (exit_carry == 0)
	{
		// 开始进程初始化函数
		initialization_start ();
		// 开始进程主循函数
		carry_start ();
	}
	// 开始进程结束
	// 点击返回按钮结束,或者正常游戏结束,游戏进程参数不变
	return exit_carry;
}

// 按钮绘制函数
void game::draw_button ()
{
	// 根据颜色结构体设置参数
	setlinecolor (RGB (125, 125, 125));
	setfillcolor (RGB (88, 88, 88));
	setbkcolor (RGB (88, 88, 88));
	settextcolor (RGB (250, 250, 250));
	settextstyle (30, 15, _T ("Consolas"));
	setlinestyle (PS_SOLID, 10);

	// 根据按钮数量参数绘制
	for (int i = 0; i < num_button; i++)
	{
		if (boxm[i].type == 0)
		{
			// 边框
			fillroundrect (boxm[i].posx1, boxm[i].posy1, boxm[i].posx2, boxm[i].posy2, 25, 25);
			// 文字
			outtextxy (boxm[i].posx1 + (boxm[i].posx2 - boxm[i].posx1) / 2 - textwidth (boxm[i].text) / 2, boxm[i].posy1 + 15, boxm[i].text);
		}
	}
	FlushBatchDraw ();
}

// 生成新棋子函数
void game::creact_piece (int boxnum)
{
	box[boxnum].type = rand () % 7 + 1;
}

// 棋子绘制函数
void game::draw_piece (int posx, int posy, int type)
{
	int i;
	setlinestyle (PS_SOLID, 1);
	setlinecolor (RGB (238, 224, 253));
	setfillcolor (RGB (217, 200, 248));

	// 根据棋盘模式,画不同的格子
	if (mod_shape == 0) { fillrectangle (posx, posy, posx + 50, posy + 50); }
	else if (mod_shape == 1) { fillcircle (posx + 25, posy + 25, 25); }

	if (type > 0)
	{
		// 绘制参数
		settextstyle (60, 50, _T ("Wingdings"));
		setbkmode (TRANSPARENT);

		// 阴影
		settextcolor (RGB (106, 93, 118));
		for (i = 0; i < 3; i++) { outtextxy (posx, posy - i, c[type]); }

		// 侧面
		settextcolor (color1[type]);
		for (i = 3; i < 6; i++) { outtextxy (posx, posy - i, c[type]); }

		// 正面
		settextcolor (color2[type]);
		for (i = 6; i < 7; i++) { outtextxy (posx, posy - i, c[type]); }

		// 恢复填充
		setbkmode (OPAQUE);
	}
}

// 矩形判断函数
int game::check_square (int x, int y)
{
	int j, flag1, flag2;
	flag1 = 0; flag2 = 0;

	// 左右记录参数
	flag1 = 0;

	// 向左
	j = x;
	while (j % 10 > 0)
	{
		j--;
		// 移动后格子上的棋子与被分析格子上的棋子类型一致,则记录
		if (box[j].type == y) { eat[flag + flag1].boxnum = j; flag1++; }
		// 否则直接退出
		else { break; }
	}

	// 向右
	j = x;
	while (j % 10 < size_shape)
	{
		j++;
		// 移动后格子上的棋子与被分析格子上的棋子类型一致,则记录
		if (box[j].type == y) { eat[flag + flag1].boxnum = j; flag1++; }
		// 否则直接退出
		else { break; }
	}

	if (flag1 >= 2 || mod_start == 1) {}
	// 左右判断少于两个,则无法消除,清空临时存储
	else { flag1 = 0; }

	// 上下记录参数
	flag2 = 0;

	// 向上
	j = x;
	while (j / 10 > 0)
	{
		j -= 10;
		// 移动后格子上的棋子与被分析格子上的棋子类型一致,则记录
		if (box[j].type == y) { eat[flag + flag1 + flag2].boxnum = j; flag2++; }
		// 否则直接退出
		else { break; }
	}

	// 向下
	j = x;
	while (j / 10 < size_shape)
	{
		j += 10;
		// 移动后格子上的棋子与被分析格子上的棋子类型一致,则记录
		if (box[j].type == y) { eat[flag + flag1 + flag2].boxnum = j; flag2++; }
		// 否则直接退出
		else { break; }
	}

	if (flag2 >= 2 || mod_start == 1) {}
	// 上下判断少于两个,则无法消除,清空临时存储
	else { flag2 = 0; }

	flag += (flag1 + flag2);
	return flag1 + flag2;
}

// 六边形判断函数
int game::check_hexagon (int x, int y)
{

	int i, j, k, t, flag1, flag2, flag3;
	flag1 = 0; flag2 = 0; flag3 = 0;

	// 正上正下记录参数
	flag1 = 0;

	// 向正上
	i = box[x].boxnum % 10; j = (box[x].boxnum / 10) % 10; k = box[x].boxnum / 100;
	while (i < size_shape)
	{
		// 向正上移动
		if (j > 0 && k > 0) { j--; k--; }
		else { i++; }t = i + j * 10 + k * 100;
		// 移动后格子上的棋子与被分析格子上的棋子类型一致,则记录
		if (box[t].type == y) { eat[flag + flag1].boxnum = t; flag1++; }
		// 否则直接退出
		else { break; }
	}

	// 向正下
	i = box[x].boxnum % 10; j = (box[x].boxnum / 10) % 10; k = box[x].boxnum / 100;
	while ((j < size_shape && k < size_shape) || i != 0)
	{
		// 向正下移动
		if (i > 0) { i--; }
		else { j++; k++; }t = i + j * 10 + k * 100;
		// 移动后格子上的棋子与被分析格子上的棋子类型一致,则记录
		if (box[t].type == y) { eat[flag + flag1].boxnum = t; flag1++; }
		// 否则直接退出
		else { break; }
	}

	if (flag1 >= 2 || mod_start == 1) {}
	// 正上正下判断少于两个,则无法消除,清空临时存储
	else { flag1 = 0; }

	// 左上右下记录参数
	flag2 = 0;

	// 向左上
	i = box[x].boxnum % 10; j = (box[x].boxnum / 10) % 10; k = box[x].boxnum / 100;
	while ((i < size_shape && k < size_shape) || j != 0)
	{
		// 向左上移动
		if (j > 0) { j--; }
		else { i++; k++; }t = i + j * 10 + k * 100;
		// 移动后格子上的棋子与被分析格子上的棋子类型一致,则记录
		if (box[t].type == y) { eat[flag + flag1 + flag2].boxnum = t; flag2++; }
		// 否则直接退出
		else { break; }
	}

	// 向右下
	i = box[x].boxnum % 10; j = (box[x].boxnum / 10) % 10; k = box[x].boxnum / 100;
	while (j < size_shape)
	{
		// 向右下移动
		if (i > 0 && k > 0) { i--; k--; }
		else { j++; }t = i + j * 10 + k * 100;
		// 移动后格子上的棋子与被分析格子上的棋子类型一致,则记录
		if (box[t].type == y) { eat[flag + flag1 + flag2].boxnum = t; flag2++; }
		// 否则直接退出
		else { break; }
	}

	if (flag2 >= 2 || mod_start == 1) {}
	// 左上右下判断少于两个,则无法消除,清空临时存储
	else { flag2 = 0; }

	// 右上左下记录参数
	flag3 = 0;

	// 向右上
	i = box[x].boxnum % 10; j = (box[x].boxnum / 10) % 10; k = box[x].boxnum / 100;
	while ((i < size_shape && j < size_shape) || k != 0)
	{
		// 向右上移动
		if (k > 0) { k--; }
		else { i++; j++; }t = i + j * 10 + k * 100;
		// 移动后格子上的棋子与被分析格子上的棋子类型一致,则记录
		if (box[t].type == y) { eat[flag + flag1 + flag2 + flag3].boxnum = t; flag3++; }
		// 否则直接退出
		else { break; }
	}

	// 向左下
	i = box[x].boxnum % 10; j = (box[x].boxnum / 10) % 10; k = box[x].boxnum / 100;
	while (k < size_shape)
	{
		// 向左下移动
		if (i > 0 && j > 0) { i--; j--; }
		else { k++; }t = i + j * 10 + k * 100;
		// 移动后格子上的棋子与被分析格子上的棋子类型一致,则记录
		if (box[t].type == y) { eat[flag + flag1 + flag2 + flag3].boxnum = t; flag3++; }
		// 否则直接退出
		else { break; }
	}

	if (flag3 >= 2 || mod_start == 1) {}
	// 右上左下判断少于两个,则无法消除,清空临时存储
	else { flag3 = 0; }

	flag += (flag1 + flag2 + flag3);
	return flag1 + flag2 + flag3;
}

// 炸弹判断函数
void game::check_bomb ()
{
	int i, j, k, t;
	// 范围判断
	for (t = 0; t < flag; t++)
	{
		// 如果原范围内有别的炸弹,加大范围,连环引爆
		if (box[eat[t].boxnum].type == 8)
		{
			// 炸弹自己炸没了
			box[eat[t].boxnum].type = 0;
			// 九宫格判断
			for (i = (box[eat[t].boxnum].i == 0 ? box[eat[t].boxnum].i : box[eat[t].boxnum].i - 1);
				i <= (box[eat[t].boxnum].i == size_shape - 1 ? box[eat[t].boxnum].i : box[eat[t].boxnum].i + 1);
				i++)
			{
				for (j = (box[eat[t].boxnum].j == 0 ? box[eat[t].boxnum].j : box[eat[t].boxnum].j - 1);
					j <= (box[eat[t].boxnum].j == size_shape - 1 ? box[eat[t].boxnum].j : box[eat[t].boxnum].j + 1);
					j++)
				{
					k = i * 10 + j;
					eat[flag].boxnum = k;
					if (box[k].type == 8) {}
					else { box[k].type = 0; }
					flag++;
				}
			}
		}
	}
}


////////////////////////////// 准备进程源文件 //////////////////////////////



// 准备进程主循函数
void game::carry_prepare ()
{
	int i;
	// 鼠标定义
	ExMessage m;
	// 准备进程控制参数初始化
	int	exit_prepare = 0;
	// 绘制界面
	draw_scene_prepare ();
	// 主循开始
	while (exit_prepare == 0)
	{
		if (peekmessage (&m, EM_MOUSE | EM_KEY))
		{
			// 左键单击判断
			if (m.message == WM_LBUTTONDOWN)
			{
				// 判断是否点击了按钮,按钮状态是否为激活
				for (i = 0; i < num_button; i++)
				{
					if (m.x > boxm[i].posx1 && m.y > boxm[i].posy1 && m.x < boxm[i].posx2 && m.y < boxm[i].posy2 && boxm[i].type == 0)
					{
						break;
					}
				}

				// 游戏类型按钮
				if (i == 0 || i == 1 || i == 2)
				{
					// 进入选择游戏模式界面
					// 按钮激活状态变更
					boxm[0].type = 1;
					boxm[1].type = 1;
					boxm[2].type = 1;
					boxm[3].type = 1;
					boxm[4].type = 0;
					boxm[5].type = 0;
					boxm[6].type = 0;
					// 开始进程控制参数为 0,进入普通模式
					exit_start = 0;
					// 游戏类型参数更新
					// 0 是宝石迷阵,1 是四消水果,2 是推拉英雄
					mod_start = i;
				}
				// 退出按钮
				else if (i == 3)
				{
					// 总进程控制参数置一,跳过开始进程
					exit_carry = 1;
					// 准备进程控制参数置一,结束主循
					exit_prepare = 1;
				}
				// 棋盘类型按钮
				else if (i == 4 || i == 5)
				{
					// 棋盘类型参数更新
					// 0 是矩形,1 是六边形
					mod_shape = i - 4;
					// 棋盘尺寸默认为:矩形 6,六边形 5
					if (i == 4) { size_shape = 6; }
					else if (i == 5) { size_shape = 4; }
					// 准备进程控制参数置一,结束主循,开始游戏
					exit_prepare = 1;
				}
				// 后退按钮
				else if (i == 6)
				{
					// 从主题选择界面返回
					// 按钮激活状态变更
					boxm[0].type = 0;
					boxm[1].type = 1;
					boxm[2].type = 1;
					boxm[3].type = 0;
					boxm[4].type = 1;
					boxm[5].type = 1;
					boxm[6].type = 1;
				}

				if (i < 10 && exit_prepare == 0)
				{
					// 点击按钮后,根据按钮激活参数,重新绘制界面
					draw_scene_prepare ();
					FlushBatchDraw ();
				}
			}
		}
	}
}

// 准备进程初始化函数	
void game::initialization_prepare ()
{
	// 按钮设置初始化
	// 按钮数量参数初始化
	num_button = 7;

	// 按钮结构体参数初始化
	boxm[0].posx1 = 200; boxm[0].posy1 = 120; boxm[0].posx2 = 400; boxm[0].posy2 = 180; boxm[0].text = _T ("宝石迷阵"); boxm[0].type = 0;
	boxm[1].posx1 = 200; boxm[1].posy1 = 220; boxm[1].posx2 = 400; boxm[1].posy2 = 280; boxm[1].text = _T ("四消水果"); boxm[1].type = 1;
	boxm[2].posx1 = 200; boxm[2].posy1 = 320; boxm[2].posx2 = 400; boxm[2].posy2 = 380; boxm[2].text = _T ("推拉消除");	boxm[2].type = 1;
	boxm[3].posx1 = 200; boxm[3].posy1 = 420; boxm[3].posx2 = 400; boxm[3].posy2 = 480; boxm[3].text = _T ("退出");		boxm[3].type = 0;

	boxm[4].posx1 = 200; boxm[4].posy1 = 120; boxm[4].posx2 = 400; boxm[4].posy2 = 180; boxm[4].text = _T ("矩形");		boxm[4].type = 1;
	boxm[5].posx1 = 200; boxm[5].posy1 = 220; boxm[5].posx2 = 400; boxm[5].posy2 = 280; boxm[5].text = _T ("六边形");	boxm[5].type = 1;
	boxm[6].posx1 = 200; boxm[6].posy1 = 420; boxm[6].posx2 = 400; boxm[6].posy2 = 480; boxm[6].text = _T ("后退");		boxm[6].type = 1;

	// 棋子初始化
	c[1] = 0xA3;	// 空心圆
	c[2] = 0xAA;	// 四角星
	c[3] = 0xAB;	// 五角星
	c[4] = 0xAC;	// 六角星
	c[5] = 0xAD;	// 八角星
	c[6] = 0xA9;	// 三角星
	c[7] = 0xAE;	// 星星
	c[8] = 0x4D;	// 炸弹

	color1[1] = RGB (57, 130, 206);
	color1[2] = RGB (210, 71, 38);
	color1[3] = RGB (79, 161, 52);
	color1[4] = RGB (225, 149, 52);
	color1[5] = RGB (180, 46, 134);
	color1[6] = RGB (151, 30, 19);
	color1[7] = RGB (152, 39, 196);
	color1[8] = RGB (200, 200, 200);

	color2[1] = RGB (102, 189, 244);
	color2[2] = RGB (239, 151, 63);
	color2[3] = RGB (120, 228, 80);
	color2[4] = RGB (248, 220, 80);
	color2[5] = RGB (236, 139, 209);
	color2[6] = RGB (236, 109, 53);
	color2[7] = RGB (235, 103, 244);
	color2[8] = BLACK;
	// 得分
	start_point = 0;

	// 矩形交换对初始化
	int i, j, k, h, t1, t2, a;
	for (i = 0; i < 100; i++)
	{
		box_change[i].type = 0;
	}
	a = 0;
	size_shape = 6;

	// 二维参数定义
	for (i = 0; i < size_shape; i++)
	{
		for (j = 0; j < size_shape; j++)
		{
			t1 = i * 10 + j;
			for (k = i; k < size_shape; k++)
			{
				for (h = j; h < size_shape; h++)
				{
					t2 = k * 10 + h;
					// 交换对是否成立
					if (t1 == t2 - 1 || t1 == t2 + 1 || t1 == t2 - 10 || t1 == t2 + 10)
					{
						box_change[a].boxnum1 = t1;
						box_change[a].boxnum2 = t2;
						box_change[a].type = 1;
						a++;
					}
				}
			}
		}
	}

}

// 准备进程绘制函数
void game::draw_scene_prepare ()
{
	// 画布绘制
	setbkcolor (WHITE);
	cleardevice ();
	// 按钮绘制
	draw_button ();
	// 标题绘制
	draw_word (50, 230, 20, _T ("宝石迷阵"));
	FlushBatchDraw ();
}

// 文字绘制函数
void game::draw_word (double size, int posx, int posy, LPTSTR text)
{
	int i, j;

	// 参数设置,填充透明
	setbkmode (TRANSPARENT);
	settextstyle (int (size), int (size / 5 * 2), _T ("Consolas"));

	// 背景色的反色
	settextcolor (BLACK);
	// 范围绘制,构造阴影
	for (i = posx - 3; i <= posx + 3; i++)
	{
		for (j = posy - 3; j <= posy + 3; j++)
		{
			outtextxy (i, j, text);
		}
	}

	// 背景色
	settextcolor (WHITE);
	// 在阴影中绘制
	outtextxy (posx, posy, text);

	// 恢复填充
	setbkmode (OPAQUE);
	FlushBatchDraw ();
}



////////////////////////////// 开始进程源文件 //////////////////////////////



// 开始进程主循函数
void game::carry_start ()
{
	// 鼠标定义
	ExMessage m;
	int i, j, k, t, x[100], h, y, z[100];
	// 时间初始化
	start_t1 = clock ();
	start_t2 = clock ();
	// 结束时间初始化
	start_endtime = 30000;
	// 绘制
	draw_scene_start ();
	// 普通模式
	while (exit_start == 0)
	{
		if (peekmessage (&m, EM_MOUSE | EM_KEY))
		{
			// 左键单击判断
			if (m.message == WM_LBUTTONDOWN)
			{
				// 单击在棋盘范围
				if (m.x < 500 && m.x > 0 && m.y > 0 && m.y < 500)
				{
					// 判断是否点击了格子,有效的格子
					for (i = 0; i < 1000; i++)
					{
						// 矩形
						if (box[i].type != -1 && m.x > box[i].posx && m.y > box[i].posy && m.x < box[i].posx + 50 && m.y < box[i].posy + 50 && mod_shape == 0)
						{
							break;
						}
						// 六边形
						else if (box[i].type != -1 && pow (double (m.x - box[i].posx - 25), 2) + pow (double (m.y - box[i].posy - 25), 2) < 626 && mod_shape == 1)
						{
							break;
						}
					}
					// 选择参数为 0,则表示选择
					if (selected_or_not == 0 && i < 1000 && box[i].type != 0)
					{
						selected_or_not = 1;
						selected_boxnum = i;
						// 选择绘制
						k = selected_boxnum;
						setfillstyle (BS_NULL);
						setlinestyle (PS_SOLID, 2);
						setlinecolor (LIGHTRED);
						// 矩形
						if (mod_shape == 0)
						{
							fillrectangle (box[k].posx + 1, box[k].posy + 1, box[k].posx + 49, box[k].posy + 49);

						}
						// 六边形
						else if (mod_shape == 1)
						{
							fillcircle (box[k].posx + 25, box[k].posy + 25, 23);
						}
						setfillstyle (BS_SOLID);
						FlushBatchDraw ();
					}
					// 选择参数为 1,则根据不同模式的规则进行下一步
					else if (selected_or_not == 1 && i < 1000 && box[i].type != 0)
					{
						selected_or_not = 0;
						// 宝石迷阵
						if (mod_start == 0)
						{
							// 点击同一个格子,表示取消选择
							if (selected_boxnum == i && box[i].type != 8) {}
							// 双击炸弹,或与炸弹交换位置
							else if (box[i].type == 8 || box[selected_boxnum].type == 8)
							{
								// 交换参数
								j = box[selected_boxnum].type;
								box[selected_boxnum].type = box[i].type;
								box[i].type = j;
								// 引爆
								flag = 1;
								// 起爆点
								if (box[i].type == 8) { eat[0].boxnum = i; }
								else if (box[selected_boxnum].type == 8) { eat[0].boxnum = selected_boxnum; }
								// 爆炸判断,确认爆炸范围
								check_bomb ();
								// 爆炸
								for (j = 0; j < 3; j++)
								{
									for (k = 0; k < flag; k++) { draw_piece (box[eat[k].boxnum].posx, box[eat[k].boxnum].posy, 0); }
									FlushBatchDraw ();
									Sleep (200);
									for (k = 0; k < flag; k++) { draw_piece (box[eat[k].boxnum].posx, box[eat[k].boxnum].posy, 8); }
									FlushBatchDraw ();
									Sleep (350);
								}
								// 时间奖励
								start_endtime += 3500;
								// 得分奖励
								start_point += (flag + 1);
								goto A;
							}
							// 点击相邻格子,表示交换
							else if (pow (double (box[selected_boxnum].posx - box[i].posx), 2) + pow (double (box[selected_boxnum].posy - box[i].posy), 2) <= 2501)
							{
								// 交换参数
								j = box[selected_boxnum].type;
								box[selected_boxnum].type = box[i].type;
								box[i].type = j;

								// 闪烁显示
								draw_piece (box[i].posx, box[i].posy, 0);
								draw_piece (box[selected_boxnum].posx, box[selected_boxnum].posy, 0);
								FlushBatchDraw ();
								Sleep (200);
								draw_piece (box[i].posx, box[i].posy, box[i].type);
								draw_piece (box[selected_boxnum].posx, box[selected_boxnum].posy, box[selected_boxnum].type);
								FlushBatchDraw ();

								// 判断能否交换
								// 重置临时参数
								for (k = 0; k < 500; k++) { eat[k].num = k; eat[k].boxnum = 0; }

								flag = 0;
								// 矩形判断
								if (mod_shape == 0)
								{
									x[0] = check_square (selected_boxnum, box[selected_boxnum].type);
									z[0] = selected_boxnum;
									x[1] = check_square (i, box[i].type);
									z[1] = i;
								}
								// 六边形
								else if (mod_shape == 1)
								{
									x[0] = check_hexagon (selected_boxnum, box[selected_boxnum].type);
									x[1] = check_hexagon (i, box[i].type);
								}
								// 能,则消除,生成新的
								if (flag >= 2)
								{
									// 时间奖励
									start_endtime += 3500;
									// 得分奖励
									start_point += (flag + 1);
									// 闪烁显示
									for (j = 0; j < 3; j++)
									{
										Sleep (350);
										if (x[0] >= 2) { draw_piece (box[selected_boxnum].posx, box[selected_boxnum].posy, 0); }
										if (x[1] >= 2) { draw_piece (box[i].posx, box[i].posy, 0); }
										for (k = 0; k < flag; k++) { draw_piece (box[eat[k].boxnum].posx, box[eat[k].boxnum].posy, 0); }
										FlushBatchDraw ();
										Sleep (200);
										if (x[0] >= 2) { draw_piece (box[selected_boxnum].posx, box[selected_boxnum].posy, box[selected_boxnum].type); }
										if (x[1] >= 2) { draw_piece (box[i].posx, box[i].posy, box[i].type); }
										for (k = 0; k < flag; k++) { draw_piece (box[eat[k].boxnum].posx, box[eat[k].boxnum].posy, box[eat[k].boxnum].type); }
										FlushBatchDraw ();
									}
									// 交换格子参数变更
									// 矩形
									if (mod_shape == 0)
									{
										t = 0;
										if (box[i].type == box[selected_boxnum].type) { t = 1; }
										h = 2;
										// 参数置零
										for (k = 0; k < h; k++)
										{
											// 炸弹
											if (x[k] >= 4)
											{
												box[z[k]].type = 8;
											}
											else if (x[k] >= 2)
											{
												box[z[k]].type = 0;
											}
										}
										for (k = 0; k < flag; k++) { box[eat[k].boxnum].type = 0; }
										if (t == 1 && flag >= 6) { box[i].type = 8; }
									}
									// 六边形
									else if (mod_shape == 1)
									{
										if (x[0] >= 2) { creact_piece (selected_boxnum); }
										if (x[1] >= 2) { creact_piece (i); }
										// 临时存储格子参数变更
										for (k = 0; k < flag; k++)
										{
											creact_piece (eat[k].boxnum);
										}
									}
								A:
									// 下落,下落后判断,循环至判定后无可消除项,注意,只有矩形有下落
									flag = 2;
									while (flag >= 2 && mod_shape == 0)
									{
										// 从下往上,空位由上方弥补,若上方也没有就空着,需要统计交换了的格子
										h = 0;
										for (k = size_shape - 1; k > 0; k--)
										{
											for (j = size_shape - 1; j >= 0; j--)
											{
												t = k * 10 + j;
												// 空位
												if (box[t].type == 0)
												{
													// 向上找
													y = t;
													while (y / size_shape > 0)
													{
														y -= 10;
														// 找到则交换参数
														if (box[y].type != 0)
														{
															box[t].type = box[y].type;
															box[y].type = 0;
															z[h] = t;
															h++;
															break;
														}

													}
												}
											}
										}
										// 填补,也需要统计,绘制
										for (k = size_shape - 1; k >= 0; k--)
										{
											for (j = size_shape - 1; j >= 0; j--)
											{
												t = k * 10 + j;
												// 空位
												if (box[t].type == 0)
												{
													creact_piece (t);
													z[h] = t;
													h++;
												}
												// 绘制
												draw_piece (box[t].posx, box[t].posy, box[t].type);
											}
										}
										FlushBatchDraw ();

										// 根据统计分析
										// 参数重置
										flag = 0;
										for (k = 0; k < h; k++)
										{
											x[k] = check_square (z[k], box[z[k]].type);
										}
										// 重新开始,最后将要消除的格子参数置零
										if (flag >= 2)
										{
											// 时间奖励
											start_endtime += 2000;
											// 得分奖励
											start_point += (flag + 1);
											// 闪烁显示
											for (j = 0; j < 3; j++)
											{
												Sleep (350);
												for (k = 0; k < h; k++) { if (x[k] >= 2) { draw_piece (box[z[k]].posx, box[z[k]].posy, 0); } }
												for (k = 0; k < flag; k++) { draw_piece (box[eat[k].boxnum].posx, box[eat[k].boxnum].posy, 0); }
												FlushBatchDraw ();
												Sleep (200);
												for (k = 0; k < h; k++) { if (x[k] >= 2) { draw_piece (box[z[k]].posx, box[z[k]].posy, box[z[k]].type); } }
												for (k = 0; k < flag; k++) { draw_piece (box[eat[k].boxnum].posx, box[eat[k].boxnum].posy, box[eat[k].boxnum].type); }
												FlushBatchDraw ();
											}
											// 参数置零
											for (k = 0; k < h; k++) { if (x[k] >= 2) { box[z[k]].type = 0; } }
											for (k = 0; k < flag; k++) { box[eat[k].boxnum].type = 0; }
										}
									}

									// 判断有无解,无解自动重置
									// 对所有可交换对,进行交换,并分析
									flag = 0;
									while (flag == 0 && mod_shape == 0)
									{
										flag = 0;
										for (i = 0; i < 100; i++)
										{
											// 有炸弹就算有解
											if (box[i].type == 8)
											{
												flag = 2;
												break;
											}
											else if (box_change[i].type == 1)
											{
												// 交换
												j = box[box_change[i].boxnum1].type;
												box[box_change[i].boxnum1].type = box[box_change[i].boxnum2].type;
												box[box_change[i].boxnum2].type = j;
												// 判断
												t = check_square (box_change[i].boxnum1, box[box_change[i].boxnum1].type);
												t = check_square (box_change[i].boxnum2, box[box_change[i].boxnum2].type);
												// 换回来
												j = box[box_change[i].boxnum1].type;
												box[box_change[i].boxnum1].type = box[box_change[i].boxnum2].type;
												box[box_change[i].boxnum2].type = j;
												// 有解
												if (flag >= 2) { break; }
											}
										}
										// 无解
										if (flag == 0)
										{
											// 整体闪烁
											for (j = 0; j < 3; j++)
											{
												Sleep (350);
												for (k = 0; k < 100; k++) { if (box[k].type != -1) { draw_piece (box[k].posx, box[k].posy, 0); } }
												FlushBatchDraw ();
												Sleep (200);
												for (k = 0; k < 100; k++) { if (box[k].type != -1) { draw_piece (box[k].posx, box[k].posy, box[k].type); } }
												FlushBatchDraw ();
											}
											// 重置,效果与刷新一致
											// 开始进程初始化函数,主要是格子参数的初始化
											initialization_start ();
											start_t2 = clock ();
											draw_scene_start ();
										}
									}
								}
								// 不能,则换回来
								else
								{
									j = box[selected_boxnum].type;
									box[selected_boxnum].type = box[i].type;
									box[i].type = j;

									// 闪烁显示
									Sleep (350);
									draw_piece (box[i].posx, box[i].posy, 0);
									draw_piece (box[selected_boxnum].posx, box[selected_boxnum].posy, 0);
									FlushBatchDraw ();
									Sleep (200);
									draw_piece (box[i].posx, box[i].posy, box[i].type);
									draw_piece (box[selected_boxnum].posx, box[selected_boxnum].posy, box[selected_boxnum].type);
									FlushBatchDraw ();
								}

							}
							// 点击其他格子,表示换选择
							else
							{
								selected_or_not = 1;
								// 选择绘制
								k = selected_boxnum;
								draw_piece (box[k].posx, box[k].posy, box[k].type);

								selected_boxnum = i;
								// 选择绘制
								k = selected_boxnum;
								setfillstyle (BS_NULL);
								setlinestyle (PS_SOLID, 2);
								setlinecolor (LIGHTRED);
								// 矩形
								if (mod_shape == 0)
								{
									fillrectangle (box[k].posx + 1, box[k].posy + 1, box[k].posx + 49, box[k].posy + 49);

								}
								// 六边形
								else if (mod_shape == 1)
								{
									fillcircle (box[k].posx + 25, box[k].posy + 25, 23);
								}
								setfillstyle (BS_SOLID);
								FlushBatchDraw ();
							}
						}
					}
					flushmessage (EM_MOUSE);
				}
				else
				{
					// 判断是否点击了按钮
					for (i = 0; i < num_button; i++)
					{
						if (m.x > boxm[i].posx1 && m.y > boxm[i].posy1 && m.x < boxm[i].posx2 && m.y < boxm[i].posy2 && boxm[i].type == 0)
						{
							break;
						}
					}

					// 刷新按钮
					if (i == 0)
					{
						// 开始进程初始化函数,主要是格子参数的初始化
						initialization_start ();
						start_t2 = clock ();
						draw_scene_start ();
					}
					// 返回按钮
					else if (i == 1)
					{
						exit_start = 1;
					}
				}
			}
		}

		// 时间更新,以及退出判断
		start_t2 = clock ();
		if ((start_t2 - start_t1) % 500 == 0 && mod_start != 1)
		{
			// 绘制
			draw_scene_start ();
		}
		if ((start_t2 - start_t1) >= start_endtime && mod_start != 1)
		{
			// 退出提示
			MessageBox (hOut, _T ("记录下得分,结束啦"), _T ("来自小豆子的提醒"), MB_OK);
			exit_start = 1;
		}
	}
}

// 开始进程初始化函数
void game::initialization_start ()
{
	int i, j, k, t;
	// 画布初始化
	setbkcolor (WHITE);
	cleardevice ();

	// 格子初始化
	for (i = 0; i < 1000; i++)
	{
		box[i].type = -1;
	}
	// 矩形
	if (mod_shape == 0)
	{
		// 二维参数定义
		for (i = 0; i < size_shape; i++)
		{
			for (j = 0; j < size_shape; j++)
			{
				k = i * 10 + j;
				box[k].boxnum = k;
				box[k].i = i;
				box[k].j = j;
				box[k].posx = j * 50 + 250 - size_shape * 25;
				box[k].posy = i * 50 + 250 - size_shape * 25;
				box[k].type = 0;
				if (mod_start == 0 || mod_start == 2)
				{
					creact_piece (k);
				}

			}
		}

		// 随机生成两个棋子
		for (i = 0; i < 2; i++)
		{
			do
			{
				k = rand () % 1000;
			} while (box[k].type < 0);

			creact_piece (k);
		}

		// 判断有无解,无解自动重置

		// 对所有可交换对,进行交换,并分析
		flag = 0;
		while (flag == 0)
		{
			flag = 0;
			for (i = 0; i < 100; i++)
			{
				if (box_change[i].type == 1)
				{
					// 交换
					j = box[box_change[i].boxnum1].type;
					box[box_change[i].boxnum1].type = box[box_change[i].boxnum2].type;
					box[box_change[i].boxnum2].type = j;
					// 判断
					t = check_square (box_change[i].boxnum1, box[box_change[i].boxnum1].type);
					t = check_square (box_change[i].boxnum2, box[box_change[i].boxnum2].type);
					// 换回来
					j = box[box_change[i].boxnum1].type;
					box[box_change[i].boxnum1].type = box[box_change[i].boxnum2].type;
					box[box_change[i].boxnum2].type = j;
					// 有解
					if (flag == 0)
						if (flag >= 2) { break; }
				}
			}
			// 无解
			if (flag == 0)
			{
				// 重置,效果与刷新一致
				// 开始进程初始化函数,主要是格子参数的初始化
				initialization_start ();
				start_t2 = clock ();
				draw_scene_start ();
			}
		}
	}
	// 六边形
	else if (mod_shape == 1)
	{
		// 三维参数定义
		for (i = 0; i <= size_shape; i++)
		{
			for (j = 0; j <= size_shape; j++)
			{
				for (k = 0; k <= size_shape; k++)
				{
					if (i == 0 || j == 0 || k == 0)
					{
						t = i + j * 10 + k * 100;
						box[t].boxnum = t;
						box[t].posx = 200 + 43 * (j - k);
						box[t].posy = 230 - 50 * i + 25 * (j + k);
						box[t].i = i;
						box[t].j = j;
						box[t].k = k;
						box[t].type = 0;
						if (mod_start == 0 || mod_start == 2)
						{
							creact_piece (t);
						}
					}
				}
			}
		}

		// 随机生成两个棋子
		for (i = 0; i < 2; i++)
		{
			do
			{
				k = rand () % 1000;
			} while (box[k].type < 0);

			creact_piece (k);
		}
	}

	// 按钮设置初始化
	num_button = 2;

	boxm[0].posx1 = 500; boxm[0].posy1 = 20;	boxm[0].posx2 = 580; boxm[0].posy2 = 80;	boxm[0].text = _T ("刷新"); boxm[0].type = 0;
	boxm[1].posx1 = 500; boxm[1].posy1 = 420;	boxm[1].posx2 = 580; boxm[1].posy2 = 480;	boxm[1].text = _T ("返回"); boxm[1].type = 0;

	// 是否选择参数初始化
	selected_or_not = 0;

}

// 开始进程绘制函数
void game::draw_scene_start ()
{
	int i, j, k, t;

	// 绘制主背景
	setbkcolor (WHITE);
	cleardevice ();

	// 画格子
	// 矩形
	if (mod_shape == 0)
	{
		// 二维参数
		for (i = 0; i < size_shape; i++)
		{
			for (j = 0; j < size_shape; j++)
			{
				k = i * 10 + j;
				// 普通状态
				draw_piece (box[k].posx, box[k].posy, box[k].type);
				// 选中状态
				if (selected_or_not == 1 && k == selected_boxnum)
				{
					setfillstyle (BS_NULL);
					setlinestyle (PS_SOLID, 2);
					setlinecolor (LIGHTRED);
					fillrectangle (box[k].posx + 1, box[k].posy + 1, box[k].posx + 49, box[k].posy + 49);
					setfillstyle (BS_SOLID);
				}
			}
		}
	}
	// 六边形
	else if (mod_shape == 1)
	{
		// 三维参数
		for (i = 0; i <= size_shape; i++)
		{
			for (j = 0; j <= size_shape; j++)
			{
				for (k = 0; k <= size_shape; k++)
				{
					if (i == 0 || j == 0 || k == 0)
					{
						t = i + j * 10 + k * 100;
						// 普通状态
						draw_piece (box[t].posx, box[t].posy, box[t].type);
						// 选中状态
						if (selected_or_not == 1 && t == selected_boxnum)
						{
							setfillstyle (BS_NULL);
							setlinestyle (PS_SOLID, 2);
							setlinecolor (LIGHTRED);
							fillcircle (box[t].posx + 25, box[t].posy + 25, 23);
							setfillstyle (BS_SOLID);
						}
					}
				}
			}
		}
	}

	// 绘制按钮
	draw_button ();

	// 绘制得分
	TCHAR s[25];

	// 时间更新,以及退出判断
	if ((start_t2 - start_t1) % 500 == 0 && mod_start != 1)
	{
		// 时间
		if (mod_start != 1)
		{
			draw_word (30, 505, 120, _T ("时间:"));
			_stprintf_s (s, _T ("%0.1d"), (start_endtime - (start_t2 - start_t1)) / 1000);
			draw_word (30, 510, 160, s);
			draw_word (30, 570, 160, _T ("秒"));
		}
	}
	// 得分
	draw_word (30, 510, 220, _T ("得分:"));
	_stprintf_s (s, _T ("%0.1d"), start_point);
	draw_word (30, 510, 260, s);

	FlushBatchDraw ();
}

添加评论