扫雷这个游戏相信我们大家都有玩过,我们每个电脑里面可能都会有,今天我将用C语言的形式来实现这功能。

目录

目录

一,设计思路

二,功能讲解

三,代码及其游戏步骤及其思路讲解

1.建立数组来保存棋子

2.初始化棋盘

3.打印棋盘

4.随机放置雷

5.玩家排雷

6.计算该位置周围雷的个数

7.递归拓展已选位置周围的区域

四,总代码总结

game.h

game.c

test.h


一,设计思路

我们电脑中的扫雷游戏就是

我们只要输入坐标就可以扫雷了(因为技术原因........),这样的话就不是很难了,我们只需要运用几个算法模块来实现,会分成main,test,game等几个模块来运行,为了方便可以创建多个项目来实现

那我们就需要用二维数组来打印两个棋盘,假如我们要打印9X9的棋盘,那我们的二维数组元素也要为9X9个吗?,不能,因为我们在设计算法时需要统计坐标周围8个方位雷的个数,假如要统计边界坐标周围雷的个数,那么就会有数组越界的问题,那我们就要在9X9的边界多上一圈元素,也就要定义11X11的数组元素,这些元素我们不要打印出来,心里有数就行

二,功能讲解

1.能让其选择是否加入游戏,在完成一把游戏后,无论输赢,可以自行选择是否再来一把

2.因为自身能力原因,无法实现电脑中那样的画面和衔接,采取坐标的形式来排雷

3.在下的位置显示该点周围雷的个数(在没爆炸的情况下)

三,代码及其游戏步骤及其思路讲解

 代码我会按照板块来写注意看哦!!

1.建立数组来保存棋子

#define ROW 9//行
#define COL 9//列#define ROWS ROW+2
#define COLS COL+2

如同猜数字和三子棋一样采用宏定义来定义棋盘的大小我们这次玩的是 “9*9” 的扫雷所以我们定义为 9 .

但是下面的ROWS=ROW+2 || COLS=COL+2如同我们上面所说的一样因为我们在设计算法时需要统计坐标周围8个方位雷的个数,假如要统计边界坐标周围雷的个数,那么就会有数组越界的问题,那我们就要在9X9的边界多上一圈元素,也就要定义11X11的数组元素,这些元素我们不要打印出来

#define easy_system 10//给的最小雷数量

我们同样会采用宏定义来给定雷的数量,后期我们也可以,设置初级/中级/高级模式来给定雷的数量,十分方便!!

2.初始化棋盘

initialization_board(mine, ROW, COL, '0');
initialization_board(show, ROW, COL, '*');

在mine数组中,用字符‘0’表示无雷区域,用字符‘1’表示有雷区域

在show数组中,’✳‘来覆盖然后来排雷,排后 用数字来取代,数字代表其周围的雷的个数

//初始化棋盘
void initialization_board(char arr[ROWS][COLS], int row, int col, int set)
{int i = 0;int j = 0;for (i = 0;i <=row; i++){for (j = 0;j <=col;j++){arr[i][j] = set;}}
}

3.打印棋盘

show_board(show, ROWS, COLS);
void show_board(char show[ROWS][COLS], int row, int col)
{{int i = 0;int j = 0;//打印列号for (i = 0; i < col-1; i++) {printf("%d ", i);}printf("\n");for (i = 1; i < row-1; i++) {printf("%d ", i); //打印行号for (j = 1; j < col; j++) {printf("%c ", show[i][j]);}printf("\n");  //打印完一行需要换行}}
}

打印出来就是这个样子的

mine_board(mine,ROW,COL);

这个就是其基础的没有✳和其他的只有 ’ 0 ‘和 ’ 1 ‘ ,我们在代码中可能不会出现这个,这是为了大家能更好的理解,列出来,大家也可以试试!

4.随机放置雷

其easy_system,在上面的宏定义部分有讲到,意思是我们选择了简单模式

在mine数组中,用字符‘0’表示无雷区域,用字符‘1’表示有雷区域,我们使用srand和rand函数生成随机数,使得雷的分布为随机位置。

void set_mine(char mine[ROWS][COLS], int row, int col)
{int count = easy_system;while (count){int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = 1 + '0';count--;}}
}

rand的话我在 “ 三子棋 ” 和 “ 猜数字 ”的博客中都有提到,大家可以去看看,支持一下,蟹蟹!!

 5.玩家排雷

 玩家根据show数组展示出的地图开始排雷,选择自己认为不是雷的区域。

在里面nearby_number()  boom_board()函数我们会在下面详细写出

void check_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int count = 0;while (count < row * col - easy_system)//我们总共循环71=81-10次,当我们已经循环了71次后,就代表我们已经将所有非雷区域全部排除了{printf("请输入坐标:");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (mine[x][y] == '1'){printf("爆炸了!!");printf("游戏失败!\n");show[x][y] = '#';show_board(show, ROWS, COLS);break;}else{boom_broad(mine, show, x, y);show[x][y] = nearby_number(mine, x, y) + '0';show_board(show, ROWS, COLS);count++;}}else{printf("坐标输入错误,请重新输入!\n");}}if (count == row * col - easy_system)//我们总共循环71=81-10次,当我们已经循环了71次后,就代表我们已经将所有非雷区域全部排除了{printf("恭喜你,你成功了,剩下的都是雷\n");show_board(mine, row, col);//赢了打印雷在哪里}
}

我们总共循环71=81-10次,当我们已经循环了71次后,就代表我们已经将所有非雷区域全部排除了,我们在前面定义了一个count如果我们排对了就++,当达到了71次就代表我们已经将所有非雷区域全部排除了。

nearby_number()我们定义的作用主要是来得到其周围雷的个数来重新给到坐标区域

boom_board()以递归的方式拓展式排雷。

6.计算该位置周围雷的个数

统计已选位置周围八个位置中含有雷的个数,并在该位置上数字的形式打印出来 

int nearby_number(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');//周围有8格所以乘8个'0'
}

在圆圈里面那个 为我们下的坐标,我们要计算的是他周围的八个坐标是否为雷

在那里面我们return里面 “ - ‘ 0 ’ ”是因为字符的原因

7.递归拓展已选位置周围的区域

如果只能一个一个雷的排,将会使得此游戏无法进行,故当选择一个位置a后对a周围八个区域进行排除,若其中一个位置b周围八个位置仍没有雷,就继续对b周围的八个位置进行排雷,以此递归的方式不断排除。 

boom_broad()

void boom_broad(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{//判断坐标是否越界if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1)return;//判断是否已经被排除if (show[x][y] != '*'){return;}int count = nearby_number(mine, x, y);if (count > 0){show[x][y] = count + '0';return;}//递归拓展地图else if (count == 0){show[x][y] = '0';boom_broad(mine, show, x - 1, y);boom_broad(mine, show, x - 1, y - 1);boom_broad(mine, show, x, y - 1);boom_broad(mine, show, x + 1, y - 1);boom_broad(mine, show, x + 1, y);boom_broad(mine, show, x + 1, y + 1);boom_broad(mine, show, x, y + 1);boom_broad(mine, show, x - 1, y + 1);}
}

 四,总代码总结

game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#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_system 10//给的最小雷数量//初始化棋盘
void initialization_board(char arr[ROWS][COLS], int row, int col, int set);//打印棋盘
void show_board(char show[ROWS][COLS], int row, int col);//放置雷
void set_mine(char mine[ROWS][COLS], int row, int col);//排查雷
void check_mine(char ine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

game.c

#include "game.h"//初始化棋盘
void initialization_board(char arr[ROWS][COLS], int row, int col, int set)
{int i = 0;int j = 0;for (i = 0;i <=row; i++){for (j = 0;j <=col;j++){arr[i][j] = set;}}
}void show_board(char show[ROWS][COLS], int row, int col)
{{int i = 0;int j = 0;//打印列号for (i = 0; i < col-1; i++) {printf("%d ", i);}printf("\n");for (i = 1; i < row-1; i++) {printf("%d ", i); //打印行号for (j = 1; j < col; j++) {printf("%c ", show[i][j]);}printf("\n");  //打印完一行需要换行}}
}void set_mine(char mine[ROWS][COLS], int row, int col)
{int count = easy_system;while (count){int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = 1 + '0';count--;}}
}int nearby_number(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');//周围有8格所以乘8个'0'
}
//递归拓展已选位置周围的区域
void boom_broad(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{//判断坐标是否越界if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1)return;//判断是否已经被排除if (show[x][y] != '*'){return;}int count = nearby_number(mine, x, y);if (count > 0){show[x][y] = count + '0';return;}//递归拓展地图else if (count == 0){show[x][y] = '0';boom_broad(mine, show, x - 1, y);boom_broad(mine, show, x - 1, y - 1);boom_broad(mine, show, x, y - 1);boom_broad(mine, show, x + 1, y - 1);boom_broad(mine, show, x + 1, y);boom_broad(mine, show, x + 1, y + 1);boom_broad(mine, show, x, y + 1);boom_broad(mine, show, x - 1, y + 1);}
}void check_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int count = 0;while (count < row * col - easy_system){printf("请输入坐标:");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (mine[x][y] == '1'){printf("爆炸了!!");printf("游戏失败!\n");show[x][y] = '#';show_board(show, ROWS, COLS);break;}else{boom_broad(mine, show, x, y);show[x][y] = nearby_number(mine, x, y) + '0';show_board(show, ROWS, COLS);count++;}}else{printf("坐标输入错误,请重新输入!\n");}}if (count == row * col - easy_system){printf("恭喜你,你成功了,剩下的都是雷\n");show_board(mine, row, col);//赢了打印雷在哪里}
}

test.h

#include "game.h"void menu()//菜单
{printf("************************\n");printf("*******  1.play  *******\n");printf("*******  0.exit  *******\n");printf("************************\n");
}void game()
{srand((unsigned int)time(NULL));//扫雷的实现//定义含雷数组,来存放布置好的雷的信息char mine[ROWS][COLS] = { 0 };//用来存放排查出的雷的信息char show[ROWS][COLS] = { 0 };//初始化棋盘initialization_board(mine, ROW, COL, '0');initialization_board(show, ROW, COL, '*');//打印棋盘/*show_board(show, ROWS, COLS);*///放置雷set_mine(mine, ROW, COL);show_board(show, ROWS, COLS);//排查雷check_mine(mine, show, ROW, COL);}int main()
{int change = 0;do{menu();//菜单printf("请输入选择:");scanf("%d", &change);switch (change){case 1:printf("扫雷游戏\n");game();break;case 0:break;default:printf("输入错误,重新输入\n");}} while (change);return 0;
}

扫雷(详细版)保姆级相关推荐

  1. MySQL+Navicat安装配置教程(超级详细、保姆级)

    MySQL+Navicat安装配置教程(超级详细.保姆级) 一. 下载MySQL 1. 选择想要安装的版本,点击Download下载 二.安装MySQL 1. 选择设置类型 2. 选择安装的产品和功能 ...

  2. Hadoop全分布式集群搭建(全网最详细,保姆级教程)

    在上一篇Hadoop环境搭建(全网最详细,保姆级教程)中已经搭建好了一个单机Hadoop环境,接下来搭建全分布式Hadoop集群 首先对Hadoop全分布示集群进行简单介绍和规划 一个集群由一个主机, ...

  3. VMware虚拟机最新详细安装保姆级教程(2023年新版教程)

    VMware最新详细安装保姆级教程(2023年新版教程) 大家好,我是洲洲,欢迎关注,一个爱听周杰伦的程序员.关注公众号[程序员洲洲]即可获得10G学习资料.面试笔记.大厂独家学习体系路线等-还可以加 ...

  4. Alexa对接开发java版(保姆级图文教程)

    文章目录 前言 一.准备工作? 二.使用步骤 1.登陆科技账号创建函数 2.登陆开发在账号创建技能 3.测试 总结 前言 提示:真正的保姆级图文教程,因本人java开发,准备写篇java+node版本 ...

  5. 【2023最新】超详细图文保姆级教程:App开发新手入门(5)

    上文回顾,我们已经完成了一个应用的真机调试,本章我们来了解一下如何引入YonBuilder移动开发的(原生)移动插件, 并利用移动插件完成一个简单的视频播放器. 8. 「移动插件」的使用 8.1 什么 ...

  6. 超详细图文保姆级教程:App开发新手入门(六)

    设置应用的Logo图标和启动页 上文回顾,我们已经完成了一个简单应用的开发,本章我们简单介绍一下如何设置应用的桌面图标及应用的启动页(本章内容超级简单 -). 1. 修改设置应用的桌面图标 1.1 登 ...

  7. 【2023最新】超详细图文保姆级教程:App开发新手入门(1)

    1. 关于 『YonBuilder移动开发』 PS: 本段内容主要目的是去除官方语音描述,用通俗的语言来简单介绍一下『YonBuilder移动开发』,方便新手开发者判断是否适合自己上手学习. 简介: ...

  8. STM32移植LVGL8.0.2超详细的保姆级教程附移植好的工程文件

    文章目录 前言 一.什么是LVGL? 二.先看效果 三.移植前准备工作 1.准备原有工程 2.下载LVGL源码 四.开始移植 1.把源码搬运到工程文件夹里 2.把搬运好的代码添加到keil工程 3.动 ...

  9. 手把手教你从0开始搭建个人博客,东半球最详细的保姆级博客搭建部署教程 | 程序员人手必备个人博客网站

    Hello 小伙伴们大家好,我是雷小帅! 想象一下你有一个技术博客,然后把网址写在了简历上,面试官点击鼠标打开了这个网站,然后被惊艳了,最后面试的结果你懂得-- 好了,今天的主题就是手把手教大家从零开 ...

  10. 阿里云轻量级服务器部署springboot项目详细教程--保姆级入门

    目录 一.服务器的配置与连接 1.配置服务器初始密码 2.进行远程连接 二. 项目部署相关的软件安装 1.JDK的安装 2.Tomcat的安装 3.MySQL的安装 三. 项目部署服务器 1.修改项目 ...

最新文章

  1. Windows中的一个类似路由器命令的命令
  2. java 的 i++ 和 ++i 的区别
  3. MySQL的主动优化和被动优化_MySQL“被动”性能优化汇总!
  4. Python中的a+=a和a=a+a的区别(认真看完后,我相信你一定会回来感谢我的)
  5. 那些用Go实现的分布式事务框架之DTM
  6. java基础环境搭建_java基础环境搭建
  7. 项目中发现 unity运行挂机放那大约半小时,运行项目变得越来越卡顿
  8. 【数据结构 严蔚敏版】 顺序栈 基本操作
  9. 蓝牙版本avrcp怎么选_新款AirPods怎么选?还是不算好耳机,但是最配的iPhone蓝牙耳机...
  10. 如何撰写软件详细设计内容?
  11. 鹏业安装算量复制工程量
  12. 数字人民币在上海试点,首次实现脱离手机的硬钱包支付模式!
  13. python打印实心菱形图案_python输入三角形三边求面积|python打印实心菱形图案
  14. Mac 下 NVM 的安装与使用
  15. busybox的init
  16. Android拖动实现(一个流畅的拖动排序DragSortGridView,自动滚屏)
  17. 大数据架构师入门学习
  18. react脚手架honeycomb部署
  19. python题目总结1
  20. 拿到新电脑后进行的一些配置,装软件

热门文章

  1. 神级程序员教你用代码哄好生气的女朋友,网友:我要甜甜的恋爱!
  2. php 时间转时辰,Powershell小技巧之获取当前的时间并转换为时辰
  3. python获取登录后的cookie_python爬虫使用cookie登录详解
  4. 为元宇宙提供动力的关键技术驱动力
  5. 使用for循环加if-else实现两个数最小公倍数和最大公约数的计算
  6. Windows Server 2016之RDS部署之添加RD虚拟化主机
  7. Java模式参考大全
  8. 持币大户谈PRS投资策略
  9. 【IoT】产品开发:产品开发战略指南:如何获得竞争优势?
  10. 谁若97岁死,奈何桥上等三年