玩儿转C语言——初级扫雷易懂详解

简介: 正片开始👀一雷不扫,何以扫天下?今天主要是实现初级的扫雷游戏,方法比较通俗易懂,制作方面不侧重包装而注重功能实现,只是简单对“扫雷”进行简单表达,后期会进行优化和提升。

正片开始👀

一雷不扫,何以扫天下?


今天主要是实现初级的扫雷游戏,方法比较通俗易懂,制作方面不侧重包装而注重功能实现,只是简单对“扫雷”进行简单表达,后期会进行优化和提升。


接受三子棋洗礼后,其实扫雷和上一篇的三子棋大同小异,但其实真正写过才知道扫雷要比三子棋简单一点点,因为三子棋在空间上操作更多,会更加依赖二维数组的使用,所以过程会更加繁琐。下面就来康康扫雷的具体流程:

为方便使用还是先将数组两个元素在头文件中宏定义一下,也方便后期修改:

# define ROW ROW2+2
# define COL COL2+2
# define ROW2 9
# define COL2 9

上菜单👏

void menu()
{
printf("------------------------------------\n");
printf("-------      M e n u     -----------\n");
printf("-------                  -----------\n");
printf("-------1.P    L    A    Y-----------\n");
printf("-------0.E    X    I    T-----------\n");
printf("------------------------------------\n");
printf("------------------------------------\n");
}

简简单单的小菜单,这是一个菜单函数,由switch语句实现选择功能:

void test()
{
  int input = 0;   //输入的值存入input以进行判断
  srand((unsigned int)time(NULL));
  do
  {
    menu();
    printf("请选择菜单:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
    {
      printf("开始扫雷:");
        saolei();  //进入游戏主体
      break;
    }
    case 0:
    {
      printf("即将退出……");
      break;
    }
    default:         //对付非指定值输入
    {
      printf("玩儿呢这是?\n");
      break;
    }   
    }
  } while (input);     //可反复游玩
}

游戏主体👏

void saolei()
{
  char board[ROW][COL] = { 0 }; //实际矩阵
  char real[ROW][COL] = { 0 };  //玩家视角矩阵
  Start(board, ROW, COL, '0');  //雷区初始化
  Start(real, ROW, COL, '*');
  Set(board, ROW, COL);  //布雷(埋雷)
  Show(board, ROW2, COL2);
  Show(real, ROW2, COL2);  //布局(雷区`在这里插入代码片`)展现
  Find(board, real, ROW, COL);  //逻辑判断
}

初始化👏

首先数组的创建上就与三子棋大不相同,基于游戏本身规则的特性,我们需要实际的设计雷阵和呈现给玩家的雷阵,这也是扫雷的一大特色。因为初始化方式不同,对应的功能也不一样,我们就创建了名为 board 和 real 的数组。

在 game.c中用Start函数进行定义:

void Start(char board[ROW][COL], int row, int col,char set)
{
  int i = 0;
  int j = 0;
  for (i = 0; i < row; i++)
  {
    for (j = 0; j < col; j++)
    {
      board[i][j] = set;
    }
    printf("\n");
  }
}

这里用一个for循环的嵌套实现数组的初始化,这里的“ set ”是我指定好的两种字符,我们制作需要全零以便埋雷,而玩家需要一个“ * ”来达到猜测的目的。

打印雷区👏

我们先把我们需要的和玩家的打出来对比一下如下:下为玩家视角。

image.png


用 Show 函数实现如下:

void Show(char board[ROW2][COL2], int row2, int col2)
{
  int i = 0;
  int j = 0;
  for (i = 0; i <= col2;i++)
  {
    printf("%d ", i);//打印行列对应数字
  }
  printf("\n");
  for (i = 1; i <= row2; i++)
  {
    printf("%d ", i);
    for (j = 1; j <= col2; j++)
    {
      printf("%c ", board[i][j]);//存入%c以埋雷
    }
    printf("\n");
  }
}

埋雷大师👏

void Set(char board[ROW][COL], int row, int col)
{
  int count = degree;
  while (count)
  {
    int x = rand() % row + 1;  //生成0~9随机数
    int y = rand() % col + 1;  //生0~9成随机数
    if (board[x][y] == '0')
    {
      board[x][y] = '1';  //判断,是空格就可以埋雷
      count--;//埋十颗
    }
  }
}

这里的重点就只有随机数的应用。这里的随机数是伪随机数,rand函数生成,需要在主函数部分进行初始化,用到 “srand”函数,以时间戳作为随机数的生成标准,不做赘述,不了解的可详见上一篇三子棋的讲解,记住要引用<stdlib.h>和<time.h>头文件。


扫雷专家👏

==一雷不扫,何以扫天下?==扫雷的标准是成功的开山斧,逻辑到位了一切都是信手拈来。判断输赢不难,看有没有踩雷,排没排完的简单逻辑谁不会写?重点是没踩雷也没排完的过程:


当我们走到一个“安全区”时,我们显示出来的是周围8个单位格子的雷数和,我们设置一个 Amount 函数,利用周围8个单位格的返回值进行输入,这里注意,我们算出的返回值是一个整型,但我放入数组的是一个字符类型,将一个数转换成他对应的字符类型怎么办呢?很简单只需+‘ 0 ’即可,由此可知,我们在算8个单位格之和返回值时会事先 -8* ‘ 0 ’。

static Amount(char board[ROW][COL], int x, int y) // 限制为本源文件使用
{
  return board[x + 1][y]
    + board[x + 1][y + 1]
    + board[x][y + 1]
    + board[x - 1][y + 1]
    + board[x - 1][y]
    + board[x - 1][y - 1]
    + board[x][y - 1]
    + board[x + 1][y - 1]-8*'0';  //总和计算
}
void Find(char board[ROW2][ROW2], char real[ROW2][COL2], int row, int col)
{
  int x = 0;
  int y = 0;
  int i = 0;
  int win = 0;
  while (win<row*col-10)
  {
    printf("请输入排查坐标:>");
    scanf("%d %d", &x, &y);
    if (x >= 1 && x <= row && y >= 1 && y <= col)
    {
      if (board[x][y] == '1')   //踩雷判断
      {
        printf("B  O  O  M !!!!\n");
        printf("Game Over\n");
        Show(board,row-2,col-2);
        break;
      }
      else    //未踩雷的雷数计算
      {
        i = Amount(board, x, y);
        real[x][y] = i+'0';
        Show(real,row-2,col-2);
        win++;
      }
    }
    else  //判断越界
    {
      printf("无效坐标!重新输入\n");
    }
  }
  if (win == row * col - 10)    //胜利判断
  {
    printf("Congratulatin,You Win !!!\n");
  }
}

雷区舞王👏

完整代码,参上:

test.c

# include"saolei.h"
void menu()
{
printf("------------------------------------\n");
printf("-------      M e n u     -----------\n");
printf("-------                  -----------\n");
printf("-------1.P    L    A    Y-----------\n");
printf("-------0.E    X    I    T-----------\n");
printf("------------------------------------\n");
printf("------------------------------------\n");
}
void saolei()
{
  char board[ROW][COL] = { 0 };//扫雷矩阵
  char real[ROW][COL] = { 0 };//排雷矩阵
  Start(board, ROW, COL, '0');//初始化
  Start(real, ROW, COL, '*');
  Set(board, ROW, COL);//布置
  Show(board, ROW2, COL2);
  Show(real, ROW2, COL2);//布局
  Find(board, real, ROW, COL);
}
void test()
{
  int input = 0;
  srand((unsigned int)time(NULL));
  do
  {
    menu();
    printf("请选择菜单:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
    {
      printf("开始扫雷:");
        saolei();
      break;
    }
    case 0:
    {
      printf("即将退出……");
      break;
    }
    default:
    {
      printf("玩儿呢这是?\n");
      break;
    }   
    }
  } while (input);
}
int main()
{
  test();
  return 0;
}          

game.c

# define _CRT_SECURE_NO_WARNINGS 
# include"saolei.h"
void Start(char board[ROW][COL], int row, int col,char set)
{
  int i = 0;
  int j = 0;
  for (i = 0; i < row; i++)
  {
    for (j = 0; j < col; j++)
    {
      board[i][j] = set;
    }
    printf("\n");
  }
}
void Show(char board[ROW2][COL2], int row2, int col2)
{
  int i = 0;
  int j = 0;
  for (i = 0; i <= col2;i++)
  {
    printf("%d ", i);
  }
  printf("\n");
  for (i = 1; i <= row2; i++)
  {
    printf("%d ", i);
    for (j = 1; j <= col2; j++)
    {
      printf("%c ", board[i][j]);
    }
    printf("\n");
  }
}
void Set(char board[ROW][COL], int row, int col)
{
  int count = degree;
  while (count)
  {
    int x = rand() % row + 1;
    int y = rand() % col + 1;
    if (board[x][y] == '0')
    {
      board[x][y] = '1';
      count--;
    }
  }
}
static Amount(char board[ROW][COL], int x, int y)
{
  return board[x + 1][y]
    + board[x + 1][y + 1]
    + board[x][y + 1]
    + board[x - 1][y + 1]
    + board[x - 1][y]
    + board[x - 1][y - 1]
    + board[x][y - 1]
    + board[x + 1][y - 1]-8*'0';
}
void Find(char board[ROW2][ROW2], char real[ROW2][COL2], int row, int col)
{
  int x = 0;
  int y = 0;
  int i = 0;
  int win = 0;
  while (win<row*col-10)
  {
    printf("请输入排查坐标:>");
    scanf("%d %d", &x, &y);
    if (x >= 1 && x <= row && y >= 1 && y <= col)
    {
      if (board[x][y] == '1')
      {
        printf("B  O  O  M !!!!\n");
        printf("Game Over\n");
        Show(board,row-2,col-2);
        break;
      }
      else
      {
        i = Amount(board, x, y);
        real[x][y] = i+'0';
        Show(real,row-2,col-2);
        win++;
      }
    }
    else
    {
      printf("无效坐标!重新输入\n");
    }
  }
  if (win == row * col - 10)
  {
    printf("Congratulatin,You Win !!!\n");
  }

game.h

#pragma once
# define ROW ROW2+2
# define COL COL2+2
# define ROW2 9
# define COL2 9
# define degree 10
# include<stdio.h>
# include<stdlib.h>
# include <time.h>
void menu();
void saolei();
void Start(char board[ROW][COL], int row, int col,char set);
void Show(char board[ROW2][COL2], int row2, int col2);
void Set(char board[ROW][COL], int row2, int col2);
void Find(char board[ROW][ROW], char real[ROW][COL], int row, int col);

实战效果:(模拟踩雷)

设置标签

image.png


相关文章
|
12天前
|
C语言
扫雷(C语言)
扫雷(C语言)
20 4
|
1月前
|
存储 编译器 C语言
|
2月前
|
C语言
【海贼王编程冒险 - C语言海上篇】怎样用C语言实现简单的扫雷游戏?
【海贼王编程冒险 - C语言海上篇】怎样用C语言实现简单的扫雷游戏?
16 1
|
2月前
|
存储 安全 Serverless
扫雷游戏C语言代码实现——万字长文超详细,手把手教你实现,新手也能学会
扫雷游戏C语言代码实现——万字长文超详细,手把手教你实现,新手也能学会
|
2月前
|
存储 C语言
c语言实现扫雷
c语言实现扫雷
12 0
|
2月前
|
存储 C语言
C语言实战——扫雷游戏
C语言实战——扫雷游戏
22 0
|
2月前
|
C语言
扫雷游戏(C语言基础版)
扫雷游戏(C语言基础版)
16 0
|
2月前
|
C语言
·扫雷游戏(C语言版)
·扫雷游戏(C语言版)
|
2月前
|
存储 C语言
C语言---扫雷游戏的实现
C语言---扫雷游戏的实现
|
3月前
|
C语言
C语言实现扫雷
C语言实现扫雷
28 1