轻松实现经典小游戏——扫雷

1.简介:xp经典小游戏-扫雷,(附源码);特点:雷的数量、位置随机,每胜利一局,视野扩大一圈,界面展示如下图:

 

2.语言、工具:C语言;visual studio或者vc 6.0都可以,需要easyX库,点击自行下载安装即可,里面也有教程,故此不再赘述,一些图片素材,声音素材;

3.原理:

设定一个N*N的数组,-1表示雷,0-8表示的是非雷位置周围雷的数量;

首先对数组先任意位置随机取随机个位置为-1,再对数组进行遍历,找出安全区周围雷的数量,数组元素值范围(-1~8);

将每个元素加20来对数组进行元素隐藏,数组元素值范围(19-28);

操作鼠标左键点击翻开则对数组元素值在19~28的元素减20,操作鼠标右键点击:标记则对数组元素值在19~28的元素加20,取消标记则对数组元素值在39~48的元素减20;

图形界面:准备图片素材,按元素值不同填充显示不同图片;

4.关键点:a.数组的操作处理及遍历;b.图形界面的绘制;c.获取鼠标信息;d.随机数;

5.代码实现:

a.用到的头文件:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>//随机数srand
#include<graphics.h>
#include <windows.h>
#pragma comment(lib,"winmm.lib")

b. 初始化游戏,获取随机数,随机填充雷,获取安全区附近的雷数量,隐藏雷

//初始化游戏
void game_init()
{
	srand((unsigned int)time(NULL));//得到非伪随机数
	//init matrix
	for (int i = 0; i < K; i++)
	{
		for (int j = 0; j < K; j++)
			map[i][j] = 0;
	}
	int a=0;
	while (a >= 3*N||a <= N)//随机雷数量
		a = rand() % (3*N);
	//为后面方便,留空外框
	//埋雷,-1 雷
	for (int i = 0; i < a;)
	{
		int r = rand() % N + 1;//随机行(1~10)
		int c = rand() % N + 1;//随机列
		if (map[r][c] == 0)
		{
			map[r][c] = -1;
			i++;
		}
	}
	//得出其他元素的值--安全区周围的雷数
	for (int i = 1; i <= N; i++)
	for (int j = 1; j <= N; j++)
	{
		if (map[i][j] != -1)
		for (int m = i - 1; m <= i + 1; m++)
		for (int n = j - 1; n <= j + 1; n++)
		{
			if (map[m][n] == -1)
				map[i][j] += 1;
		}
	}
	//隐藏,点一下就减去20恢复
	for (int i = 1; i <= N; i++)
	for (int j = 1; j <= N; j++)
	{
		map[i][j] += 20;
	}

	hwnd = GetHWnd();
}

c.游戏窗口

//游戏窗口刷新
void window_set()
{
	for (int i = 0; i < N; i++)
	for (int j = 0; j < N; j++)
	{
		if (map[i + 1][j + 1] == -1)
		{
			putimage(i*SIZE, j*SIZE, &img[9]);//雷
		}
		else if (map[i + 1][j + 1] >= 0 && map[i + 1][j + 1] <= 8)//0~8,非雷
			putimage(i*SIZE, j*SIZE, &img[map[i + 1][j + 1]]);
		else if (map[i + 1][j + 1] >= 19 && map[i + 1][j + 1] <= 28)//19~28,隐藏的
			putimage(i*SIZE, j*SIZE, &img[10]);
		else if (map[i + 1][j + 1] >= 39 && map[i + 1][j + 1] <= 48)//29~38,标记
			putimage(i*SIZE, j*SIZE, &img[11]);
	}  
}

 d.点开的一个0后,自动把周围的翻开

/点0后,递归把周围的0打开
void openZero(int x, int y)
{
	map[x][y] -= 20;
	for (int i = x - 1; i <= x + 1; i++)
	{
		for (int j = y - 1; j <= y + 1; j++)
		{
			if (i >= 1 && i <= N&&j >= 1 && j <= N)
			{
				if (map[i][j] >= 19 && map[i][j] <= 28)
				{
					if (map[i][j] == 20)
						openZero(i, j);
					else
						map[i][j] -= 20;
				}
			}
		}
	}
}

e.鼠标点击玩游戏

//鼠标点击玩游戏
void playGame()
{
	MOUSEMSG msg = { 0 };//定义鼠标消息

	msg = GetMouseMsg();//获取
	switch (msg.uMsg)
	{
	case WM_LBUTTONDOWN:
		if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] == 20)//
			openZero(msg.x / SIZE + 1, msg.y / SIZE + 1);
		else if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 19 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 28)
			map[msg.x / SIZE + 1][msg.y / SIZE + 1] -= 20;
		break;
	case WM_RBUTTONDOWN:
		if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 19 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 28)
			map[msg.x / SIZE + 1][msg.y / SIZE + 1] += 20;
		else if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 39 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 48)
			map[msg.x / SIZE + 1][msg.y / SIZE + 1] -= 20;
		break;
	}
}

f.游戏主循环

while (1)
	{
		int num = 0;
		window_set();
		playGame();
		//如果矩阵里出现-1,就结束了
		for (int i = 1; i <= N; i++)
		{
			for (int j = 1; j <= N; j++)
			{
				if (map[i][j] == -1)
				{
					window_set();
					for (int t = 1; t <= N; t++)
					{
						for (int p = 1; p <= N;p++)
						{
							if (map[t][p] == 19)
								map[t][p] -= 20;
							else if (map[t][p] == 39)
								map[t][p] -= 40;

							mciSendString(L"open ./res/start.wav alias BGM", 0, 0, 0);
							mciSendString(L"play BGM", 0, 0, 0);
							
							window_set();
							Sleep(5);
						}
					}
					MessageBox(hwnd, L"失败!", L"", MB_OK);
					mciSendString(L"close BGM", NULL, 0, NULL);
					return 0;//失败
				}
			}
		}
		for (int i = 1; i <= N; i++)
		{
			for (int j = 1; j <= N; j++)
			{
				if (map[i][j] == 19 || map[i][j] == 39)
				{
					num++;
				}
				if (map[i][j]>= 0 && map[i][j] < 9)
				{
					num++;
				}

				if (num == N*N)
				{
					window_set();
					MessageBox(hwnd, L"VICTORY!", L"", MB_OK);
					N++;
					return 1;//成功
				}
			}
		}
	}

 6.源代码

#include<stdio.h>
#include<time.h>
#include<stdlib.h>//随机数srand
#include<graphics.h>
#include <windows.h>
#pragma comment(lib,"winmm.lib")

int N = 10;//雷最少的数量,横纵数量
#define K 50//足够大的数组
int map[K][K];//全局变量初始时是0
IMAGE img[12];
#define SIZE 50
HWND    hwnd;

//初始化游戏
void game_init()
{
	srand((unsigned int)time(NULL));//得到非伪随机数
	//init matrix
	for (int i = 0; i < K; i++)
	{
		for (int j = 0; j < K; j++)
			map[i][j] = 0;
	}
	int a=0;
	while (a >= 3*N||a <= N)//随机雷数量
		a = rand() % (3*N);
	//为后面方便,留空外框
	//埋雷,-1 雷
	for (int i = 0; i < a;)
	{
		int r = rand() % N + 1;//随机行(1~10)
		int c = rand() % N + 1;//随机列
		if (map[r][c] == 0)
		{
			map[r][c] = -1;
			i++;
		}
	}
	//得出其他元素的值--安全区周围的雷数
	for (int i = 1; i <= N; i++)
	for (int j = 1; j <= N; j++)
	{
		if (map[i][j] != -1)
		for (int m = i - 1; m <= i + 1; m++)
		for (int n = j - 1; n <= j + 1; n++)
		{
			if (map[m][n] == -1)
				map[i][j] += 1;
		}
	}
	//隐藏,点一下就减去20恢复
	for (int i = 1; i <= N; i++)
	for (int j = 1; j <= N; j++)
	{
		map[i][j] += 20;
	}

	hwnd = GetHWnd();
}

//游戏窗口刷新
void window_set()
{
	for (int i = 0; i < N; i++)
	for (int j = 0; j < N; j++)
	{
		if (map[i + 1][j + 1] == -1)
		{
			putimage(i*SIZE, j*SIZE, &img[9]);//雷
		}
		else if (map[i + 1][j + 1] >= 0 && map[i + 1][j + 1] <= 8)//0~8,非雷
			putimage(i*SIZE, j*SIZE, &img[map[i + 1][j + 1]]);
		else if (map[i + 1][j + 1] >= 19 && map[i + 1][j + 1] <= 28)//19~28,隐藏的
			putimage(i*SIZE, j*SIZE, &img[10]);
		else if (map[i + 1][j + 1] >= 39 && map[i + 1][j + 1] <= 48)//29~38,标记
			putimage(i*SIZE, j*SIZE, &img[11]);
	}  
}

//点0后,递归把周围的0打开
void openZero(int x, int y)
{
	map[x][y] -= 20;
	for (int i = x - 1; i <= x + 1; i++)
	{
		for (int j = y - 1; j <= y + 1; j++)
		{
			if (i >= 1 && i <= N&&j >= 1 && j <= N)
			{
				if (map[i][j] >= 19 && map[i][j] <= 28)
				{
					if (map[i][j] == 20)
						openZero(i, j);
					else
						map[i][j] -= 20;
				}
			}
		}
	}
}

//鼠标点击玩游戏
void playGame()
{
	MOUSEMSG msg = { 0 };//定义鼠标消息

	msg = GetMouseMsg();//获取
	switch (msg.uMsg)
	{
	case WM_LBUTTONDOWN:
		if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] == 20)//
			openZero(msg.x / SIZE + 1, msg.y / SIZE + 1);
		else if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 19 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 28)
			map[msg.x / SIZE + 1][msg.y / SIZE + 1] -= 20;
		break;
	case WM_RBUTTONDOWN:
		if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 19 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 28)
			map[msg.x / SIZE + 1][msg.y / SIZE + 1] += 20;
		else if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 39 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 48)
			map[msg.x / SIZE + 1][msg.y / SIZE + 1] -= 20;
		break;
	}
}


int game()
{
	game_init();
	
	while (1)
	{
		int num = 0;
		window_set();
		playGame();
		//如果矩阵里出现-1,就结束了
		for (int i = 1; i <= N; i++)
		{
			for (int j = 1; j <= N; j++)
			{
				if (map[i][j] == -1)
				{
					window_set();
					for (int t = 1; t <= N; t++)
					{
						for (int p = 1; p <= N;p++)
						{
							if (map[t][p] == 19)
								map[t][p] -= 20;
							else if (map[t][p] == 39)
								map[t][p] -= 40;

							mciSendString(L"open ./res/start.wav alias BGM", 0, 0, 0);
							mciSendString(L"play BGM", 0, 0, 0);
							
							window_set();
							Sleep(5);
						}
					}
					MessageBox(hwnd, L"失败!", L"", MB_OK);
					mciSendString(L"close BGM", NULL, 0, NULL);
					return 0;//失败
				}
			}
		}
		for (int i = 1; i <= N; i++)
		{
			for (int j = 1; j <= N; j++)
			{
				if (map[i][j] == 19 || map[i][j] == 39)
				{
					num++;
				}
				if (map[i][j]>= 0 && map[i][j] < 9)
				{
					num++;
				}

				if (num == N*N)
				{
					window_set();
					MessageBox(hwnd, L"VICTORY!", L"", MB_OK);
					N++;
					return 1;//成功
				}
			}
		}
	}
	return 1;
}
void loadimg()
{
	initgraph(N*SIZE, N*SIZE);
	loadimage(&img[0], L"./res/0.jpg", SIZE, SIZE);
	loadimage(&img[1], L"./res/1.jpg", SIZE, SIZE);
	loadimage(&img[2], L"./res/2.jpg", SIZE, SIZE);
	loadimage(&img[3], L"./res/3.jpg", SIZE, SIZE);
	loadimage(&img[4], L"./res/4.jpg", SIZE, SIZE);
	loadimage(&img[5], L"./res/5.jpg", SIZE, SIZE);
	loadimage(&img[6], L"./res/6.jpg", SIZE, SIZE);
	loadimage(&img[7], L"./res/7.jpg", SIZE, SIZE);
	loadimage(&img[8], L"./res/8.jpg", SIZE, SIZE);
	loadimage(&img[9], L"./res/9.jpg", SIZE, SIZE);
	loadimage(&img[10], L"./res/10.jpg", SIZE, SIZE);
	loadimage(&img[11], L"./res/11.jpg", SIZE, SIZE);
}
int main()
{
	
	while (1)
	{
		loadimg();
		int k = game();
		
	}
	return 0;
}
发布了16 篇原创文章 · 获赞 16 · 访问量 2349

猜你喜欢

转载自blog.csdn.net/weixin_42204569/article/details/105044578
今日推荐