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