.
🚀write in front🚀
🔎大家好,我是gugugu。希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
🆔本文由 gugugu 原创 CSDN首发🐒 如需转载还请通知⚠
📝个人主页:gugugu—CSDN博客
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:gugugu的系列专栏——CSDN博客
✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩
前言
在学完数组和函数之后,今天带来C语言的第二个小游戏——扫雷。
本程序对初学者来说存在一定难度,多次反复练习,加强理解即可。
本文将从设计思路,功能实现等角度进行详细教学分析。
注意:本游戏是多文件编程
一.介绍扫雷。
1.扫雷的规则
游戏规则:点击方格,如果是地雷,游戏失败,找到所有方格,而不踩到地雷游戏胜利。游戏初始,所有的方格都是被覆盖的。点开的“空”会标识数字,中心的“空”标识数字“1”,即表示其周围8个方格内仅有1颗雷,玩家需要通过这样的信息来判断正确的雷区位置并予以标识。最终排除所有地雷获胜。
看看扫雷游戏的原版是啥样的吧。
本文将介绍初阶的扫雷,进阶版将在不久之后继续更新。
2.扫雷功能模板
扫雷游戏主要由以下几个板块组成
a.菜单
b.初始化
c.打印游戏界面
d.布置雷
e.排除雷
二、扫雷功能分析
首先本游戏依旧采用do while循环的结构实现多次进行游戏的功能。
1.确定棋盘的大小和雷的个数
在这里我们需要使用宏来确定棋盘的大小和雷的个数
使用宏可以方便随时更改,而不会把程序给写死,也就是说,我们想要多大的棋盘,想要多少颗雷都可以随时更改
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2//棋盘大小
#define BOOM 10//10课雷
2.菜单
扫雷游戏的菜单和猜数字游戏菜单的实现是一个道理,详细可见猜数字游戏博客
…链接…
创建一个变量,用1表示开始游戏,用0表示结束游戏,设计一个菜单进行选择即可。
void main()
{
printf("#####################\n");
printf("########1.play#######\n");
printf("########0.exit#######\n");
printf("#####################\n");
}
3.初始化
棋盘初始化就是将界面清空,放上我们想让界面存在的东西。
void init(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;
}
}
}
4.打印
我们玩游戏的时候肯定要看到游戏界面啊,所以需要写一个函数来打印游戏界面。
也就是打印数组的内容。
但是打印的时候不能只有*啊
我们还得打印行号和列号来辅助玩家确定坐标。
void Display(char board[ROWS][COLS],int row,int col)//这个地方使用rows和cols也可以,代码差别不大
{
//分割线
printf("########扫雷########\n");
//打印列号
int i=0;
for(i=0;i<=col;i++)
{
printf("%d ",i);
}
//换行
printf("\n");
//打印棋盘内容
for(i=1;i<=row;i++)
{
int j=0;
for(j=0;j<=col;j++)//一行
{
if(j=0)
{
printf("%d ",i);//打印行号
}
else
{
printf("%c ",board[i][j]);
}
}
printf("\n");
}
printf("########扫雷########\n");
}
5.布置雷
首先我们确定雷的个数
使用宏来确定雷的个数,比较方便,易于更改
#define BOOM 10
但是记住雷的数量要布置的合理,不能出现9*9的棋盘,出现100颗雷,对吧。
- 那么雷的位置如何确定呢?
这就需要创建两个随机数分别放在x和y中,作为行号和列号。
布置雷肯定是把数组某一个位置上放雷,我们把雷记作‘1’,注意,这里的1是字符1,而不是数字1.
-
但是肯定不止布置一颗雷啊,所以需要用到循环,创建一个变量int count=BOOM;
把count作为while的判断条件,每进行一次循环count–,那么当count=0,也就是当雷布置完的时候,会自动退出循环。 -
注意,每次布置雷的时候,要确定这个地方是否已经布置过雷了,如果布置过雷的话,重新产生随机数,重新布置这颗雷。
look look!!
void getboom(char board[ROWS][COLS],int row,int col)
{
int x=0;
int y=0;
int count=BOOM;
while(count)
{
int x=rand()%row+1;
int y=rand()%col+1;
if(board[x][y]=='0')
{
board[x][y]='1';
count--;
}
}
}
6.排雷
布置好雷之后要进行排查雷,每次排查完一次之后都要进行一次排查完之后的展示
如果排到的地方是雷的话,你会被炸死,游戏结束;
如果不是雷,则在该处计算并输出旁边的八个格子内有多少颗雷;
一直循环,知道炸死,或者雷被排完。
void outboom(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{
int x=0;
int y=0;
int count=row*col-BOOM;
while(count)
{
printf("请输入坐标\n");
scanf("%d %d",&x,&y);
if(x>=1&&x<=row&&y>=1&&y<=col)
{
if(show[x][y]!='*')
{
printf("该位置已被排查,请重新输入\n”);
}
if(mine[x][y]=='1')
{
printf("很遗憾,你被炸死了\n");
break;
}
else
{
char num=getnum(mine,x,y);//需要再引入一个函数
show[x][y]=num;
display(show,ROW,COL);
}
}
else
{
printf("坐标非法,请重新输入\n");
}
7.数雷的个数
这里就需要另写一个函数来实现这个功能了,因为我们的数组show和mine都是字符数组,所以我们返回的雷的个数也需要是字符,所以将返回类型定义为char
char getnum(char board[ROWS][COLS], int x,int y)
{
return (board[x-1][y-1]+
board[x-1][y]+
board[x-1][y+1]+
board[x][y-1]+
board[x][y+1]+
board[x+1][y-1]+
board[x+1][y]+
board[x+1][y+1]-8*48+48);
}
-
来分析一下为什么会这么写
-
首先我们先解释一下为什么可以字符加减
-
每一个字符会对应一个ASCII码表, 字符会先转化为ASCII码值,用ASCII码值进行加减,再返回ASCII码表对应的字符
-
为什么要先减8*48呢?
-
因为0的ASCII码值为48,这里就是相当于8个位置都减了一个字符0
-
那为什么要加48呢?
-
如果不加48的话,那运算结果就是从ASCII值0开始,可以看上表,ASCII码值0对应的字符是不显示字符,但是字符0对应的ASCII值为48,之后加上48之后,才能从字符0开始输出。
三、效果演示
大致就是这些功能啦,更高级的功能将在下一次博客—进阶版扫雷更新,敬请期待!
四、源码
1、头文件(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
#define BOOM 10
void init(char board[ROWS][COLS], int rows, int cols, char set);
void display(char board[ROWS][COLS], int row, int col);
void getboom(char board[ROWS][COLS], int row, int col);
void outboom(char board[ROWS][COLS], int row, int col);
2、函数实现部分(game.c)
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
char numboom(char board[ROWS][COLS], int x, int y)
{
return board[x - 1][y - 1] +
board[x - 1][y] +
board[x - 1][y + 1] +
board[x][y - 1] +
board[x][y + 1] +
board[x + 1][y - 1] +
board[x + 1][y] +
board[x + 1][y + 1] - 8 * 48 + 48;
}
//初始化
void init(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 display(char board[ROWS][COLS], int row, int col)
{
printf("-------扫雷--------\n");
int i = 0;
//列号
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
//打印内容
for (i = 1; i <= row; i++)
{
int j = 0;
for (j = 0; j <= col; j++)//一行
{
if (j == 0)
{
printf("%d ", i);//行号
}
else
{
printf("%c ", board[i][j]);
}
}
printf("\n");
}
printf("-------扫雷--------\n");
}
//布置雷
void getboom(char board[ROWS][COLS], int row, int col)
{
int count = BOOM;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
//排查雷
void outboom(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = row * col - BOOM;
while (count)
{
printf("请输入坐标\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] != '*')
{
printf("位置已经排查,请重新输入\n");
}
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
display(mine, ROW, COL);
break;
}
else
{
char num = numboom(mine, x, y);
show[x][y] = num;
display(show, ROW, COL);
count--;
}
}
else
{
printf("输入的坐标非法,请重新输入\n");
}
}
if (count == 0)
{
printf("游戏获胜\n");
}
}
3、主函数部分(test.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] = { 0 };
char show[ROWS][COLS] = { 0 };
//初始化
init(mine, ROWS, COLS, '0');
init(show, ROWS, COLS, '*');
//打印
display(mine, ROW, COL);
display(show, ROW, COL);
//布置雷
getboom(mine, ROW, COL);
display(mine, ROW, COL);
//排查雷
outboom(mine, show, ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择\n");
scanf("%d", &input);
switch (input)
{
case 1:
printf("###### 扫雷 ########\n");
game();
break;
case 0:
printf("安全退出\n");
break;
default :
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
好了,到这里本期分享就结束了,不知道各位小伙伴有没有学会,可以在评论区留言哦,博主看到就会回答的。下一期进阶版扫雷将很快更新!!!敬请期待!!!!!
!!!!!!!!!!!!!!求关注!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!一键三连吧!!!!!!!!!!!!!!!!文章来源:https://www.toymoban.com/news/detail-624697.html
文章来源地址https://www.toymoban.com/news/detail-624697.html
到了这里,关于【C语言】扫雷小游戏详细分析(模块化编程)——内附源码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!