扫雷游戏简述:
电脑最经典的游戏了,扫雷游戏
就是有一个棋盘,表面的棋盘是空白的小方块,我们点击小方块,小方块会被掀开,下面如果是雷那么我就会被炸死,不是雷就展示这个小方块周围八个方块有多少个雷
实现思路:
我们如果要用程序来实现扫雷游戏,最初的问题是什么呢?游戏的初始化界面我们该怎么在控制面板上面显示出来。
就像下面的图片这样,行列分明的一个棋盘
这时候相比大家都想到了,我们可以打印一个二维数组,然后我要查哪个位置的就输入那个位置的坐标。就像这样
但是又有一个问题了,我们要对二维数组初始化:
1、可是同一个坐标又要显示小方块(’ * ‘)不让我们看到雷,又要在我们查找该坐标之后显示周围有多少个雷(非炸弹),这个好解决,我们就先对它初始化为’*‘,在查找过后又改变他的值为周围雷的个数,反正这两个本来就要给我们看的嘛。
2、扫雷游戏的雷都是随机的,我们不能在初始化的时候直接对其输入该坐标周围有多少个雷,那怎么办?而且布了雷不会覆盖掉原本的’*‘吗我们不就直接看到雷了。
所以我们定义了两个数组,也就是两个棋盘,一个棋盘专门用来放雷,另一个棋盘专门给我们看展示’ * ‘和雷的个数。
接下来就是,随机布雷咋办,这个也好办用这个
srand((unsigned int)time(NULL));
//这个是随机数的种子,time()返回一个改变的值
int x = rand() % RWO + 1;//RWO是行标,x为横坐标1~ROW
int y = rand() % COL + 1;//COL是列表,y为纵坐标1~COL
这样x、y就是随机在棋盘里面选一个位置,然后用一个循环,循环十次就可以随机布十个雷。布了雷,就要扫雷,没扫到雷要返回周围雷的个数,那么有这样一个想法就是把雷设为1,不是类的就为0,我们输入一个坐标,然后他帮我们把周围的数字加起来那么不就是雷的个数了吗。
不过有一点需要注意,因为我们定义的是字符串数组,所以我们不能直接把周围的数字加起来,因为我们定义的1不是数字1,而是字符1,0也是一样的,当字符做加减法的时候是用他们的ASCLL码值来计算,正好字符0,1,2,3..的ASCLL码值是连在一起的,所以我们像下面这样就可以返回周围雷的个数了。(这个board相当于是布雷的棋盘)
由于棋盘统一格式才好初始化,所以我们可以设置两个字符数组,我们返回周围雷的个数的时候要访问坐标周围的数组,我们定义九行九列的时候访问(9,9)那它的周围我们去访问不就越界了吗,所以我们初始化棋盘的时候把棋盘设置为(11,11)也就是行列都+2是为了防止数组越界访问,那么我编写游戏程序的步骤就是,先打印一个游戏界面让玩家选择是否开始游戏
然后当玩家选择开始游戏之后,我们初始化两个棋盘,一个棋盘放雷,一个棋盘展示给我们看,我们布雷和查雷都是在雷的棋盘上,展示初始化棋盘和周围雷的个数是在展示棋盘上
程序与运行效果展示
程序展示:
头文件game.h
#define _CRT_SECURE_NO_WARNINGS 1
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define BOMB 10
void InitBoard(char board[ROWS][COLS],int row,int col,char ret);
void PrintBoard(char board[ROWS][COLS],int row,int col);
void SetBomb(char mine[ROWS][COLS], int row,int col);
void FindBomb(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
test.c
#define _CRT_SECURE_NO_WARNINGS 1
# include "game.h"
void menu(void)
{
printf("********************\n");
printf("**** 1.开始游戏 ****\n");
printf("**** 0.退出游戏 ****\n");
printf("********************\n");
}
void game(void)
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//初始化棋盘
PrintBoard(show, ROW, COL);
//打印棋盘
SetBomb(mine, ROW, COL);
//布置雷
FindBomb(mine,show,ROW,COL);
//找雷
}
int main(void)
{
int input;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择是否开始游戏:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("期待您的下次游戏~~拜拜\n");
break;
default:
printf("输入错误,重新输入\n");
break;
}
} while (input);
return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
# include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char ret)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = ret;
}
}
}
void PrintBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
for (i = 0; i <= ROW; i++)
{
printf("%-2d", i);
}
printf("\n");
for (i = 1; i <= COL; i++)
{
printf("%-2d", i);
int j = 0;
for (j = 1; j <= COL; j++)
{
printf("%-2c", board[i][j]);
}
printf("\n");
}
}
void SetBomb(char mine[ROWS][COLS], int row, int col)
{
int count = BOMB;
while (count)
{
int x = rand() % ROW + 1;
int y = rand() % COL + 1;//1~9
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
char BombNum(char board[ROWS][COLS], int x, int y)
{
return (board[x + 1][y + 1] +
board[x][y + 1] +
board[x - 1][y + 1] +
board[x - 1][y] +
board[x - 1][y - 1] +
board[x][y - 1] +
board[x + 1][y] +
board[x + 1][y - 1] - 8 * '0');
}
void FindBomb(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col)
{
int win = 0;
int x = 0;
int y = 0;
while (win < ROW * COL - BOMB)
{
printf("请输入排查坐标:>");
scanf("%d %d", &x, &y);
if (x > 0 && x <= ROW && y > 0 && y <= COL)
{
if (mine[x][y] == '1')
{
printf("很抱歉,您被炸死了。\n");
PrintBoard(mine, ROW, COL);
break;
}
else if (mine[x][y] == '0')
{
show[x][y] = BombNum(mine,x,y) + '0';
PrintBoard(show, ROW, COL);
win++;
}
}
else
{
printf("坐标非法,重新输入\n");
}
}
if (win == ROW * COL - BOMB)
{
printf("扫雷成功(●ˇ∀ˇ●)\n");
}
}
运行效果
运气有点差哈