数组和函数实践:扫雷游戏玩法和棋盘初始化(1)

简介: 数组和函数实践:扫雷游戏玩法和棋盘初始化(1)

各位少年,大家好,我是博主那一脸阳光,我们学会了数组,exturn声明外部文件,static修饰静态变量,那么很显然,我们需要用到我们学习这些,实现一个扫雷游戏。

扫雷游戏介绍以及玩法

在地图上布置十个雷

排查雷:如果位置是雷,就炸死了,游戏结束,不是雷,就统计 :就统计周围雷的个数,并显示。

这个1表示周围格子有雷,如果把所有非雷的位置找到,游戏结束,如果碰到雷游戏结束。

如何实现9*9扫雷

数据的分析和设计

数据结构的分析

扫雷过程中,布置雷和排查除的雷信息都需要存储,所以我们需要一定的数据结构来存储这些信息,因为我们需要在99的棋盘上布置的信息和排查雷,我们首先想到的就是创建一个99的数组来存放信息。

那如果这个位置布置雷,我们就存放1,没有布置雷就存放0.

那问题出来了,如果说我们要访问第0行第0列,我们知道一个方块等排查旁边一个元素,那么很显然,这里出现了越界。所以说要创建11杠11的模块来实现。

多文件的使用

我们在写一性大型游戏的时候,往往需要N多行代码,比如说这个比较小众的扫雷,就需要两百块C语言代码,我们才能达到最总目的

我们主要分为这三个模块性,来帮我们实现扫雷这个游戏的代码,我们会使用到自定义头文件,使用多文件会让我们代码更加方面简介,易修改。

我们创建了三个文件,然后我们来编写程序即可,test c我们放代码的文本,自定义函数在game。c中使用,然后放到test。c

game。h放头文件以及define定义,总之game点h是来测试游戏的。

#include<stdio.h>
void menu()
{
  printf("*******************\n");
  printf("******  1.play  ********\n");
  printf("******  0.exit  *********\n");
  printf("*******************\n");
}
int main()
{
  int input = 0;
  do
  {
    menu();
    priintf("请输入:");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      printf("扫雷\n");
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误,重新选择!\n");
      break;
    }
  } while (input);
  return 0;
}

do while:如果我们打开这个游戏,肯定要玩一次,先玩一次,玩完以后再判断do-while玩不玩下次的问题(1)代表false玩,0代表true假不玩,我们这里不需要多判断用switch语句是最好的。

好,我们把扫雷换成自定义函数game(),来实现这个游戏

#include<stdio.h>
void menu()
{
  printf("*******************\n");
  printf("******  1.play  ********\n");
  printf("******  0.exit  *********\n");
  printf("*******************\n");
}
int main()
{
  int input = 0;
  do
  {
    menu();
    priintf("请输入:");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      void game();
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误,重新选择!\n");
      break;
    }
  } while (input);
  return 0;
}

假设我们排查(2,5)这个坐标时,我们访问周围的⼀圈8个⻩⾊位置,统计周围雷的个数是1

假设我们排查(8,6)这个坐标时,我们访问周围的⼀圈8个⻩⾊位置,统计周围雷的个数时,最下⾯的三

个坐标就会越界,为了防⽌越界,我们在设计的时候,给数组扩⼤⼀圈,雷还是布置在中间的99的坐
标上,周围⼀圈不去布置雷就⾏,这样就解决了越界的问题。所以我们将存放数据的数组创建成11
11

是⽐较合适。

排雷的假设 周围加上⼀圈的棋盘比较合适

我们多谢几行的方面性比写代码限制效率高,存放数据的类型太多,容易产生歧义,在统计一个坐标周围的雷的个数的时候,可能会越界。

雷的隐秘,没初始化。

我们在棋盘上布置了雷,棋盘上雷的信息(1)和⾮雷的信息(0),假设我们排查了某

⼀个位置后,这个坐标处不是雷,这个坐标的周围有1个雷,那我们需要将排查出的雷的数量信息记录

存储,并打印出来,作为排雷的重要参考信息的。那这个雷的个数信息存放在哪⾥呢?如果存放在布

置雷的数组中,这样雷的信息和雷的个数信息就可能或产⽣混淆和打印上的困难。

这⾥我们肯定有办法解决,⽐如:雷和⾮雷的信息不要使⽤数字,使⽤某些字符就⾏,这样就避免冲

突了,但是这样做棋盘上有雷和⾮雷的信息,还有排查出的雷的个数信息,就⽐较混杂,不够⽅便。

这⾥我们采⽤另外⼀种⽅案,我们专⻔给⼀个棋盘(对应⼀个数组mine)存放布置好的雷的信息,再

给另外⼀个棋盘(对应另外⼀个数组show)存放排查出的雷的信息。这样就互不⼲扰了,把雷布置到

mine数组,在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期

排查参考。

同时为了保持神秘,show数组开始时初始化为字符 ‘*’,为了保持两个数组的类型⼀致,可以使⽤同⼀

套函数处理,mine数组最开始也初始化为字符’0’,布置雷改成’1’。如下

char mine[11] [11]//雷用1表示非雷0表示

```c
char show[11] [11]//雷用1表示非雷0表示
```对应的数组应该是:
char mine[11][11] = {0};//⽤来存放布置好的雷的信息
char show[11][11] = {0};//⽤来存放排查出的雷的个数信息
大家想象,如果想玩大点的扫雷游戏,不要九乘九了,要20*20是不是要更改的很麻烦
所以说这里来头文件定义两个宏
game.H
#define ROW 9
#define COL 9//后面会使用
#define ROWS ROW+2
#define COLS 11
void game()
{
char mine[ROWS][COLS]
char show[ROWS][COLS]
}

这样方便了不少,我们修改上面的宏改变整个数组的大小,改变扫雷游戏的大小。

初始化棋盘

我们写一个自定义函数 来把这个扫雷的棋盘初始化,写出来,我们自定义一个InitBoard函数,给他传三个参数

InitBoard(mine,ROWS,COLS);

你要初始化布置雷的数组你也要初始化,隐藏数组show

InitBoard(show,ROWS,COLS);

game.h这里需要放一个函数的声明,如果以后后期改游戏配置会在game头文件中更改

void InitBoard(char arr[ROWS][COLS], int rows, int cols);

然后我们在game .c里实现

#include"game.h"
void InitBoard(char arr[ROWS][COLS], int rows, int cols)
{
  int i = 0;
  for (i = 0; i < rows; i++)
  {
    int j = 0;
    for (j = 0; j < cols; j++)
    {
      arr[i][j] = 0;
    }
  }
}

那问题出来了,我们得初始化o,那么*就是遮住棋盘的符号怎么打印呢?再写一个,是可以的,但是有点挫,那我们如何用一个game点c的模板,完成两个数组的初始化呢?那我们再传入一个参数**或者0传进去

test。c

void game()
{
  char mine[ROWS][COLS];
  char show[ROWS][COLS];
  InitBoard(mine, ROWS, COLS,'0');
  InitBoard(show, ROWS, COLS,'*');
}

game .c

#include"game.h"
void InitBoard(char arr[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++)
    {
      arr[i][j] = set;
    }
  }
}

.game.h

```c
void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set);

我们实现了扫雷棋盘的打印,通过循环的方式把扫雷的基本模型实现了,但是我们得打印出来呀?判断输赢呀?

由于篇幅的问题,我们只能下篇分析介绍

相关文章
|
6月前
|
存储
数组和函数实践:扫雷游戏
数组和函数实践:扫雷游戏
|
6月前
|
存储 算法 编译器
扫雷游戏棋盘的打印,判断输赢,深度分析
扫雷游戏棋盘的打印,判断输赢,深度分析
|
6月前
扫雷游戏(优化版)
扫雷游戏(优化版)
60 0
扫雷游戏(优化版)
[C语言][小游戏][猜拳游戏]
[C语言][小游戏][猜拳游戏]
[C语言][小游戏][猜拳游戏]
|
C语言
扫雷游戏(数组与函数实现)
扫雷游戏(数组与函数实现)
小白的第二个项目--扫雷游戏
小白的第二个项目--扫雷游戏
90 0
|
存储 数据可视化
扫雷游戏简单实现
扫雷游戏简单实现
|
存储 算法 程序员
软件协会第01次活动第04次任务布置:爱心代码+数组练习
软件协会第01次活动第04次任务布置:爱心代码+数组练习
222 0
井字棋和扫雷游戏代码解析
设置一个game.h用于声明函数 设置一个test.c用于正常运行,调用函数 设置一个game.c用于函数的实现