(首先我是一个刚学C语言的新手🙏还在军训中,这是针对我对解决扫雷游戏的难点和思维理解,从一个新手的角度可能会遇到的问题的讲解(只是针对详细的问题分享,没有所有具体代码讲解,可能会存在不足请大家见谅)
1.game.h
---相关函数的说明和定义
2.game.c
---代码的微观逻辑
3.test.c
---代码的宏观布局
- 关于棋盘初步理解可能会有的问题
首先,扫雷需要一个二维数组,
void game()
{
char mine [ROWS][COLS];
char show[ROWS][COLS];
}
~~~~分界线~~~~~~~~~~
ROW中文的意思是行
COL中文意思是列
mine中文意思是雷
(mine和 show就是一个函数的名字而已,对新手来说,可能看上去很复杂,但是你其实输什么代替它都行,只是说用这种形式形成习惯可能对以后要方便点以及能看懂,以及row col其实你直接输数字也行,但用这种形式只有可能改动数据的时候,只需要改一个地方就行(我自己的理解)就是说char a[数字][数字]和上面是一样的)
在game.h头文件中定义ROW COL为9
定义ROWS COLS为11
定义如下:
~~~~~~~分界线~~~~~~~
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
~~~~~~分界线~~~~~~~~
问题一:为什么要用char类型
因为我们要打印两个二维数组,一个数组放雷,点开一个坐标后,如果不是雷,为了显示周围有几个雷,用另一个数组来放周围有几个雷的结果,放雷的那个数组为了保持神秘感用*填满棋盘,而在后续的棋盘定义中为了更方便(后面细说),所以说两个数组都用char类型
问题二:为什么要定义ROWS和ROW以及COLS COL
一般把雷放在9×9棋盘中,而当如果你输入边界坐标
如(8 6)时会发生越界的情况,所以我们实际要打印11×11的棋盘,但是把雷和输入坐标限制在9×9的棋盘中
问题三:为什么要两个二维数组?一个棋盘放雷,另一个棋盘放周围几个雷的数字,这样的话会更方便。当我们玩扫雷时,我们能看到的只是show棋盘,显示几个雷的数字的棋盘。放雷的mine棋盘可以用//隐藏起来,看不到雷在哪个坐标(show就是看的意思嘛)
- 定义棋盘以及打印棋盘可能会有的问题
我们可以通过双重的for循环来实现打印棋盘
1.定义棋盘(就是初始化棋盘)
在test.c中
ini是initialize(初始化的意思)的筒写
board是棋盘的意思
(上文说到的方便)由于mine 和show用的都是char类型的所以说用一个函数iniboard就行mine棋盘中要都是字符0也就是'0'后续中用int x=rand()%9+1 int y=rand()%9+1 让(x y)随机坐标放到mine中去作为雷的坐标( 后续细讲)用同一个函数 我们的实参分别是'0'和'*',以及mine和show,那形参就可以只用一个字符set替代'0'和'*',用a来代表mine和show。如果不让0变为'0'那我就要写一个int类型的函数和一个char类型函数,来分别初始化,会变得麻烦。
game.c:
#include "game.h"
void iniboard(char a[ROWS][COLS], int rows, int cols, char b)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int h = 0;
for (h = 0; h < cols; h++)
{
a[i][h] = b;
}
}
}
void setboard(char a[ROWS][COLS], int row, int col)
{
int k = 0;
printf("---------------------\n");
for (k = 0; k <= col; k++)
{
printf("%d ", k);
}
printf("\n");
for (k = 1; k <= row; k++)
{
printf("%d ", k);
int f = 0;
for (f = 1; f <= col; f++)
{
printf("%c ", a[k][f]);
}
printf("\n");
}
}
2.打印棋盘
注意每个函数中的a是代表着对应的实参,像初始化中的a代表着mine和show,要看你test.c中void game()中的函数的实参是啥,可能打到后面a多了就会搞混,当然,一般来说都是写board代表而不是写a,你想写什么代表都行,只是我想方便点写a。在打印棋盘中,你的实参如果选择的是mine(mine定义的是'0'),你就会得到0棋盘,选择的是show(定义的是'*')你就会得到*棋盘
- 设置雷可能遇到的问题
- void setmine(char a[ROWS][COLS], int row, int col)
{
int count = 10;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (a[x][y] == '0')
{
a[x][y] = '1';
count--;
}
}
}
1.任何一个数%上9的余数,范围是0到8
所以int x=rand()%9+1的范围是1到9
2.如果想看到雷的分布,要把
setboard(mine, ROW, COL);放到setmine的后面
- 发现雷可能遇到的问题
int all(char mine[ROWS][COLS], int x, int y)
{
return (mine[x-1][y] + mine[x-1][y+1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y - 1] - 8 * '0');
}
1.因为在发现雷过程中,我们需要把mine函数的信息传递给show,所以我们实参中要包含他们两个,这时候就用mine show作为他们的形参,再用a的话就可能搞混
2.在算周围有几个雷的时候,最好画一个井字格
中间为(x y)再把周围几个补齐,再输进去,确保不会出错
3.数字+'0'='数字',同理,当显示周围有几个雷的数字的时候要加上'0',变为char的类型传给show,以及'数字'-'0'=数字
~~~~~分界线~~~~~~~~
以上就是我对于扫雷游戏过程中遇到的疑难点的分享以及提醒点,该篇文章我在大一军训休息的时候写的,一个人在这里看代码,想着怎么把这个东西讲清楚,好累(ಥ_ಥ)。感谢大家支持!ヾ^_^♪,如果以上有什么不足的,请大佬们指出来,我会认真的反思,谢谢观看三っ•̀.̫•́)っ