目录
前言:
大家好,我是拳击哥。今天给大家展现的是C语言实现扫雷小游戏教程和源码的展示,相信大家都知道扫雷游戏的规则,那怎么用C语言实现呢?下面我就来讲解。
1、设计框架
首先,我们要有一个菜单来选择我是开始游戏还是退出游戏。其次我们要设计控制开始或退出后程序的走向。设计完菜单后,我们要初始化雷阵,然后玩家排雷。每排一次我们要判断雷阵周围有几个雷,直到所有的雷都被排完了我们就胜利了,反之排到雷了我们就输了。有了以上思想后,我们再来看程序流程与代码吧。
编辑
2、设计流程
我们要设计五个函数:
- 菜单
- 初始化雷阵
- 生成雷
- 玩家输入坐标
- 显示周围有多少个雷
在编上述几个函数之前,我们先创建三个文件。为了程序的条理清晰,我们要模块化程序,因此创建三个文件。分别为:test.c、game.c、game.h这三个文件
编辑
game.h头文件我们把上述几个模块函数的声明放在里面,包括库函数的头文件,我们都可以放在里面。等到game.c和test.c文件要用的时候,我们直接引用game.h头文件就行。
2.1菜单
菜单就是一个简易的黑框款,里面有开始、退出两个选择。选择1就开始,选择0就退出。它的代码为:
//test.c void menu() { printf("+------------------+\n"); printf("|------1.开始------|\n"); printf("|------0.退出------|\n"); printf("+------------------+\n"); }
菜单函数我命名为menu,并且把这个函数放在了test.c里面。
编辑
2.2初始化雷阵
我们初始化雷阵我们需要两个雷盘,一个是用来排雷的雷盘,一个是显示给用户看的雷盘。排雷的雷阵里面我们可以设置雷的个数,并且用户是看不到这个雷阵的。我设置的雷盘是9*9的雷盘我们来看代码:
//game.h #include<stdio.h> #include<stdlib.h> #include<time.h> #define EasyGame 20 #define H 9 #define L 9 #define HS H+2 #define LS L+2 //game.h void InitB(char board[HS][LS], int h, int l, char rat); //test.c void test() { char mine[HS][LS] = { 0 }; char show[HS][LS] = { 0 }; InitB(mine, HS, LS, '0'); InitB(show, HS, LS, '*'); PrintB(mine, H, L); PrintB(show, H, L); SetB(mine, H, L); FindB(mine, show, H, L); } //game.c void InitB(char board[HS][LS], int h, int l, char rat) { for (int i = 0; i < h; i++) { for (int j = 0; j < l; j++) { board[i][j] = rat; } } }
我给初始化雷阵函数起名为InitB,mine是排雷雷阵,show是用户展现雷阵。那么我在test.c里面初始化这两个雷阵并且调用InitB函数来修改雷阵,mine雷阵我设置全为‘0’,show雷阵我设置全为‘*’。注意是字符类型的。InitB函数的InitB函数的定义放在game.c里面,InitB函数的声明放在game.h里面。
可能有的朋友说不是9*9的雷阵为啥传参给InitB是11*11,因为我们在判断周围有多少雷的时候假设我们输入的是第9行的坐标那么9*9的雷阵就越界了,因此我传给InitB的是雷阵是9*9我们只需要在9*9里面生成雷就好了,外面那一层里面始终是字符'0'。这样判断的时候不会造成数组越界。
编辑
2.3生成雷
生成雷我们在排雷雷阵mine里面生成,你可以任意设置你想要的雷数。
//game.h #include<stdio.h> #include<stdlib.h> #include<time.h> #define EasyGame 20 #define H 9 #define L 9 #define HS H+2 #define LS L+2 //game.h #define EasyGame 20 //game.h void SetB(char mine[HS][LS], int h, int l); //test.c void test() { char mine[HS][LS] = { 0 }; char show[HS][LS] = { 0 }; SetB(mine, H, L); } //game.c void SetB(char mine[HS][LS], int h, int l) { int count = EasyGame; while(count) { int x = rand() % h + 1; int y = rand() % l + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } }
我给生成雷函数名为SetB,EasyGame是雷数,我设置的是20个你也可以修改。 设置雷就把原来初始化雷为'0'改成'1',注意是字符0和1。
编辑
2.4玩家输入坐标
玩家输入坐标,首先得判断这个坐标之前有没有被输入过。再判断是不是雷,是雷就被炸死了。不是雷就显示用户雷阵中该坐标周围有几个雷,这时候就需要调用一个找到该坐标附近雷数的函数get_mine。
//game.h void FindB(char mine[HS][LS], char show[HS][LS], int h, int l); //game.c int get_mine(char mine[HS][LS], 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'; } //game.c void FindB(char mine[HS][LS], char show[HS][LS], int h, int l) { int x = 0; int y = 0; int win = 0; while (win<(h*l-EasyGame)) { printf("请输入您要排查的坐标:>"); scanf("%d %d", &x, &y); if (x >= 1 && x <= h && y >= 1 && y <= l) { if (show[x][y] != '*') { printf("坐标已重名,请重新输入:>\n"); continue; } if (mine[x][y] == '1') { printf("很遗憾你被炸死了...\n"); PrintB(mine, H, L); break; } else { int n=get_mine(mine, x, y); show[x][y] = n+'0'; PrintB(show, H, L); win++; } } else { printf("请输入正确的坐标:>\n"); } } if (win == (h * l - EasyGame)) printf("恭喜你,排雷成功!\n"); }
判断坐标有没有输入过。只要show雷阵里面的该坐标(输入的坐标)!=*就证明这个坐标未输入过,当然如果恰好你输入的是雷就被炸死了,没有就显示周围的雷数。
2.5显示有多少个雷
get_mine函数是怎么判断呢,假设我输入的坐标是5,5我要知道该坐标周围有几个雷这时候。把周围8个坐标加起来然后减去8*'0',假设周围有3个雷那么就是5*'0'+3*'1'-8*'0'得到的就是数字3,数字3再加字符'0'就得到了字符'3'然后赋值给show雷阵中的该坐标,这样就达成了显示该坐标有几个雷。
编辑
win是每输入一次坐标就自增一次,直到win<(h*l-EasyGame)也就是win等于没有雷的坐标总数时退出循环。
最后判断输赢的是行乘以列然后减去EasyGame,如果win等于h*l-EasyGame那么所有的雷就找到了。
3、所有程序的源码
3.1game.h
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<time.h> #define EasyGame 20 #define H 9 #define L 9 #define HS H+2 #define LS L+2 void InitB(char board[HS][LS], int h, int l, char rat); void PrintB(char show[HS][LS], int h, int l); void SetB(char mine[HS][LS], int h, int l); void FindB(char mine[HS][LS], char show[HS][LS], int h, int l);
3.2game.c
#include"game.h" void InitB(char board[HS][LS], int h, int l, char rat) { for (int i = 0; i < h; i++) { for (int j = 0; j < l; j++) { board[i][j] = rat; } } } void PrintB(char show[HS][LS], int h, int l) { printf("-----扫雷游戏------\n"); for (int i = 0; i <= l; i++) { printf("%d ", i); } printf("\n"); for (int i = 1; i <= h; i++) { printf("%d ", i); for (int j = 1; j <= l; j++) { printf("%c ", show[i][j]); } printf("\n"); } printf("-----扫雷游戏------\n"); } void SetB(char mine[HS][LS], int h, int l) { int count = EasyGame; while(count) { int x = rand() % h + 1; int y = rand() % l + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } } int get_mine(char mine[HS][LS], 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 FindB(char mine[HS][LS], char show[HS][LS], int h, int l) { int x = 0; int y = 0; int win = 0; while (win<(h*l-EasyGame)) { printf("请输入您要排查的坐标:>"); scanf("%d %d", &x, &y); if (x >= 1 && x <= h && y >= 1 && y <= l) { if (show[x][y] != '*') { printf("坐标已重名,请重新输入:>\n"); continue; } if (mine[x][y] == '1') { printf("很遗憾你被炸死了...\n"); PrintB(mine, H, L); break; } else { int n=get_mine(mine, x, y); show[x][y] = n+'0'; PrintB(show, H, L); win++; } } else { printf("请输入正确的坐标:>\n"); } } if (win == (h * l - EasyGame)) printf("恭喜你,排雷成功!\n"); }
3.3test.c
#include"game.h" void test() { char mine[HS][LS] = { 0 }; char show[HS][LS] = { 0 }; InitB(mine, HS, LS, '0'); InitB(show, HS, LS, '*'); PrintB(show, H, L); SetB(mine, H, L); FindB(mine, show, H, L); } void menu() { printf("+------------------+\n"); printf("|------1.开始------|\n"); printf("|------0.退出------|\n"); printf("+------------------+\n"); } int main() { srand((unsigned int)time(NULL)); int input = 0; do { menu(); printf("请输入您选择的数:>"); scanf("%d", &input); switch (input) { case 0:printf("您已退出游戏!\n"); break; case 1:test(); break; default:printf("请输入正确的数字:>\n"); break; } } while (input); return 0; }
本期博客就到这里结束了,如有不懂可在评论区留言
编辑
Never Give Up