用C语言实现扫雷游戏
话不多说先看效果;
代码:小小少年的GitHub
那么要实现这个游戏有下面几步:
分析
我们先列个表:1.要创建数组存放信息,一个是user显示给玩家,一个是mine存放雷。
2.初始化,打印雷盘;雷盘(mine)全初始化为‘0’,玩家全为‘*’
3.放雷:要往数组里随机放雷(字符‘1’),非雷则放(字符‘0’)。(到下面解释为什么)
4.找雷:输入坐标,4.1 统计周围8个位置的雷的个数,并显示雷的个数
4.2 没有雷的话就展开非雷区
4.3 有雷的话就炸死了。
4.4 第一次不会被炸死。
1.创建数组
void game()
{
char mine[ROWS][COLS] = {0}; //创建数组用来存雷
char user[ROWS][COLS] = {0}; //用来存放雷的个数并显示给玩家
init(mine, '0', ROWS, COLS); //初始化雷盘
init(user, '*', ROWS, COLS); //初始化显示盘
Display(user, ROW, COL); //显示函数用来打印 数组(mine ,user)
place_mine(mine,ROWS,COLS,MINE_NUM); //放置雷
fine_mine(mine, user, ROWS, COLS); //输入坐标找雷
}
2.初始化数组
void init(char arr[ROWS][COLS],char target,int rows,int cols)
{
memset(arr,target,rows*cols*sizeof(arr[0][0]));
}
将数组arr全部初始化为target(是传入的字符)
3.放置雷
在数组mine中放置mine_num个雷
void place_mine(char mine[ROWS][COLS],int rows,int cols,int mine_num)
{
int n, m;
while (mine_num)
{
n = rand() % 9 + 1;
m = rand() % 9 + 1;
if (mine[n][m] != '1')
{
mine[n][m] = '1';
mine_num--;
}
}
}
4.寻找雷
函数参数需要 mine[ROWS][COLS],user[ROWS][COLS],rows,cols,判断玩家输入的坐标(x,y),的位置是否有雷
如果是第一次输入有雷的话,就将雷移到没有 雷的位置,保证第一次不死。没有雷的话就展开非雷区
void fine_mine(char mine[ROWS][COLS],char user[ROWS][COLS],int rows,int cols)
{
int x, y;
int ret;
while(1)
{
int count = 1;
printf("请输入座标:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= rows - 2 && y >= 1 && y <= cols - 2)
{
if (mine[x][y] == '1')
{
if (count == 1)
{
mine[x][y] = '0';
while (1)
{
int n; int m;
n = rand() % 9 + 1;
m = rand() % 9 + 1;
if (mine[n][m] != '1')
{
mine[n][m] = '1';
break;
}
}
open_to_mine(mine, user, x, y);
}
else
{
printf("很遗憾你被炸死乐!!!!!!!!!!!!\n");
break;
}
}
else
{
open_to_mine(mine,user, x, y);
}
}
Display(user, ROW, COL);
}
}
5.坐标周围雷的个数
注意:我们解释上面将雷为‘1’,非雷为‘0’,而不是其他:要统计(x,y)坐标周围的雷的个数,就可以像下面这样将周围的字符相加 减去 8*‘0’ 既是雷的个数
int is_mine(char mine[ROWS][COLS], int x, int y)
{
if(x>=1&&x<=ROW&&y>=1&&y<=COL)
{ return mine[x - 1][y] + mine[x - 1][y - 1] +
mine[x][y - 1] + mine[x + 1][y - 1] +
mine[x + 1][y] + mine[x + 1][y + 1] +
mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0';
}
}
6.展开非雷区
效果:
从上图中我们可以看出,如果没雷的话,就将这块非雷区,一直展开,直到格子周围有雷,并将雷数显示出来。再看下面分析:
红色为输入坐标,周围没雷,就以周围8个格子分别为中心(可假设为输入坐标)向外展开,就是分别计算8个格子他们周围的雷数,有雷就写上雷的个数(就是黄色的框)并停止向外展开,否则继续展开。
在这里我们使用递归的思想:1.停止条件:格子周围有雷
2.不断展开,不断接近条件
代码:
int open_to_mine(char mine[ROWS][COLS], char user[ROWS][COLS],static int x,static int y)
{
if (x >= 1 && x <= ROW&&y >= 1 && y <= COL&&user[x][y]=='*') {
if (is_mine(mine, x, y)!=0)
{
user[x][y] = is_mine(mine,x, y) + '0';
}
else
{
user[x][y] = ' ';
open_to_mine(mine, user, x - 1, y);
open_to_mine(mine, user, x - 1, y-1);
open_to_mine(mine, user, x , y-1);
open_to_mine(mine, user, x +1, y-1);
open_to_mine(mine, user, x +1, y);
open_to_mine(mine, user, x +1, y+1);
open_to_mine(mine, user, x , y+1);
open_to_mine(mine, user, x - 1, y+1);
}
}
}
my_main.c我的主函数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "game.h"
void menu()
{
printf("*******************\n");
printf("****1.开始游戏*****\n");
printf("****0.结束游戏*****\n");
printf("*******************\n");
}
void test()
{
int n;
do
{
menu();
printf("请输入你的选择:>");
scanf("%d", &n);
switch (n)
{
case 1:
game();
break;
case 0:
printf("退出游戏!");
break;
default:
printf("输入有误!");
}
} while (n);
}
int main()
{
srand((unsigned)time(NULL));
test();
system("pause");
return 0;
}
总结:
游戏的基本功能,到这算是实现了,但还没完,随着进一步的学习将会不断完善,大家可以一直关注,或者有问题可在下方评论。