輕鬆實現經典小遊戲——掃雷

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;
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章