在刚刚接触c语言,遇上排雷这种设计,无疑是有很大挑战的,无论是代码行数,还是数据个数以及函数的种类,都是需要我们进行思考与考究的。现在,我将刨析排雷游戏,揭开其神秘的面纱,领略编程的魅力。
一.游戏运行前准备工作;
二.初始化棋盘;
三.打印排雷棋盘;
四.随机布置雷;
五.排除雷;
在设计这个排雷游戏时,必定会用到很多函数,否则我们的代码就会错综复杂
而函数需要先声明再使用,所以我创建了一个头文件叫做game.h,两个源文件game.c和test.c,game.c用来函数的实现,test.c用来创建游戏主体。
这里我已经将所有头文件写出来了,在源文件中直接引用#include"game.h"就行了,不需要再在源文件中加上头文件了。
首先我们的游戏要有个进入或者退出的设计,比如按1开始游戏,按0退出游戏。
这里我们可以用switch函数来实现。先输入一个数,case(1)指进入游戏,case(0)指退出游戏,default指非法输入,重新输入。我们将这个数定义为input,并使用一个while循环。并将while()里面的条件定义为input,当input输入0时,0为假,自动退出循环;输入1时,进入循环。接下来放出代码实现
同时我们需要设计一个函数menu,并引用到主体中,下面代码中menus应改为menu(),书写
时错误
这样我们就将游戏主体设计好了,接下来就是游戏运行时需要的代码了
这一切代码都将在game()函数中实现,里面也将也非常多的函数嵌套使用,包括我上面放出来的game.h里面的那些函数,接下来我将一点点阐述(这里函数的声明我就不再强调了,自己是实现时记得在game.h里面声明
首先,我的设计了两个棋盘,一个用于存放玩家看到的样子,一个是雷的位置,但其中的‘1’,‘0’,均为字符,而非数字,这样写有个优点,之后会讲到
我们玩家玩的是9*9的格子,但是如果你点边缘的位置,他会排查附近8个格子的数量,这样就超出了9*9的规模,所以我们需要再将棋盘扩大成11*11的,但呈现给玩家是9*9的,而我们许多数据需要重复使用,为了方便,我们在game.h里面定义了很多数字,比如ROW为9
1.初始化棋盘
a.首先我们需要创建两个字符数组,因为棋盘里面的‘1’,‘0’均为字符,而非整型。玩家看见的为show数组,呈现雷位置的为mine数组(玩家看不见的,只有排雷成功或者失败才呈现出来的)
b.我们需要创建一个函数来初始化数组,这一点其实并不难,只需要两个循环,我们需要打印两个不同棋盘,show--'*',mine--'0',这是初始状态,但如何在同一个函数中初始不同字符的两个字符呢?此时我们可以子啊函数中定义一个set,如下
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
此时只要在char set处写上不同字符就可以了,然后InitBoard 最后 printf("%c",set)就行了
2.打印排雷棋盘
首先定义一个函数void DisplayBoard(char board[ROWS][COLS], int row, int col) 由于虽然我们数组设计的是11*11的棋盘,但我们只需要打印出9*9的棋盘,所以循环里面i , j=1&&i , j<=ROW,COL,又ROW,COL=9;这样就可以只打印9*9的棋盘了,为什么打印9*9的棋盘,但却设计11*11的棋盘,这一点我上面有讲
代码实现如左图,但我们不知道每个位置的坐标是什么,所以我们对函数进行改进,右图为我们期待的结果
改进后代码如下,作图为game.c, 右图为test.c。这样打印就完成了。
3.随机布置雷
布置雷我们也设计一个函数:void SetMine( char mine[ROWS][COLS], int row, int col);这里我们需要随机生成10个雷,所以需要用到rand函数,所以也要在main函数中加入srand函数,但srand只用引用一次,代码如下
我们这里要将雷布置在mine数组中即雷盘中,并且雷的位置的‘0’要变成‘1’,所以设计一个while循环,假如这里要设计10个雷,指定一个数假如是count,每生成一个雷count--,而int count=EASY_COUNT;EASY_COUNT在上文的game.h中定义过,为10,如果你想设计其他个数的雷,就在game.h中EASY_COUNT的指改掉。
while的条件为count,当count减为0后为假,便自动退出循环。代码实现如下
这样我们的雷就布置完成了,接下来我们打印一下看看mine棋盘布雷是否成功,我们先不打印show棋盘,下图我们可以看到mine棋盘已经布置了十个雷
4.排除雷
首先设计一个函数:void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col),因为这次要用到两个函数,所以形参中要写出两个函数,由于这次过程太复杂,我说出大概流程,其他我在图中为大家讲解。
我们首先要运用一个函数,重复输入一对坐标排查这个坐标时候又雷,或者附近有多少雷,当这个坐标是雷时,游戏结束,打印“你被炸死了”;当他没有雷时,要显示出附近8个格子中有多少雷,这要借助另一个函数实现:int GetMineCount(char mine[ROWS][COLS], int x, int y),等下子图中会具体分析。如果排除了10个雷后,自动跳出循环,游戏结束,打印“游戏成功”。至此,游戏设计完成。接下来我在图中为大家一一解读排除雷这部分的代码
由于玩家玩的时候只能看到show棋盘,所以我们只打印show棋盘,mine棋盘只在游戏结束后呈现
接下我给大家看一下全部的代码
game.h:
#pragma warning(disable:4996) #include#include #include #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 10 //初始化棋盘 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); //打印棋盘 void DisplayBoard(char board[ROWS][COLS], int rows, int cols); //布置雷 void SetMine(char mine[ROWS][COLS], int row, int col); //排查雷 void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
game.c:
#include"game.h" #includevoid InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; for (i = 0; i < rows; i++) { int j = 0; for (j = 0; j < cols; j++) { board[i][j] = set; } } } void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0; printf("-------扫雷游戏-------\n"); for (i = 0; i <= row; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { printf("%d ", i); int j = 0; for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } printf("-------扫雷游戏-------\n"); } void SetMine(char mine[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (mine[x][y] == '0') { mine[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 + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1]-8*'0'); } void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; while (win = 1 && x <= ROW && y <= COL && y >= 1) { if (mine[x][y] == '1') { printf("你被炸死了"); DisplayBoard(mine, ROW, COL); break; } else { int count = GetMineCount(mine, x, y); show[x][y] = count + '0'; DisplayBoard(show, ROW, COL); win++; } } else { printf("非法输入"); } } if (win == row * col - EASY_COUNT) { printf("排雷成功\n"); DisplayBoard(mine, ROW, COL); } }
test.c:
#pragma warning(disable:4996) #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]; InitBoard(mine, ROWS, COLS,'0'); InitBoard(show, ROWS, COLS,'*'); //棋盘打印 // printf("\n"); DisplayBoard(show, ROW, COL); //布置雷 SetMine(mine, ROW, COL); //DisplayBoard(mine, ROW, COL); //排查雷 FindMine(mine,show ,ROW, COL); } int main() { srand((unsigned int)time(NULL)); int input; do { menu(); printf("请输入:"); scanf("%d", &input); switch (input) { case(1): game(); break; case(0): printf("退出游戏\n"); break; default: printf("选择错误,请重新输入\n"); break; } } while (input); }
这样,所有步骤都讲完了希望大家能亲手设计这个有趣的游戏