C语言扫雷游戏
程序员文章站
2024-03-18 13:44:52
...
Window上最经典的游戏肯定免不了扫雷游戏了,那么如何用C语言写一个自己的扫雷游戏。为了写一个扫雷游戏,一定要先搞清楚如何尽心一个游戏整个过程的设计,在游戏代码的构建之前,一定要将游戏每一步搞清楚,然后将游戏按照步骤进行逐步实现,这样写出来的游戏,才会最大限度的满足自己的要求。
扫雷游戏的只要思路是:
- 进行一次游戏是否开始的选择,并且在一次游戏结束后,不用退出游戏,然后重新开始,而是可以通过输入,重新进行一次游戏的选择。
- 将扫雷游戏的游戏地图打印出来,为玩家进行游戏提供一个图形界面。
- 获取玩家输入的数据,判断数据的有效性。
- 进行一个玩家是否是否踩雷的判断,如果踩雷了,那就结束游戏。否则继续进行游戏。
- 如果在第四部没有踩到雷,则重新进行游戏地图的打印,并且将游戏中已经翻开的位置也打印出来。如果翻开的位置的周围8个格子中有雷,则就在翻开的格子中计算出8个格子中所有的雷的总数,写在格子中。
接下来就是实现这个游戏了,首先要进行的是,进行一个常量的声明。在游戏的开始,需要创建一个存放雷的数组,这个数组的大小就是创建的常量的大小。并且还要声明一个雷的数量。然后通过这个数组中所记录数据,获得雷的位置。然后就是按照我们一开始所准备的进行一个游戏的选择,然后进行游戏的地图的打印,实现游戏重复开始的选择。
//头文件"Game.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define ROW 12
#define COL 12
#define MINE 10
void PrintMap(char ArrMap[ROW][COL]);
int Game(char ArrMine[ROW][COL]);
#define _CRT_SECURE_NO_WARNINGS 1
#include "Game.h"
int main()
{
int Chick = 0;
srand((unsigned int)time(NULL));
char ArrMine[ROW][COL] = { 0 };
char ArrMap[ROW][COL] = { 0 };
int key = 0;
printf("================================\n");
printf("====== 1.Start ======\n");
printf("====== 0.Exit ======\n");
printf("================================\n");
while (1)
{
printf("请选择:>");
scanf("%d", &key);
if (key == 1)
{
PrintMap(ArrMap);
Chick = Game(ArrMine);
}
else if (key > 1 && key < 0)
{
continue;
}
else
{
break;
}
if (Chick == 0)
{
printf("游戏结束,玩家扫雷失败!\n");
printf("================================\n");
printf("====== 1.Start ======\n");
printf("====== 0.Exit ======\n");
printf("================================\n");
}
if (Chick == 1)
{
printf("游戏结束,玩家扫雷成功!\n");
printf("================================\n");
printf("====== 1.Start ======\n");
printf("====== 0.Exit ======\n");
printf("================================\n");
}
}
system("pause");
return 0;
}
void PrintMap(char ArrMap[ROW][COL])
{
int row = 1;
int col = 1;
int k = 0;
int x = 1;
int y = 1;
printf(" ");
while (x <= COL)//打印列标
{
if (x>9)
{
printf("%d ", x);
}
else
{
printf(" %d ", x);
}
if (x == COL)
{
printf("\n");
}
x++;
}
for (row = 1; row <= ROW; ++row)
{
printf("%2d ", y); //打印行号
y++;
for (col = 1; col <= COL; ++col)
{
if (col == COL)
{
printf(" * \n");
break;
}
printf(" * |");
}
k++;
if (k == ROW)
{
break;
}
printf(" ");
for (col = 1; col <= COL; ++col)
{
if (col == COL)
{
printf("---\n");
break;
}
printf("---|");
}
}
}
在以上代码的基础上,我们就可以进行游戏主题的搭建了。游戏的主体,游戏函数的搭建。
int Game( char ArrMine[ROW][COL])
{
int row = 0;
int col = 0;
InitMine(ArrMine);//进行雷位置的初始化
while (1)
{
printf("请输入要翻开的行和列:>\n");
scanf("%d", &row);
scanf("%d", &col);
system("cls");//清空屏幕
if (row<1 || row>ROW||col<1 || col>COL)//判断数据输入是否越界
{
printf("输入有误,请重新输入:>\n");
CountMine(ArrMine);//这个函数是最中心的函数,需要做到判断雷,然后计算周围雷的数量
continue;
}
if (ArrMine[row-1][col-1] == ' ')//判断数据输入是否重复
{
printf("输入数据重复,请重新输入:>\n");
CountMine(ArrMine);
continue;
}
if (ArrMine[row-1][col-1] == '#')//判断输入的位置是否是雷,如果是,就打印地雷图,然后结束游戏
{
PrintMine(ArrMine);
return 0;
}
if (ArrMine[row - 1][col - 1] != '#')//对不是雷,且有效的位置,进行一个赋值操作
{
ArrMine[row - 1][col - 1] = ' ';
if (ChickCount(ArrMine))//检查是否所有的除去雷的位置都翻开了吗,如果翻开了,就是真,真的话,就返回玩家胜利
{
return 1;
}
CountMine(ArrMine);//对下棋的地图进行一个打印
}
}
}
这便是游戏函数的主题,然后在这个函数内部,通过调用其他函数,实现对数据的写入,以及判定,然后将结果再一次打印出来。这个过程要在这个过程中一次性完成。中心函数CountMine(ArrMine)
void CountMine(char ArrMine[ROW][COL])
{
int row = 1;
int col = 1;
int k = 0;
int x = 1;
int y = 1;//变量声明
printf(" ");
while (x <= COL)
{
if (x > 9)
{
printf("%d ", x);
}
else
{
printf(" %d ", x);
}
if (x == COL)
{
printf("\n");
}
x++;
}//打印列标
for (row = 0; row <ROW; ++row)
{
printf("%2d ", y++);//打印行号
for (col = 0; col < COL; ++col)
{
int count_mine = 0;
if (col == COL - 1)
{
if (ArrMine[row][col] == ' ')//这里便是判断周围八个块中雷的数量的函数,因为有的中心块周围并不都是8个块,所以根据情况的不同,会有不同的判定
{
if (row == 0 && col == 0)
{
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}
if (row == ROW - 1 && col == COL - 1)
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
}
if (row == ROW - 1 && col == 0)
{
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
}
if (row == 0 && col == COL - 1)
{
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
}
if (row == 0 && col > 0 && col < COL - 1)
{
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}
if (row == ROW - 1 && col > 0 && col < COL - 1)
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
}
if (col == 0 && row > 0 && row < ROW - 1)
{
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}
if (col == COL - 1 && row > 0 && row < ROW - 1)
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
}
if ((row > 0) && (row<(ROW - 1)) && (col>0) && (col < (COL - 1)))
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}//判断雷的数量
if (count_mine == 0)
{
printf(" \n");
}
else
{
printf(" %d \n", count_mine);
}
break;
}
printf(" * \n");
break;
}
else
{
if (ArrMine[row][col] == ' ')
{
if (row == 0 && col == 0)
{
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}
if (row == ROW - 1 && col == COL - 1)
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
}
if (row == ROW - 1 && col == 0)
{
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
}
if (row == 0 && col == COL - 1)
{
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
}
if (row == 0 && col > 0 && col < COL - 1)
{
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}
if (row == ROW - 1 && col > 0 && col < COL - 1)
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
}
if (col == 0 && row > 0 && row < ROW - 1)
{
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}
if (col == COL - 1 && row > 0 && row < ROW - 1)
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
}
if ((row > 0) && (row<(ROW - 1)) && (col>0) && (col < (COL - 1)))
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}//判断雷的数量
if (count_mine==0)
{
printf(" |");
}
else
{
printf(" %d |", count_mine);
}
continue;
}
printf(" * |");
continue;
}
if (col == COL-1)
{
printf(" * \n");
break;
}
printf(" * |");
}//列的打印
k++;
if (k == ROW)
{
break;
}//判断行打印的结束
printf(" ");
for (col = 0; col < COL; ++col)
{
if (col == COL-1)
{
printf("---\n");
break;
}
printf("---|");
}//打印表格的行
}
}
中间最长的那部分就是对中心块周围的雷进行计数的判断,我会单独写出来方便你们看
if (row == 0 && col == 0)
{
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}
if (row == ROW - 1 && col == COL - 1)
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
}
if (row == ROW - 1 && col == 0)
{
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
}
if (row == 0 && col == COL - 1)
{
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
}
if (row == 0 && col > 0 && col < COL - 1)
{
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}
if (row == ROW - 1 && col > 0 && col < COL - 1)
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
}
if (col == 0 && row > 0 && row < ROW - 1)
{
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}
if (col == COL - 1 && row > 0 && row < ROW - 1)
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
}
if ((row > 0) && (row<(ROW - 1)) && (col>0) && (col < (COL - 1)))
{
if (ArrMine[row - 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row - 1][col] == '#')
count_mine += 1;
if (ArrMine[row - 1][col + 1] == '#')
count_mine += 1;
if (ArrMine[row][col - 1] == '#')
count_mine += 1;
if (ArrMine[row][col + 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col - 1] == '#')
count_mine += 1;
if (ArrMine[row + 1][col] == '#')
count_mine += 1;
if (ArrMine[row + 1][col + 1] == '#')
count_mine += 1;
}
由这张图就可以看出其中的逻辑关系。
void InitMine(char ArrMine[ROW][COL])//对雷的位置初始化的函数
{
int row = 0;
int col = 0;
for (row = 0; row < ROW;++row)
{
for (col = 0; col < COL;++col)
{
ArrMine[row][col] = 0;
}
}
int count_mine = 0;
for (count_mine = 1; count_mine <= MINE; ++count_mine)//初始化地雷数组
{
while (1)
{
row = rand() % (MINE - 1);
col = rand() % (MINE - 1);
if (ArrMine[row][col] != '#')
{
ArrMine[row][col] = '#';
break;
}
}
}
for (row = 0; row < ROW; ++row)
{
for (col = 0; col < COL; ++col)
{
if (ArrMine[row][col] != '#')
{
ArrMine[row][col] = '@';
}
}
}
}
这是对雷的位置进行初始化的函数
void PrintMine(char ArrMine[ROW][COL])//游戏失败后,进行雷的位置打印的函数
{
int row = 0;
int col = 0;
int k = 0;
int x = 1;
int y = 1;
while (x <= COL)//打印列标
{
if (x > 9)
{
printf("%d ", x);
}
else
{
printf(" %d ", x);
}
if (x == COL)
{
printf("\n");
}
x++;
}
for (row = 1; row <= ROW; ++row)
{
printf("%2d ", y); //打印行号
y++;
for (col = 1; col <= COL; ++col)
{
if (ArrMine[row - 1][col - 1] == '#')//进行字符判定,打印出所存储的字符
{
if (col == COL)
{
printf(" # \n");
break;
}
else
{
printf(" # |");
continue;
}
}
if (col == COL)
{
printf(" \n");
break;
}
printf(" |");
}
k++;
if (k == ROW)
{
break;
}
printf(" ");
for (col = 1; col <= COL; ++col)
{
if (col == COL)
{
printf("---\n");
break;
}
printf("---|");
}
}
}
这是雷的打印函数 ^
这便是我对扫雷游戏的简单实现。
上一篇: Python发送邮件
下一篇: 用JavaScript写一个猜拳小游戏