在给出的代码中,使用了以下库来实现游戏功能和图形界面:
graphics.h:这是一个基于BGI(Borland Graphics Interface)库的图形库,用于创建图形窗口、绘制图形等操作。
stdlib.h:这是C标准库中的一个头文件,提供了一些常用函数,例如srand()和rand()用于生成随机数,NULL用于表示空指针。
time.h:这是C标准库中的一个头文件,提供了时间相关的函数,例如time(NULL)用于获取当前时间的秒数。
当游戏开始时,会调用GameInit()
函数进行游戏的初始化。这个函数的作用是随机布雷、计算周围雷的数量,并将地图中的每个格子初始化为特定的值。具体来说:
- 使用
srand((unsigned int)time(NULL))
设置随机数种子,确保每次运行时生成的随机数不同。 - 将地图数组
map
的所有元素初始化为0。 - 通过随机数生成雷的位置,将指定数量(NUM)的雷(-1)放置在地图上。
- 根据雷的分布情况,遍历地图数组,对于非雷区域,统计周围8个格子中雷的数量,并将该数字存储在当前格子中。
- 最后,将地图中所有数字都加上一个偏移量(20),以便后续绘制时能够正确显示图片。
GameMap()
函数用于绘制游戏地图,并根据地图中不同的值显示相应的图片:
- 遍历地图数组,将每个格子的值打印出来,并根据格子的值选择合适的图片进行显示。具体规则如下:
- 如果格子的值为-1,表示是雷,则显示雷的图片。
- 如果格子的值在0到8之间,表示周围雷的数量,则显示对应数字的图片。
- 如果格子的值在19到28之间,表示空白区域,则显示空白图片。
- 如果格子的值大于30,表示标记区域,则显示标记图片。
OpenZero()
函数用于打开周围的0格子:
- 当玩家点击到一个值为0的格子时,程序会递归地打开周围的空白格子,直到边界或有数字的格子为止。
PlayGame()
函数实现了游戏的主要逻辑:
- 通过获取鼠标消息,判断玩家的鼠标操作。
- 当玩家左键点击时,根据点击的位置打开格子或递归打开周围的空白格子。
- 当玩家右键点击时,用于标记雷区或取消标记。
- 函数返回点击的格子的值,以便后续判断游戏输赢条件。
在main()
函数中,程序初始化图形窗口、加载图片资源,然后进入游戏循环:
- 不断绘制游戏地图、处理玩家操作,直到游戏结束。
- 当游戏结束时,根据玩家胜负情况弹出相应的消息框提示。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <graphics.h>
#pragma comment(lib,"winmm.lib")
#define ROW 50 //行
#define COL 30 //列
#define NUM 100 //雷的个数
#define SIZE 20 //图片大小
//ROW*COL - NUM =count
int count = 0; //点开的个数
int map[ROW+2][COL+2];
IMAGE img[12]; //img可以存放12张图片
void GameInit() {
//随机数种子
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++) {
if (map[m][n] == -1) {//找到一个雷
map[i][j]++;
}
}
}
}
}
}
for (int i = 1; i <= ROW; i++)
{
for (int j = 1;j <= COL;j++) {
map[i][j] += 20;
}
}
}
//绘制函数,打印二维数组中所有的元素
void GameMap() {
for (int i = 1;i <= ROW+1;i++) {
for (int j=1;j <= COL+1;j++) {
printf("%2d ", map[i][j]);
if (map[i][j] == -1) {
putimage((i - 1)*SIZE, (j - 1)*SIZE, &img[9]);
}
else if (map[i][j] >= 0 && map[i][j] <= 8) {
//数字图片
putimage((i - 1)*SIZE, (j - 1)*SIZE, &img[map[i][j]]);
}
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[11]);
}
}
printf("\n");
}
}
void OpenZero(int r,int c) {
//打开这个0
map[r][c] -= 20;
count++;
//0 辅助区0
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);
}
}
}
}
}
}
int PlyaGame() {
int r, c;
//定义一个鼠标消息
MOUSEMSG msg = { 0 };
while (1) {
msg = GetMouseMsg();
switch (msg.uMsg) {
case WM_LBUTTONDOWN: //翻开扫雷空白图片
r = msg.x / SIZE + 1;
c = msg.y / SIZE + 1;
if (map[r][c] >= 19 && map[r][c] <= 28) {
if (map[r][c] == 20) { //点到的是0
OpenZero(r,c);
}
else {
map[r][c] -= 20;
count++;
}
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] += 30;
}
else if (map[r][c] > 30) {
map[r][c] -= 50;
}
return map[r][c];
break;
}
}
}
int main()
{
//打开一个图形窗口
HWND hwnd=initgraph(ROW*SIZE, COL*SIZE, SHOWCONSOLE);
mciSendString(L"open 1.mp3 alias music", 0, 0, 0);
mciSendString(L"play music", 0, 0, 0);
//加载图片
loadimage(&img[0], L"0.jpg", SIZE,SIZE); //0
loadimage(&img[1], L"1.jpg", SIZE, SIZE);
loadimage(&img[2], L"2.jpg", SIZE, SIZE);
loadimage(&img[3], L"3.jpg", SIZE, SIZE);
loadimage(&img[4], L"4.jpg", SIZE, SIZE);
loadimage(&img[5], L"5.jpg", SIZE, SIZE);
loadimage(&img[6], L"6.jpg", SIZE, SIZE);
loadimage(&img[7], L"7.jpg", SIZE, SIZE);
loadimage(&img[8], L"8.jpg", SIZE, SIZE);//8
loadimage(&img[9], L"9.jpg", SIZE, SIZE);//雷
loadimage(&img[10], L"10.jpg", SIZE, SIZE);//空白
loadimage(&img[11], L"11.jpg", SIZE, SIZE);//标记
GameInit();
while (1) {
GameMap();
if (PlyaGame() == -1) {
GameMap();
MessageBox(hwnd, L"You are a Low B!!", L"", MB_OK);
break;
}
if (ROW*COL - NUM == count) {
GameMap();
MessageBox(hwnd, L"You are a Superman!!", L"", MB_OK);
break;
}
}
return 0;
}
/******************************************
根据雷的分布填充,其他不为雷的数据
1.遍历九宫格
2.边上的数据遍历的时候会越界
3.辅助区,游戏区
********************************************/
标签:map,游戏,img,int,C语言,格子,扫雷,loadimage,SIZE
From: https://www.cnblogs.com/luexiaomeng/p/18057403