C语言扫雷游戏

发布于:2023-01-04 ⋅ 阅读:(231) ⋅ 点赞:(0)

该游戏需要分出游戏区和辅助区,以此来确定九宫格内雷的个数,通过增加游戏区,确保在边缘的数字不会出错,防止越界

/*

根据雷的分布来填充其他不为雷的数据

原理:

1.遍历九宫格

根据   行列     i-1;i;i+1           j-1;j;j+1;来遍历

2.边上的数据,在遍历时会越界,

3.所以要加辅助区 游戏区         

此处尤其要注意

所以在初始化时要考虑什么要初始化,什么不要

4.drawGame里需要通过判断数字来打印图片

5.游戏九宫格内0的部分要全部打开,打开之后有0继续全部打开

因此是一个递归函数,注意传参

翻开是0就要递归

6.通过鼠标左键点击的坐标,获取图片的位置

7.标记或取消标记的规则是通过判断        右键则加,标记之后继续右键则减 ,通过具体的数值来判断

8.添加随机数种子的方法

//添加随机数种子
    srand((unsigned int)time(NULL));

//随机得到行和列
        int r = rand() % ROW+1;//从1-ROW    !!!!!
        int c = rand() % COL+1;//从1-COL    !!!!!

9.通过嵌套for循环来遍历数组

10.遍历二维数组的游戏区

//根据雷的分布,找到不为雷的数据

如果有雷,原数自增,并显示

11.简单加密是通过改变数据的大小,来实现不同层面的显示

12.

导图图片的格式

loadimage(&img[0], "./数字0.png", SIZE, SIZE);

输入图片的格式

putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[map[i][j]]);/

13.控制台的显示以及弹窗

HWND hwnd = initgraph(ROW*SIZE,COL*SIZE,SHOWCONSOLE);

    MessageBox(hwnd, "You are lose!", "", MB_OK);

*/

想要改游戏难度,只需要改变头文件

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <graphics.h>

#define ROW 10//行
#define COL 10//列
#define NUM 10//雷的数量
#define SIZE 50

//创建二维数组
int map[ROW+2][COL+2];
int count;	//获得分数

//初始化12张图片
IMAGE img[12];

//绘制函数 打印二维数组中的所有元素

void openZero(int r,int c) 
{
	//先打开这个0
	map[r][c] -= 20;
	count++;
	//接下来遍历九宫格
	for (int m = r - 1; m <= r + 1; m++) {
		for (int n = c - 1; n <= c + 1; n++) {	//九宫格
		//首先必须保证辅助区是不变的,变化的是游戏区
			if (m >= 1 && m <= ROW && n>=1 && n<=COL) {	//游戏区
				if (map[m][n] >= 19 && map[m][n] <= 28) {
					if (map[m][n] != 20) {
						map[m][n] -= 20;
						count++;
					}
					else {
						openZero(m, n);			//翻开的还是0 ,实现基本的递归	
					}
				}
			}
		}
	}
}

void drawGame() 
{
	//打印游戏区
	/*******************************************************
		想要显示空白图片  只需要给数字和图片都+20就可以了
		后续点击空白图片  让对应元素-20就可以得到想要的

		0-8是数字图片					+20=28
		-1是雷							+20=19
				但是需要旗子  空白等等
		所以添加
		19-28是空白
		>30  是旗子


	*************************************************************/
	for (int i = 1; i <= ROW; i++) 
	{
		for (int j = 1; j <= COL; j++) 
		{
			printf("%2d ", map[i][j]);
			if (map[i][j] == -1) {
			//雷
				//在图形界面都是以坐标为基础,所以  以坐标乘以图片大小
				putimage((i-1)*SIZE,(j-1)*SIZE,&img[11]);
			}
			else if (map[i][j] >= 0 && map[i][j] < 8) {
				putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[map[i][j]]);//正好下标与ij相对应
			}
			else if(map[i][j]>=19&&map[i][j]<=28) {
				putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[10]);
			}
			else if (map[i][j] > 30) {
				//旗子
				putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[9]);
			}
		}
		printf("\n");
		
	}
}

int playGame() 
{
	int r, c;

	//定义一个鼠标消息
	MOUSEMSG msg = { 0 };
	while (1) 
	{
		msg = GetMouseMsg();

		switch (msg.uMsg)
		{
		case WM_LBUTTONDOWN://翻开扫雷空白处
			r = msg.x / SIZE + 1;//这里要加1是因为有辅助区
			c = msg.y / SIZE + 1;//这里要加1是因为有辅助区
			if (map[r][c] >= 19 && map[r][c] <= 28) {	//空白
				if (map[r][c] == 20) { 
					openZero(r,c);
				}
				else {
					map[r][c] -= 20;
					count++;
				}
			}
			return map[r][c];
			break;
		case WM_RBUTTONDOWN://标记或取消标记
			r = msg.x / SIZE + 1;
			c = msg.y / SIZE + 1;
			if (map[r][c] >= 19 && map[r][c] <= 28) {
				map[r][c] += 20;
			}
			else if (map[r][c] > 30) {
				map[r][c] -= 20;
			}
			return map[r][c];
			break;



		}
	}
}

//初始化该函数 
void initGame()
{
	//添加随机数种子
	srand((unsigned int)time(NULL));



	//数组的赋初值0
	for (int i = 0; i < ROW + 2; i++)//初始化时要全部初始化  通过遍历数组  全部初始化
	{
		for (int j = 0; j < COL + 2; j++)
		{
			map[i][j] = 0;
		}

	}

	//布雷 -1表示雷 NUM表示雷的个数
	int n = 0;
	while (n < NUM)
	{
		//随机得到行和列
		int r = rand() % ROW+1;//从1-ROW	!!!!!
		int c = rand() % COL+1;//从1-COL	!!!!!

		if (map[r][c] == 0)
		{
			map[r][c] = -1;
			n++;
		}
	}
	//根据雷的分布,找到不为雷的数据

	for (int i = 1; i <= ROW; i++) {
		for (int j = 1; j <= COL; j++) {	//首先遍历二维数组    遍历二维数组的	【游戏区】
			if (map[i][j] != -1) {			//找到不为雷的元素
				//遍历九宫格
				for (int m = i - 1; m <= i + 1; m++) {	//在该九宫格的范围内确定
					for (int n= j - 1; n<= j + 1; n++) {//m n和别处的m n之间没有关系

						//找到一个雷
						//判断
						if (map[m][n] == -1) {
							//原数自增	
							map[i][j]++;
						}
					}
				}
			}
		}
		//简单加密
		
	}
	for (int i = 1; i < ROW + 1; i++) {
		for (int j = 1; j < COL + 1; j++) {
			map[i][j] += 20;
		}
	}
}
int main() 
{
	loadimage(&img[0], "./数字0.png", SIZE, SIZE);
	loadimage(&img[1], "./数字1.png", SIZE, SIZE);
	loadimage(&img[2], "./数字2.png", SIZE, SIZE);
	loadimage(&img[3], "./数字3.png", SIZE, SIZE);
	loadimage(&img[4], "./数字4.png", SIZE, SIZE);
	loadimage(&img[5], "./数字5.png", SIZE, SIZE);
	loadimage(&img[6], "./数字6.png", SIZE, SIZE);
	loadimage(&img[7], "./数字7.png", SIZE, SIZE);
	loadimage(&img[8], "./数字8.png", SIZE, SIZE);
	loadimage(&img[9], "./旗子.png", SIZE, SIZE);
	loadimage(&img[10], "./空白.png", SIZE, SIZE);
	loadimage(&img[11], "./雷.png", SIZE, SIZE);

	HWND hwnd = initgraph(ROW*SIZE,COL*SIZE,SHOWCONSOLE);
	initGame();
	while (1) {
		drawGame();
		if (playGame() == -1)
		{
			drawGame();
			MessageBox(hwnd, "You are lose!", "", MB_OK);
			break;
		}
		if (ROW * COL-NUM == count) {
			MessageBox(hwnd, "You are win!", "", MB_OK);
		}
	};
	closegraph();
	return 0;

	/*******************************************************
		想要显示空白图片  只需要给数字和图片都+20就可以了
		后续点击空白图片  让对应元素-20就可以得到想要的

		0-8是数字图片					+20=28
		-1是雷							+20=19
				但是需要旗子  空白等等
		所以添加
		19-28是空白	
		>30  是旗子

	
	*************************************************************/
}


网站公告

今日签到

点亮在社区的每一天
去签到