学C的第十四天【应用多文件的形式实现 扫雷 程序(重点);练习:(递归实现)1. 打印9*9乘法口诀表 2. 编写一个函数实现n的k次方 3. 计算一个数的每位之和 4.将参数字符串中的字符反向排列】-1

简介: 10.数组的应用实例2:扫雷游戏 (综合之前学习的知识代码)(重点都在注释中)

10.数组的应用实例2:扫雷游戏 (综合之前学习的知识代码)

(重点都在注释中)

扫雷游戏的实现:

   

 

1. 游戏不退出,继续玩下一把(循环)

2. 应用多文件的形式写代码

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 EASY_COUNT 10
//1. InitBoard() -- 初始化棋盘 函数声明
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//2. DisplayBoard() -- 打印棋盘
//传过来的数组是 11*11 的数组,但(访问)显示的只是其中的 9*9 
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//3. SetMine() -- 布置雷
void SetMine(char board[ROWS][COLS], int row, int col);
//4. FindMine() -- 排查雷(在mine数组中找信息,信息放到show数组中,操作的也是9*9)
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);


7f0c32211be54e6a9867b4ce7841400f.png

game.c        --        游戏函数的实现

#define _CRT_SECURE_NO_WARNINGS 1
//该文件存放 游戏实现 的代码
#include "game.h"
//1. InitBoard() -- 初始化棋盘 函数实现
void InitBoard(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;
      //直接把棋盘初始化成传过来的 set
    }
  }
}
//2. DisplayBoard() -- 打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
//行和列都是从0开始的,要打印 9*9 ,只需要从第1行和列开始打印就好
  int i = 0;
  printf("---------扫雷游戏--------\n");
  for (i = 0; i <= col; i++) //打印列序号
  {
    printf("%d ", i);
  }
  printf("\n"); //换行,防止上面和下面的循环在同一行
  for (i = 1; i <= row; i++) //从第一行开始
  {
    printf("%d ", i); //打印行序号
    int j = 0;
    for ( j = 1; j <= col; j++) //从第一列开始
    {
      printf("%c ", board[i][j]);
    }
    printf("\n");
  }
}
//3. SetMine() -- 布置雷
void SetMine(char board[ROWS][COLS], int row, int col)
{
  //布置10个雷
  //生成随机的坐标,布置雷
  int count = EASY_COUNT; //布置的雷的数量
  while (count) //只要还有雷(非0),就继续布置
  {
     //雷在行列中都是布置在 1-9 
    //用rand()函数生成随机的x和y坐标
    int x = rand() % row + 1; //取余后(row=9)是 0-8 ,再+1后是 1-9
    int y = rand() % col + 1;
    if (board[x][y] == '0') //当前位置无雷才能布置
    {
      board[x][y] = '1'; //布雷
      count--; //布雷成功后,布雷数减1
    }
    //直到count = 0;跳出循环
  }
}
//3.5 --- GetMineCount()函数:统计mine数组坐标为x y的位置上雷的个数
int GetMineCount(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');
  //把xy坐标周围8个坐标的字符 0(无雷) 或 1(有雷) 加起来,
  //再 - 8 * '0' ,把字符 0 或 1 转化为 数字(整型)0 或 1
}
//4. FindMine() -- 排查雷(在mine数组中找信息,信息放到show数组中,操作的也是9*9)
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) 
{
  int x = 0;
  int y = 0;
  int win = 0; //统计找出的不是雷的位置
  while (win < row * col - EASY_COUNT)
    //找到非雷位置 小于 总位置数 减 雷数,说明还有雷,继续排雷
  {
    printf("请输入要排查的坐标:>");
    scanf("%d %d", &x, &y);
    if (x >= 1 && x <= row && y >= 1 && y <= col)
      //输入的坐标正确:1-9
    {
      if (mine[x][y] == '1') //踩到雷了
      {
        printf("很遗憾,你被炸死了\n");
        DisplayBoard(mine, ROW, COL); //结束后查看游戏情况
        break; //这轮游戏结束
      }
      else //没踩到雷的话,统计周围雷的个数 
      {
        int count = GetMineCount(mine, x, y); //把周围雷个数传给count
        //GetMineCount():用于统计周围雷的个数
        //统计mine数组中该坐标周围有几个雷,所以要把mine传过去
        //雷的个数传到show数组相同x y坐标上
        show[x][y] = count + '0'; 
        //show是字符数组,count是数字,+‘0’后转化为字符
        //假设count = 3,加上0的ACSII值 48 后,即 51
        //ASCII码值51 对应的就是 字符3(ASCII码值为51)
        DisplayBoard(show, ROW, COL); //打印查看排雷情况
        win++; //找到不是雷的位置就++
      }
    }
    else
    {
      printf("坐标非法,重新输入\n");
    }
  }
  //被炸死 或者 排完雷后 到这位置
  if (win == row * col - EASY_COUNT)
  {
    printf("恭喜你,排雷成功\n");
    DisplayBoard(mine, ROW, COL); //查看棋盘
  }
}

1. InitBoard() -- 初始化棋盘 函数实现

image.png

2. DisplayBoard() -- 打印棋盘

3. SetMine() -- 布置雷

3.5 --- GetMineCount()函数:统计mine数组坐标为x y的位置上雷的个数

image.png

4. FindMine() -- 排查雷(在mine数组中找信息,信息放到show数组中,操作的也是9*9)

image.png

test.c        --        测试游戏

#define _CRT_SECURE_NO_WARNINGS 1
//实现扫雷游戏代码
//该文件为 测试游戏 的代码
// 设计要点:
//1. 扫雷游戏要存储布置好的雷的信息,需要一个二维数组
//2. 给两个二维数组: 一个存放雷的信息 ; 另一个存放布置好的雷的信息
//3. 为了防止在统计坐标周围的雷的额个数的时候越界,我们让给数组设计为 11 * 11;
//4. 数组是 11 * 11,并且是字符数组
#include "game.h"
void menu()
{
  printf("***********************************\n");
  printf("**********    1.play    ***********\n"); 
  printf("**********    0.exit    ***********\n");
  printf("***********************************\n");
}
void game()
//在自定义game()函数中实现扫雷游戏的执行
{
  char mine[ROWS][COLS]; //存放布置好的雷
  char show[ROWS][COLS]; //存放排查出的雷的信息
  //1. 初始化棋盘
  //(1). mine数组最开始全是‘0’;
  //(2). show数组最开始全是‘#’;
  InitBoard(mine, ROWS, COLS, '0');
  InitBoard(show, ROWS, COLS, '*');
  // 第四个参数为想要初始化成的 符号
  //2. 打印棋盘(玩的时候只显示 9*9 ,所以打印 9*9 就可以了)
  //DisplayBoard(mine, ROW, COL); 
  DisplayBoard(show, ROW, COL); //实际显示的棋盘
  //3. 布置雷(布置在 9*9 中)
  SetMine(mine, ROW, COL); //雷是布置在mine数组上的
  //DisplayBoard(mine, ROW, COL);
  //4. 排查雷(在mine数组中找信息,信息放到show数组中,操作的也是9*9)
  FindMine(mine, show, ROW, COL);
}
int main()
{
  int input = 0;
  //使用rand前要设置srand。设置随机数起点
  //用time()函数返回时间戳
  //返回类型为 无符号整型
  srand((unsigned int)time(NULL));
  do
  {
    menu();
    printf("请选择:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      game(); 
      //在自定义game()函数中实现扫雷游戏的执行
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误,重新选择\n");
      break;
    }
  } while (input); 
  //如果选择了0退出游戏,则刚好判断为0退出循环
  //非0则继续循环
  return 0;
}

void menu() --- 打印菜单

bc16e25e26d444c19ab3a753f2536f5d.png

相关文章
|
9月前
学C的第十三天【应用多文件的形式实现 三子棋 程序(重点);练习:1. 打印9*9乘法口诀表、2. 求10个整数中的最大值、3. 分数加减交叉计算、4. 数一下 1到 100 的整数中出现了多少个9】
9.数组的应用实例1:三子棋(综合以前学习的知识) 三子棋的实现:(重点都在注释中) 1. 游戏不退出,继续玩下一把(循环) 2. 应用多文件的形式写代码
|
9月前
学C的第三天(多组输入的一种方法;简单了解函数,数组,多种操作符)-2
10.2:移位操作符(移动的是二进制位): >>(右移) <<(左移) 10.3:位操作符(操作的额也是二进制位): &(按位与) ^(按位异或) |(按位或)