扫雷游戏简单实现

简介: 扫雷游戏简单实现

 目录

定义的一些变量

设计思路

为什么设计两个数组棋盘?

为什么游戏是9*9但设计数组要设计11*11?

初始化函数

为什么要把雷的棋盘初始化为0?

打印函数

布置雷

排除雷

解释为什么先前初始化记数字棋盘时选择0和1:

可以存在的优化

递归函数实现展开

借助图形库可视化能力更强

全部源码


定义的一些变量

为了代码的可读性和可操作性,开始前要定义一些值,后续有讲解:

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define Set 10

image.gif


设计思路

我们要创建两个字符串二维数组,一个用来存储雷的位置,一个用来给玩家提示信息的位置,玩家输入一个坐标,如果这个坐标是雷,就提示玩家被炸了,如果这个坐标不是雷,则提示玩家周围雷的数量,供玩家进行排雷。

为什么设计两个数组棋盘?

如果设计一个棋盘,则排雷和提示用户雷容易被干扰,代码可读性不强,而假设选择两个数组,把存储雷和排雷分开放,就可以在完成项目的同时还能使得代码可读性增强。

为什么游戏是9*9但设计数组要设计11*11?

在统计数量时,我们统计的是以该点为中心周围八个点的雷的个数,如果数组设置为9*9,那么在统计周围雷的个数时会导致越界访问,产生不必要的麻烦,因此在设计时选择11*11可以避免这样的问题。


初始化函数

棋盘被创建好了,那么就该进行初始化了,初始化后的内容就是要让用户看到的内容,在本实验的思路中,我们选择的是让用户看到的棋盘被*覆盖,但用来存放的棋盘也需要被初始化,于是初始化函数中可以加入新的参数。

为什么要把雷的棋盘初始化为0?

便于统计个数,后续的代码实现中会发现这样设置的优越性。

函数的实现:

void Initboard(char board[][COLS], int rows, int cols, char c)
{
  for (int i = 0; i < rows; i++)
  {
    for (int j = 0; j < cols; j++)
      board[i][j] = c;
  }
}

image.gif

打印函数

棋盘被设置和初始化后,就可以进行打印棋盘的函数实现了,只需要打印出数组的内容即可,要注意的是为了可读性,要打印出行和列对应的数字,代码实现如下:

void Displayboard(char board[][COLS], int row, int col)
{
  for (int i = 0; i <= row; i++)
  {
    if (i == 0)
      printf("%d|",i);
    else
        printf("%d ", i);
  }
  printf("\n");
  for (int i = 0; i < row; i++)
  {
    printf("--");
  }
  printf("\n");
  for (int i = 1; i <= row; i++)
  {
    printf("%d|", i);
    for (int j = 1; j <= col; j++)
    {
      printf("%c ", board[i][j]);
    }
    printf("\n");
  }
  printf("\n");
}

image.gif

布置雷

开头定义中我们定义了雷的个数,那么在实现函数时,基本思路是运用while循环,如果布置成功了就让雷的个数减一,直到雷的个数为0,此时判断结果为假,则此时就跳出循环,在进行判断时增加一些限制条件,判断坐标合法性等,综合考量就能得出下面的代码实现原理:

void Setmine(char mineboard[][COLS], int row, int col)
{
  int num = Set;
  while (num)
  {
    int x = rand() % row + 1;
    int y = rand() % col + 1;
    if (mineboard[x][y] == '0')
    {
      mineboard[x][y] = '1';
      num--;
    }
  }
}

image.gif


排除雷

来看实现的基本思路,玩家输入坐标,如果恰好是雷的位置那么玩家就被淘汰出局,如果不是雷的位置就显示周围雷的个数。

解释为什么先前初始化记数字棋盘时选择0和1:

在统计雷的个数的时候,统计的是周围八个格子的数据,如果先前我们选择的是#等作为雷的标记,那么在统计雷的时候就非常麻烦,但如果选择的是0和1,只需要把这些数据加起来最后减去一个'0'即可,这样就能把char类型的数据转换成int类型的数据,再返回到函数中即可。

那么具体的实现为:

int Count(char board[][COLS], int x, int y)
{
  return (board[x - 1][y] + board[x - 1][y - 1] + board[x - 1][y + 1] + board[x][y - 1] +
    board[x][y + 1] + board[x + 1][y] + board[x + 1][y - 1] + board[x + 1][y + 1]- 8*'0');
}
void FindSets(char mineboard[][COLS], char showboard[][COLS], int row, int col)
{
  int x=0, y=0;
  int nums = row * col - Set;
  while (nums)
  {
    printf("请输入坐标:-->");
    scanf("%d %d", &x, &y);
    if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
    {
      if (mineboard[x][y] == '1')
      {
        printf("被炸死了\n");
        break;
      }
      else
      {
        int ret = Count(mineboard, x, y);
        showboard[x][y] = ret + '0';
        Displayboard(showboard, ROW, COL);
        nums--;
      }
    }
    else
    {
      printf("坐标不合法,重新输入\n");
    }
  }
  if (nums == 0)
  {
    printf("扫雷成功,游戏结束\n");
  }
}

image.gif

可以存在的优化

递归函数实现展开

在实际的游戏过程中,在玩家点击一块没有雷的方格时,会将周围的部分都展开,而本文写的这个代码游戏不能达成这个效果,这里可以进行一定程度的优化,可以使用递归函数进行每个九宫格的展开。

借助图形库可视化能力更强

在实际游戏中是用了图形库的,这里只是一个简单的游戏实现,不包括图形库,图形库也可以作为代码的优化。

全部源码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define Set 10
void Initboard(char board[][COLS], int rows, int cols, char c)
{
  for (int i = 0; i < rows; i++)
  {
    for (int j = 0; j < cols; j++)
      board[i][j] = c;
  }
}
void Displayboard(char board[][COLS], int row, int col)
{
  for (int i = 0; i <= row; i++)
  {
    if (i == 0)
      printf("%d|",i);
    else
        printf("%d ", i);
  }
  printf("\n");
  for (int i = 0; i < row; i++)
  {
    printf("--");
  }
  printf("\n");
  for (int i = 1; i <= row; i++)
  {
    printf("%d|", i);
    for (int j = 1; j <= col; j++)
    {
      printf("%c ", board[i][j]);
    }
    printf("\n");
  }
  printf("\n");
}
void Setmine(char mineboard[][COLS], int row, int col)
{
  int num = Set;
  while (num)
  {
    int x = rand() % row + 1;
    int y = rand() % col + 1;
    if (mineboard[x][y] == '0')
    {
      mineboard[x][y] = '1';
      num--;
    }
  }
}
int Count(char board[][COLS], int x, int y)
{
  return (board[x - 1][y] + board[x - 1][y - 1] + board[x - 1][y + 1] + board[x][y - 1] +
    board[x][y + 1] + board[x + 1][y] + board[x + 1][y - 1] + board[x + 1][y + 1]- 8*'0');
}
void FindSets(char mineboard[][COLS], char showboard[][COLS], int row, int col)
{
  int x=0, y=0;
  int nums = row * col - Set;
  while (nums)
  {
    printf("请输入坐标:-->");
    scanf("%d %d", &x, &y);
    if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
    {
      if (mineboard[x][y] == '1')
      {
        printf("被炸死了\n");
        break;
      }
      else
      {
        int ret = Count(mineboard, x, y);
        showboard[x][y] = ret + '0';
        Displayboard(showboard, ROW, COL);
        nums--;
      }
    }
    else
    {
      printf("坐标不合法,重新输入\n");
    }
  }
  if (nums == 0)
  {
    printf("扫雷成功,游戏结束\n");
  }
}
void menu()
{
  printf("*****************************\n");
  printf("*********  1.game  **********\n");
  printf("*********  0.exit  **********\n");
  printf("*****************************\n");
}
void game()
{
  srand((unsigned int)time(NULL));
  char mineboard[ROWS][COLS];
  char showboard[ROWS][COLS];
  Initboard(mineboard, ROWS, COLS, '0');
  Initboard(showboard, ROWS, COLS, '*');
  Displayboard(showboard, ROW, COL);
  Setmine(mineboard, ROW, COL);
  FindSets(mineboard, showboard, ROW, COL);
}
int main()
{
  int input = 0;
  do
  {
    menu();
    printf("请输入:->");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      game();
      break;
    case 0:
      printf("结束游戏\n");
      break;
    default:
      printf("重新输入\n");
    }
  } while (input);
  return 0;
}

image.gif


相关文章
|
算法 JavaScript 前端开发
递归的递归之书:第五章到第九章
递归的递归之书:第五章到第九章
242 0
|
前端开发 JavaScript Python
分享76个文字特效,总有一款适合您
分享76个文字特效,总有一款适合您
129 5
|
10月前
|
机器学习/深度学习 人工智能 算法
AI与未来教育:一场革命性融合
在这个信息爆炸的时代,人工智能(AI)正逐步渗透到我们生活的每一个角落,教育领域也不例外。本文旨在探讨AI技术如何革新传统教育模式,以及这一变革可能带来的深远影响。通过分析AI在个性化学习、智能辅导系统、教育资源优化分配等方面的应用案例,揭示其对未来教育生态的重塑潜力。同时,文章也将讨论伴随技术进步而来的挑战,如数据隐私保护、教师角色转变等问题,并提出相应的解决思路和建议,为构建更加公平、高效、人性化的教育体系提供参考。
|
监控 算法 自动驾驶
目标检测算法:从理论到实践的深度探索
【7月更文第18天】目标检测,作为计算机视觉领域的核心任务之一,旨在识别图像或视频中特定对象的位置及其类别。这一技术在自动驾驶、视频监控、医疗影像分析等多个领域发挥着至关重要的作用。本文将深入浅出地介绍目标检测的基本概念、主流算法,并通过一个实际的代码示例,带您领略YOLOv5这一高效目标检测模型的魅力。
1216 11
|
安全 Java 程序员
【C++练级之路】【Lv.12】继承(你真的了解菱形虚拟继承吗?)
【C++练级之路】【Lv.12】继承(你真的了解菱形虚拟继承吗?)
131 0
|
小程序 前端开发
【微信小程序-原生开发】TDesign 实战模板——聊天气泡
【微信小程序-原生开发】TDesign 实战模板——聊天气泡
304 0
|
Linux Android开发 iOS开发
探索Android与iOS开发:平台之战还是互补共生?
在移动应用开发的浩瀚宇宙中,Android和iOS这两大星系始终吸引着无数开发者的目光。它们各自拥有独特的引力场,引领着技术潮流的方向。本文将穿梭于这两个平台的星际空间,揭示它们背后的力量对比,以及如何在这两者之间找到平衡点,共同推动移动应用开发的进步。
107 1
|
关系型数据库 C++
红黑树的插入(C++实现)
红黑树的插入(C++实现)
88 0
|
JavaScript 前端开发 数据处理
vue中实现文件下载,导出Excel表格
vue中实现文件下载,导出Excel表格
570 2
|
SQL 算法 Java
自定义水平分库分表策略【hint分片】
自定义水平分库分表策略【hint分片】