对于扫雷 点一块消周围一片没有雷的区域

扫雷游戏零区消除算法

最开始想到采用递归,对点的那一块周围八块进行递归操作  8个递归  实际过程中 会产生栈溢出 无法使用。


void saolei(int leipan[X11][Y11], char youxipan[X11][Y11],int x,int y,int x1, int y1)
{
	if ((x > 0) && (x <= x1) && (y > 0) && (y <= y1))
	{
		int m = leipan[x - 1][y - 1] + leipan[x - 1][y] + leipan[x - 1][y + 1] + leipan[x][y - 1] + leipan[x][y + 1] + leipan[x + 1][y - 1] + leipan[x + 1][y] + leipan[x + 1][y + 1];
		if (m == 0)
		{
			youxipan[x][y] = ' ';                             
			if ((x > 0) && (x <= x1) && (y > 0) && (y <= y1))      //递归不动  栈溢出
			{

				saolei(leipan, youxipan, x - 1, y , x1, y1);
                saolei(leipan, youxipan, x - 1, y - 1, x1, y1);
			    saolei(leipan, youxipan, x - 1, y + 1, x1, y1);
				saolei(leipan, youxipan, x, y - 1, x1, y1);
			    saolei(leipan, youxipan, x, y + 1, x1, y1);
				saolei(leipan, youxipan, x + 1, y - 1, x1, y1);
			    saolei(leipan, youxipan, x + 1, y, x1, y1);
				saolei(leipan, youxipan, x + 1, y + 1, x1, y1);
			}
		}
		else
			youxipan[x][y] = m + '0';//字符1 2 3  用的ASC||码
	}
}

可以看到上面那个盘为实际游戏显示的    下面那个盘是实际游戏过程中,不会显示的这里为了演示消0区 故拿出来

可以看到这里 没有雷 实际的效果希望可以直接消一些方块

一个函数里面又调用八次   8的指数倍增长  会造成栈溢出      故这里想达到这个效果递归不在可用

这里采用 首写判断程序 代替递归  实际就是这个函数复制 稍微修改一下即可

复制了四个  实现了需要的效果  而且不会溢出

代码:

void saolei(int leipan[X11][Y11], char youxipan[X11][Y11],int x,int y,int x1, int y1)
{
	if ((x > 0) && (x <= x1) && (y > 0) && (y <= y1))
	{
		int m = leipan[x - 1][y - 1] + leipan[x - 1][y] + leipan[x - 1][y + 1] + leipan[x][y - 1] + leipan[x][y + 1] + leipan[x + 1][y - 1] + leipan[x + 1][y] + leipan[x + 1][y + 1];
		if (m == 0)
		{
			youxipan[x][y] = ' ';                             
			if ((x > 0) && (x <= x1) && (y > 0) && (y <= y1))      //递归不动  栈溢出
			{
				digui1(leipan, youxipan, x - 1, y, x1, y1);//用函数代替递归四次
				digui1(leipan, youxipan, x - 1, y - 1, x1, y1);
				digui1(leipan, youxipan, x - 1, y + 1, x1, y1);
				digui1(leipan, youxipan, x, y - 1, x1, y1);
				digui1(leipan, youxipan, x, y + 1, x1, y1);
				digui1(leipan, youxipan, x + 1, y - 1, x1, y1);
				digui1(leipan, youxipan, x + 1, y, x1, y1);
				digui1(leipan, youxipan, x + 1, y + 1, x1, y1);


			/*	saolei(leipan, youxipan, x - 1, y , x1, y1);
                saolei(leipan, youxipan, x - 1, y - 1, x1, y1);
			    saolei(leipan, youxipan, x - 1, y + 1, x1, y1);
				saolei(leipan, youxipan, x, y - 1, x1, y1);
			    saolei(leipan, youxipan, x, y + 1, x1, y1);
				saolei(leipan, youxipan, x + 1, y - 1, x1, y1);
			    saolei(leipan, youxipan, x + 1, y, x1, y1);
				saolei(leipan, youxipan, x + 1, y + 1, x1, y1);
			}*/
		}
		else
			youxipan[x][y] = m + '0';//字符1 2 3  用的ASC||码
	}
}












void digui1(int leipan[X11][Y11], char youxipan[X11][Y11], int x, int y, int x1, int y1)
{

	int m = 0;
	if ((x > 0) && (x <= x1) && (y > 0) && (y <= y1))     
	{
		m= leipan[x - 1][y - 1] + leipan[x - 1][y] + leipan[x - 1][y + 1] + leipan[x][y - 1] + leipan[x][y + 1] + leipan[x + 1][y - 1] + leipan[x + 1][y] + leipan[x + 1][y + 1];
		if (m == 0)
		{
			youxipan[x][y] = ' ';
			digui2(leipan, youxipan, x - 1, y, x1, y1);
			digui2(leipan, youxipan, x - 1, y - 1, x1, y1);
			digui2(leipan, youxipan, x - 1, y + 1, x1, y1);
			digui2(leipan, youxipan, x, y - 1, x1, y1);
			digui2(leipan, youxipan, x, y + 1, x1, y1);
			digui2(leipan, youxipan, x + 1, y - 1, x1, y1);
			digui2(leipan, youxipan, x + 1, y, x1, y1);
			digui2(leipan, youxipan, x + 1, y + 1, x1, y1);

		}
		else
			youxipan[x][y] = m + '0';//字符1 2 3  用的ASC||码
	
	}

}

void digui2(int leipan[X11][Y11], char youxipan[X11][Y11], int x, int y, int x1, int y1)
{

	int m = 0;
	if ((x > 0) && (x <= x1) && (y > 0) && (y <= y1))     
	{
		m = leipan[x - 1][y - 1] + leipan[x - 1][y] + leipan[x - 1][y + 1] + leipan[x][y - 1] + leipan[x][y + 1] + leipan[x + 1][y - 1] + leipan[x + 1][y] + leipan[x + 1][y + 1];
		if (m == 0)
		{
			youxipan[x][y] = ' ';
			digui3(leipan, youxipan, x - 1, y, x1, y1);
			digui3(leipan, youxipan, x - 1, y - 1, x1, y1);
			digui3(leipan, youxipan, x - 1, y + 1, x1, y1);
			digui3(leipan, youxipan, x, y - 1, x1, y1);
			digui3(leipan, youxipan, x, y + 1, x1, y1);
			digui3(leipan, youxipan, x + 1, y - 1, x1, y1);
			digui3(leipan, youxipan, x + 1, y, x1, y1);
			digui3(leipan, youxipan, x + 1, y + 1, x1, y1);

		}
		else
			youxipan[x][y] = m + '0';//字符1 2 3  用的ASC||码

	}

}


void digui3(int leipan[X11][Y11], char youxipan[X11][Y11], int x, int y, int x1, int y1)
{

	int m = 0;
	if ((x > 0) && (x <= x1) && (y > 0) && (y <= y1))     
	{
		m = leipan[x - 1][y - 1] + leipan[x - 1][y] + leipan[x - 1][y + 1] + leipan[x][y - 1] + leipan[x][y + 1] + leipan[x + 1][y - 1] + leipan[x + 1][y] + leipan[x + 1][y + 1];
		if (m == 0)
		{
			youxipan[x][y] = ' ';
			digui4(leipan, youxipan, x - 1, y, x1, y1);
			digui4(leipan, youxipan, x - 1, y - 1, x1, y1);
			digui4(leipan, youxipan, x - 1, y + 1, x1, y1);
			digui4(leipan, youxipan, x, y - 1, x1, y1);
			digui4(leipan, youxipan, x, y + 1, x1, y1);
			digui4(leipan, youxipan, x + 1, y - 1, x1, y1);
			digui4(leipan, youxipan, x + 1, y, x1, y1);
			digui4(leipan, youxipan, x + 1, y + 1, x1, y1);

		}
		else
			youxipan[x][y] = m + '0';//字符1 2 3  用的ASC||码

	}

}



	void digui4(int leipan[X11][Y11], char youxipan[X11][Y11], int x, int y, int x1, int y1)
	
	{

		int m = 0;
		if ((x > 0) && (x <= x1) && (y > 0) && (y <= y1))
		{
			m = leipan[x - 1][y - 1] + leipan[x - 1][y] + leipan[x - 1][y + 1] + leipan[x][y - 1] + leipan[x][y + 1] + leipan[x + 1][y - 1] + leipan[x + 1][y] + leipan[x + 1][y + 1];
			if (m == 0)
			{
				youxipan[x][y] = ' ';

			}
			else
				youxipan[x][y] = m + '0';//字符1 2 3  用的ASC||码

		}
	}

效果展示

即可实现 扫雷中 点一块 消很多块的效果

在C语言中实现扫雷游戏,当鼠标击的第一个位置可能是时,通常需要维护一个区矩阵,并通过用户交互更新当前状态。下面是一个简单的流程概述: 1. 初始化区:创建一个二维数组表示区,其中0代表安全区域,非0值代表有的位置。随机分布的位置。 2. 用户交互:使用`getch()`或类似函数获取用户的鼠标击坐标。对于Windows平台,可以使用`GetAsyncKeyState() + VK_DOWN`来模拟鼠标左键击。 3. 检查当前位置:在区矩阵中检查击坐标对应的元素是否为。如果是,则显示提示信息并结束游戏;如果不是,进入下一步。 4. 开始递归搜索:如果击位置不是,你可以选择向下、向左、向右、向上四个方向进行递归搜索,标记出安全区域。同时,检查周围8个相邻格子是否有,如有则相应地增加计数。 5. 更新界面:每次用户击后,都要更新区矩阵的显示,显示当前的安全格子和已知的的数量。 6. 结束条件:当用户成功避开所有或全部都被标记时,游戏结束。 ```c // 示例代码片段 int check_square(int row, int col) { if (row < 0 || col < 0 || row >= board_size || col >= board_size) // 越界处理 return -1; else if (board[row][col] == mine) // return 0; else if (!visited[row][col]) { // 如果没访问过 visited[row][col] = 1; // 标记为已访问 count[row][col] = check_square(row+1, col) + check_square(row-1, col) + ...; // 检查周围 return count[row][col]; } return -1; // 如果已经访问过,直接返回 } void mouse_click(int x, int y) { int row = y / cell_size, col = x / cell_size; if (check_square(row, col) == 0) printf("危险!这里有!\n"); else update_board(row, col); // 更新显示 } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值