今天我们讲如何用C语言编写出一个简单扫雷,扫雷也算是一个比较原始的游戏了吧,那么我们今天就来实现他!
首先我们要来缕一缕游戏框架
我们在代码中我们肯定会写许多函数来实现扫雷,那么我们为了简便看出游戏的运行逻辑,我们创建一个test.c的源文件来进行大体代码主体的实现,那么我们再创建一个game.c来写各种游戏部分的功能函数,最后因为功能函数和其他库函数使用时都要声明函数和引头文件所以我们建立一个头文件game.h用来解决这些问题!!!如下!
首先我们从第一步开始布局,test.c为主体框架所以我们跟着test.c来进行讲解!首先我们先看完成的菜单选择,如下:
do while 循环里运用switch语句来完成!然后一一看看内容·!
menu菜单
因为简洁版我们就不弄那么复杂了!
void game( ) 游戏大体功能
InitBorad(mine, ROWS, COLS, '0'); InitBorad(show, ROWS, COLS, '*'); Setmine(mine, ROW, COL); Print(show, ROW, COL); Print(mine, ROW, COL); Findmine(mine, show, ROW, COL);
这些函数都是放在game.c来编写实现的!!!
下面一一剖析
建立两个数组和 ROWS 和 COLS 及 ROW和 COL的原因
首先我们肯定是要运用数组知识来完成扫雷但为什么要建立两个数组呢?原因是---->一边我们要在数组中埋雷(即”1“)放在棋盘里,但我们刚开始和过程又必须要将棋盘的各各位置隐藏(即”*“)而且再扫雷过程中要显示无雷位置周围的雷数数字,所以我们必须用一个棋盘用作比对棋盘,另一个用作显示给玩家,所以我们建立两个数组即show和mine两个数组。然后是ROWS,COLS,ROW,COL为什么会有这些呢,首先我们要知道当我们在检周围雷数时是3X3的范围,当我们棋盘时ROW X COL时 ,比如9X9时,在边缘检验周围雷数时就会越界,为了不让它越界我们就要在原来多加两行两数确保四边都空一行防止越界,所以我们就有了COWS,COLS。
InitBorad(mine, ROWS, COLS, '0') InitBorad(show, ROWS, COLS, '*') ------格式化
就简单的赋值进数组中,show数组全为”*“,mine则先赋值为”0“,后续在进行设置雷!
Setmine(mine, ROW, COL)---------设置雷的位置
这里用到设置随机数的知识,其实就是运用rand(),但也要利用时间戳来设置为种子,这样我们才可以使每次的随机数不一样,在这里便可以每把雷的位置不一样.
int Getmine(char arr[ROWS][COLS], int x, int y)
这个函数是一个检查周围雷数的函数,注意的只要最后减去8个‘0’,也就是将字符类型通过转换成整型数字。
void expend(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int win)
void expend(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int win) { if (x >= 1 && x <= ROW && y >= 1 && y <= COL) //避免坐标非法 { if (mine[x][y] != '1') //确定没有踩到雷 { if (Getmine(mine, x, y) == 0) //确定其周围没有雷时展开继续进行 { if (show[x][y] == '*') //确保其展开对象是* { show[x][y] = ' '; int i = 0, j = 0; for (i = x - 1; i <= x + 1; i++) { for (j = y - 1; j <= y + 1; j++) { if (show[i][j] == '*') { expend(mine, show, i, j, win); } } } } win++; } else //当其周围有雷时显示雷数 { show[x][y] = Getmine(mine, x, y) + '0'; } } } }
这个函数便是展开函数,通过上面函数可以看见我们用到了很多if语句,主要的功能其旁边也写有注释,各位可以看注释进行理解!
void Findmine(char mine[ROWS][COLS],char show [ROWS][COLS],int row,int col)
void Findmine(char mine[ROWS][COLS],char show [ROWS][COLS],int row,int col) { int x, y,win=0; while(win<row*col-Easy_count) { scanf("%d %d", &x, &y); if (0 < x && x <= row && y <= col && y > 0 ) { if (mine[x][y] == '1') { printf("太可惜了,您踩到雷了呢~~~~~\n"); break; } else if (show[x][y]!='*') { printf("老弟位置已排过雷了呢~~~~~~"); printf("\n您可以重新输入坐标呢~~~~~\n"); } else if(mine[x][y]=='0') { expend(mine, show, x, y, win); printf("恭喜你排雷成功了\n"); Print(show, ROW, COL); } } if (win == row * col - Easy_count) { printf("恭喜你游戏胜利了呢~~~~~~~\n"); printf("您是否决定在玩一把呢~~~~~~~~~\n\n"); break; } } }
这个函数就是玩家操作的函数,通过输入坐标进行开始扫雷,代码中的win便是函数棋盘中的*的数量。
最后这篇文章的其他细节需要各位慢慢消化,有不懂的可以私聊我!最后给大家展示所有的代码。
game.h
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<time.h> #include<stdlib.h> #define ROWS 11 #define COLS 11 #define ROW 9 #define COL 9 #define Easy_count 10 void InitBorad(char board[ROWS][COLS], int rows, int cols, char set); void Print(char board[ROWS][COLS], int row, int col); void Setmine(char board[ROWS][COLS], int row, int col); void Findmine(char mine[ROWS][COLS], char[ROWS][COLS], int row, int col); int Getmine(char arr[ROWS][COLS], int x, int y); void expend(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int win);
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" menu() { printf("******************************************\n"); printf("******************************************\n"); printf("*********** 1. play 0.exit *************\n"); printf("******************************************\n"); printf("******************************************\n"); } void game() { char mine[ROWS][COLS]; char show[ROWS][COLS]; //建立两个数组 InitBorad(mine, ROWS, COLS, '0'); InitBorad(show, ROWS, COLS, '*'); Setmine(mine, ROW, COL); Print(show, ROW, COL); Print(mine, ROW, COL); Findmine(mine, show, ROW, COL); } int main() { int input, i; srand((unsigned int)time(NULL)); do { menu(); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏了"); break; default : printf("输入错误"); break; } } while (input); return 0; }
game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void InitBorad(char board[ROWS][COLS],int rows,int cols ,char set) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = set; } } } void Print(char board[ROWS][COLS], int row, int col) { int i, j; for (i = 0; i <= col; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } printf("\n"); } void Setmine(char board[ROWS][COLS],int row,int col) { int x, y; int count = Easy_count; while (count) { x = rand() % row + 1; y = rand() % col + 1; if (board[x][y] != 1&&x<=ROW&&y<=COL) { board[x][y] = '1'; count--; } } } int Getmine(char arr[ROWS][COLS], int x, int y) { return (arr[x - 1][y - 1] + arr[x - 1][y] + arr[x - 1][y + 1] + arr[x][y - 1] + arr[x][y + 1] + arr[x + 1][y - 1] + arr[x + 1][y + 1] + arr[x + 1][y] - 8 * '0'); } void expend(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int win) { if (x >= 1 && x <= ROW && y >= 1 && y <= COL) { if (mine[x][y] != '1') { if (Getmine(mine, x, y) == 0) { if (show[x][y] == '*') { show[x][y] = ' '; int i = 0, j = 0; for (i = x - 1; i <= x + 1; i++) { for (j = y - 1; j <= y + 1; j++) { if (show[i][j] == '*') { expend(mine, show, i, j, win); } } } } win++; } else { show[x][y] = Getmine(mine, x, y) + '0'; } } } } void Findmine(char mine[ROWS][COLS],char show [ROWS][COLS],int row,int col) { int x, y,win=0; while(win<row*col-Easy_count) { scanf("%d %d", &x, &y); if (0 < x && x <= row && y <= col && y > 0 ) { if (mine[x][y] == '1') { printf("太可惜了,您踩到雷了呢~~~~~\n"); break; } else if (show[x][y]!='*') { printf("老弟位置已排过雷了呢~~~~~~"); printf("\n您可以重新输入坐标呢~~~~~\n"); } else if(mine[x][y]=='0') { expend(mine, show, x, y, win); printf("恭喜你排雷成功了\n"); Print(show, ROW, COL); } } if (win == row * col - Easy_count) { printf("恭喜你游戏胜利了呢~~~~~~~\n"); printf("您是否决定在玩一把呢~~~~~~~~~\n\n"); break; } } }
今天这篇文章就结束了!
希望大家多多支持!