扫雷游戏的玩法:
首先玩家按1:开始游戏;
其次玩家通过排查,输入一个非雷点坐标,直至排查完所有的非雷点坐标,在其过程中如果有一个是雷点,则游戏失败。
对于扫雷游戏的实现,我们这里采用分文件编写,这样做的使其功能责任划分,调试也更加方便;
game.h-------函数的声明
game.c--------游戏各个功能函数进行编写
test_SL.c------主函数
基本布局
1.play:开始游戏
0.exit:退出游戏
其他数字:输入不合法,重新输入
菜单:
采用switch语句对于每个部分进行编写:
int a;
do
{
menu();
scanf("%d", &a);
switch (a)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入不合法,请重新输入!\n");
break;
}
} while (a);
1、开始游戏
布置棋盘:
用数组来模拟棋盘,设置一个9*9的棋盘,判断是否存在数组越界现象
1 | ||||||||
1 | ||||||||
1 | ||||||||
1 |
若在棋盘边界位置:在计算其周围雷的个数时会出现数组越界,解决这个问题开一个11*11的数组即可。
1 | 1 | |||||||||
1 | ||||||||||
1 | ||||||||||
1 | 1 | |||||||||
1 | ||||||||||
1 | 1 | |||||||||
#define row 9
#define col 9
#define rows row+2
#define cols col+2
对于后续如果需要改变行列的数量,只需要在此处修改即可。
解决完数组越界问题后对棋盘进行初始化:
这里设置两个棋盘分别是mine[][](布置雷),show[][](排查雷)
对于mine[][]棋盘:最先初始化为‘0’,表示没有雷,游戏开始后系统自动随机生成一定数量的雷,其对应的坐标的值则变成了字符‘1’。
对于show[][]棋盘:初始化为字符‘*’,通过玩家输入一个合理化的坐标(x,y),系统将对比该点坐标在mine[][]中是否为雷点,如果是,则玩家游戏失败;如果不是,将在show[][]棋盘中更新该点坐标为周围的雷的数量。
void initborad(char arr[rows][cols], int r, int c,char set)
{
int i, j;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
arr[i][j] = set;//其中对于mine[][]初始化‘0’,show[][]初始化‘*’
}
}
}//mine[][]中‘0’表示不是雷点,‘1’表示是雷点;
打印棋盘
void disborad(char arr[rows][cols], int r, int c)
{
int i, j;
for (int i = 0; i <= r; i++)
printf("%d ", i);
printf("\n");
for (i = 1; i <= r; i++)
{
printf("%d ", i);
for (j = 1; j <= c; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
布置雷
随机产生x,y值如在mine[][]棋盘中该点为‘0’,则将该点设置为雷点,(x,y)坐标变为字符‘1’;
int count = 10;
while (count)
{
int x = rand() % 9 + 1;//1~9
int y = rand() % 9 + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
其中随机数的产生:
采用rand()函数生成随机数;(范围:0—RAND_MAX(32767))
但是rand生成的随机数是伪随机数--->种子没有变化
解决这个问题:采用srand-->初始化种子的随机值
即:srand((unsigned int)time(NULL));//返回的时间戳
(不能每次生成随机数时都要设置一个种子,设置一次即可,否则产生的随机数相差不大甚至相等)
这里还需要添加两个头文件:
#include<stdlib.h>
#include<time.h>
布置完雷后:
排查雷
首先玩家先输入一个合理的坐标,如果是雷点,则游戏失败;如若不是则在该点显示其周围的雷点数;依次,直至排查出所有的非雷点,扫雷成功。
void findmine(char mine[rows][cols], char show[rows][cols], int r, int c)
{
int x, y;
int win = 0;
while(win<row*col-10)
{
printf("请输入要排查的坐标:\n");
scanf("%d %d", &x, &y);
if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
{
if (mine[x][y] == '1')
{
printf("很遗憾你被炸死了\n");
break;
}
else
{
int n = getminecount(mine, x, y);//获取周围的雷点
show[x][y] = n + '0';
disborad(show, row, col);
win++;
}
}
else
{
printf("坐标错误!请重新输入\n");
}
}
if (win == row * col - 10)
{
printf("排雷成功!\n");
}
}
对于获取周围雷点数量:
int getminecount(char mine[rows][cols], int x, int y)
{
return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
mine[x][y - 1] + mine[x][y] + mine[x][y + 1] +
mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 9 * '0';
}
也可以写出:
static int getminecount(char mine[rows][cols], int x, int y)
{
return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
mine[x][y - 1] + mine[x][y] + mine[x][y + 1] +
mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 9 * '0';
}//加上static后将该函数设置为静态函数,只在此文件中可以访问。
2、退出游戏
直接按0即可退出游戏
3、完整代码
test_SL.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
printf("**********************\n");
printf("****** 1.play ******\n");
printf("****** 0.exit ******\n");
printf("**********************\n");
}
void game()
{
char mine[rows][cols];
char show[rows][cols];
//初始化棋盘
initborad(mine, rows, cols,'0');
initborad(show, rows, cols,'*');
//打印棋盘
//disborad(show, row, col);
//disborad(mine, row, col);
//布置雷
setmine(mine, row, col);
disborad(mine, row, col);
//排查雷
findmine(mine, show, row, col);
}
int main()
{
int a;
srand((unsigned int)time(NULL));
do
{
menu();
scanf("%d", &a);
switch (a)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入不合法,请重新输入!\n");
break;
}
} while (a);
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void initborad(char arr[rows][cols], int r, int c,char set)
{
int i, j;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
arr[i][j] = set;
}
}
}
void disborad(char arr[rows][cols], int r, int c)
{
int i, j;
for (int i = 0; i <= r; i++)
printf("%d ", i);
printf("\n");
for (i = 1; i <= r; i++)
{
printf("%d ", i);
for (j = 1; j <= c; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
void setmine(char arr[rows][cols], int r, int c)
{
int count = 10;
while (count)
{
int x = rand() % 9 + 1;//1~9
int y = rand() % 9 + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
int getminecount(char mine[rows][cols], int x, int y)
{
return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
mine[x][y - 1] + mine[x][y] + mine[x][y + 1] +
mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - 9 * '0';
}
void findmine(char mine[rows][cols], char show[rows][cols], int r, int c)
{
int x, y;
int win = 0;
while(win<row*col-10)
{
printf("请输入要排查的坐标:\n");
scanf("%d %d", &x, &y);
if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
{
if (mine[x][y] == '1')
{
printf("很遗憾你被炸死了\n");
break;
}
else
{
int n = getminecount(mine, x, y);
show[x][y] = n + '0';
disborad(show, row, col);
win++;
}
}
else
{
printf("坐标错误!请重新输入\n");
}
}
if (win == row * col - 10)
{
printf("排雷成功!\n");
}
}
game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define row 9
#define col 9
#define rows row+2
#define cols col+2
//初始化棋盘
void initborad(char arr[rows][cols], int r, int c,char set);
//打印棋盘
void disborad(char arr[rows][cols], int r, int c);
//布置雷
void setmine(char arr[rows][cols], int r, int c);
//排查雷
void findmine(char mine[rows][cols], char show[rows][cols], int r, int c);
以上就是扫雷游戏的基本思路和代码,希望有所帮助。