C语言实现进阶版扫雷小游戏

游戏简介:

电脑随机设置10个雷,用户输入坐标,若坐标下是雷则结束游戏,不是则该位置显示周围的雷数。

相较于之前优化的点在于:

1>保证第一次不被炸死(功能实现见SafeFindMine函数,若第一次就触雷,则将该坐标雷清除,即将其置0,然后在未置雷处随机找一坐标安放新雷)
2>若坐标周围没有雷则雷盘可以自动展开(功能实现见 OpenMine函数,运用了递归)

game.h

#ifndef __GAME_H__
#define __GAME_H__
#include<stdio.h>
//设置屏幕显示的雷盘的大小
#define ROW 9
#define COL 9 //设置实际雷盘的大小(判断雷数是看用户所选的坐标周围八个坐标内是否设雷,但若是用户选择的坐标是位于雷盘四周,则会数组访问越界,所以行和列都要多设两行)
#define ROWS ROW+2
#define COLS COL+2 //设置雷的数量
#define MINE_NUM 10 #include<stdlib.h>
#include<time.h>
//初始化棋盘
void IntiBoard(char board[][ROWS], int row, int col, char set);
void Show(char board[][ROWS], int row, int col);
void SetMine(char board[][ROWS], int row, int col);
void FindMine(char Mine[][ROWS], char MineInfo[][ROWS], int row, int col);
void SafeFindMine(char Mine[][ROWS], char MineInfo[][ROWS], int row, int col);
void OpenMine(char Mine[][ROWS], char MineInfo[][ROWS], int row, int col, int x, int y);#endif

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{ printf("********0.exit********\n");printf("********1.play********\n");printf("**********************\n");
}
void game()
{char Mine[ROWS][COLS] = { 0 };//记录设置后的雷的情况IntiBoard(Mine, ROWS, ROWS,'0');//还未设置雷char MineInfo[ROWS][COLS] = { 0 };//用来展示给用户看的雷盘IntiBoard(MineInfo, ROWS, ROWS, '*');Show(MineInfo, ROWS, ROWS);SetMine(Mine, ROW, ROW);//设置雷//Show(Mine, ROWS, ROWS);SafeFindMine(Mine, MineInfo, ROW, ROW);FindMine(Mine,MineInfo, ROW, ROW);}
int main()
{int input = 0;do{menu();printf("请输入您的选择-->");scanf("%d", &input);switch (input){case 1:printf("游戏开始,玩的开心呦~~~\n");game();//进入游戏break;case 0:printf("游戏退出\n");break;default:printf("请输入正确的操作");break;}} while (input);return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void IntiBoard(char board[][ROWS], 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;}}
}void Show(char board[][ROWS], int row, int col)
{int i = 0;int j = 0;printf("-------------------------------\n");for (i = 0; i < row - 1; i++){printf("%d ", i);}printf("\n");//遍历数组,打印for (i = 1; i < row - 1; i++){printf("%d ", i);for (j = 1; j < col - 1; j++){printf("%c ", board[i][j]);}printf("\n");}printf("-------------------------------\n");
}void SetMine(char board[][ROWS], int row, int col)
{int x;int y;srand((unsigned)time(NULL));for (int i = 0; i < MINE_NUM; i++)//随机设置10个雷{x = rand() % row + 1;//产生1—9的随机数(程序中定义row为9)y = rand() % row + 1;if (board[x][y] == '0'){board[x][y] = '1';}else{i--;}}
}int MineCount(char Mine[][ROWS], int x, int y)//统计周围雷的个数
{return (Mine[x - 1][y - 1] + Mine[x - 1][y] + Mine[x - 1][y + 1] + Mine[x][y - 1] + Mine[x][y + 1] + Mine[x + 1][y - 1] + Mine[x + 1][y] + Mine[x + 1][y + 1])-(8*'0');
}void SafeFindMine(char Mine[][ROWS], char MineInfo[][ROWS], int row, int col)
{int x = 0;int y = 0;int count = MINE_NUM;int countmine = 0;do{printf("请输入坐标:");scanf("%d%d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col){if (Mine[x][y] == '1')//初始选中坐标为雷{Mine[x][y] = '0';//将该坐标的雷清掉while (1)//找一个先前没有置雷的地方放雷{srand((unsigned)time(NULL));x = rand() % row + 1;//产生1—9的随机数(程序中定义row为9)y = rand() % row + 1;if (Mine[x][y] == '0'){Mine[x][y] = '1';break;}}countmine = MineCount(Mine, x, y);MineInfo[x][y] = countmine + '0';//统计重新置雷后坐标附近的雷数OpenMine(Mine, MineInfo, ROWS, ROWS, x, y);Show(MineInfo, ROWS, ROWS);//Show(Mine, ROWS, ROWS);break;}else//初始选中坐标不是雷{countmine = MineCount(Mine, x, y);MineInfo[x][y] = countmine + '0';OpenMine(Mine, MineInfo, ROWS, ROWS, x, y);Show(MineInfo, ROWS, ROWS);//Show(Mine, ROWS, ROWS);break;}}else//坐标错误{printf("坐标不合法,请重新输入");}} while (0);
}int Win(char MineInfo[][ROWS], int row, int col)
{int ret = 0;for (int i = 1; i < row - 1; i++){for (int j = 1; j < col - 1; j++){if (MineInfo[i][j] == '*'){ret++;}}}return ret;
}void FindMine(char Mine[][ROWS], char MineInfo[][ROWS], int row, int col)
{int x = 0;int y = 0;int count = MINE_NUM;int countmine = 0;while (1){printf("请输入坐标:");scanf("%d%d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col){if (Mine[x][y] == '1'){printf("Boom!你被炸了!\n");Show(Mine, ROWS, ROWS);break;}else{countmine = MineCount(Mine, x, y);MineInfo[x][y] = countmine + '0';OpenMine(Mine, MineInfo, ROWS, ROWS, x, y);Show(MineInfo, ROWS, ROWS);//Show(Mine, ROWS, ROWS);if (Win(MineInfo, ROWS, ROWS) == count){break;}}}else{printf("坐标不合法,请重新输入");}}if (Win(MineInfo, ROWS, ROWS) == count){printf("恭喜你小机灵鬼儿\n");Show(Mine, ROWS, ROWS);}
}void OpenMine(char Mine[][ROWS], char MineInfo[][ROWS], int row, int col, int x, int y)//展开函数
{int ret = 0;ret = MineCount(Mine, x, y);if (ret == 0) {MineInfo[x][y] = ' ';if (x - 1>0 && y>0 && MineInfo[x - 1][y] == '*')//(x,y)左边一个位置合法且为“*”(即在雷盘里头)OpenMine(Mine, MineInfo, row, col, x - 1, y);if (x - 1>0 && y + 1 <= col && MineInfo[x - 1][y + 1] == '*')OpenMine(Mine, MineInfo, row, col, x - 1, y + 1);if (x>0 && y + 1 <= col && MineInfo[x][y + 1] == '*')OpenMine(Mine, MineInfo, row, col, x, y + 1);if (x + 1 <= row && y + 1 <= col && MineInfo[x + 1][y + 1] == '*')OpenMine(Mine, MineInfo, row, col, x + 1, y + 1);if (x + 1 <= row && y>0 && MineInfo[x + 1][y] == '*')OpenMine(Mine, MineInfo, row, col, x + 1, y);if (x + 1 <= row && y - 1>0 && MineInfo[x + 1][y - 1] == '*')OpenMine(Mine, MineInfo, row, col, x + 1, y - 1);if (x>0 && y - 1>0 && MineInfo[x][y - 1] == '*')OpenMine(Mine, MineInfo, row, col, x, y - 1);if (x - 1>0 && y - 1>0 && MineInfo[x - 1][y - 1] == '*')OpenMine(Mine, MineInfo, row, col, x - 1, y - 1);}else//ret不为0,即该坐标点周围有雷,返回周围雷数{MineInfo[x][y] = MineCount(Mine, x, y) + '0';}
}

二维数组应用——扫雷进阶版相关推荐

  1. java二维数组扫雷,C语言二维数组实现扫雷游戏

    #include //使用二维数组实现 扫雷 int main() { char ui[8][8]={ '+','+','+','+','+','+','+','+', '+','+','+','+' ...

  2. 07二维数组生成扫雷游戏地图

    运用二维数组生成扫雷游戏地图     要求:a,定义10*10的数组,把所有元素初始化为0               b,随机生成10个雷,不能重复(一定要有10个) -1表示雷          ...

  3. 二维数组应用——扫雷

    C语言实现简单扫雷小游戏 游戏简介: 电脑随机设置10个雷,用户输入坐标,若坐标下是雷则结束游戏,不是则该位置显示周围的雷数. game.h #ifndef __GAME_H__ #define __ ...

  4. 前缀和(一维数组+二维数组+差分)

    前缀和与差分 图文并茂 超详细整理(全网最通俗易懂)_林深不见鹿 的博客-CSDN博客_前缀和与差分 讲得非常的好,大幅度降低时间复杂度 特别是二维数组的前缀和 二维数组前缀和例题,利用二维数组的前缀 ...

  5. 背包(二维数组版和一维数组版)

    一:前言 这是动态规划的经典题型,那么我们也是 按照动态规划五步走的策略分析的 确定dp数组的含义以及下标的含义 确定dp数组的递推公式 确定dp数组的初始化 确定dp数组的遍历顺序 举例验证(如果不 ...

  6. 01背包和完全背包 的完整讲解版 包含 一维数组实现 和二维数组实现题目

    (二)01背包和完全背包 的完整讲解版 包含 一维数组实现 和二维数组实现题目 //有N件物品和一个容量为V的背包.第i件物品的体积是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. ...

  7. 剑指offer:2.二维数组的查找(Java版)

    备注:本文参照<剑指offer第二版> 题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数, 输入这样的一个二维数组和一个整数 ...

  8. C 语言之二维数组(详细版)

    目录 1.二维数组的定义和初始化 2.二维数组在内存中的存储 3.二维数组的使用 4.数组与函数 1. 二维数组是定义和初始化 1.1 二维数组的定义 定义类型:类型名 数组名[ 行表达式 ][ 列表 ...

  9. 二维数组实战项目--------《扫雷游戏》

    接上期介绍的三子棋游戏,今天给大家介绍与其相似的扫雷游戏!(源码在文章末尾) 一  . 游戏开发框架 建立游戏菜单 建立扫雷的棋盘 初始化棋盘 布置雷 排雷(判断是否踩雷) 游戏结束 二 . 游戏开发 ...

最新文章

  1. Oxford Nanopore sequencing, hybrid error correction, and de novo assembly of a eukaryotic genome
  2. 【深度学习】查准率、召回率、AP、mAP
  3. JAVA实现SFTP实例(JSCH)
  4. pytest测试实战pdf_Pytest测试实战
  5. java登录功能多线程_java之多线程
  6. 为什么envi镶嵌老是出错_10个数学考试老出错的根源和解决办法,你值得拥有
  7. (86)FPGA读文件激励(readmemh)
  8. 百度飞桨之python小白逆袭训练营
  9. 物理内存充足,但是为什么用代码总申请不到内存呢?
  10. python图片转动漫_python实现了照片转化为动漫模式
  11. OpenCV-Python图像处理教程(源码及素材)
  12. mongodb数据结构学习1--增删改查
  13. 目标跟踪 | 目标跟踪算法总结
  14. Swagger注解 详解
  15. 高低压配电柜温度在线监测系统解决方案
  16. MapReduce实操5-1数据预处理——巴西利亚历史气温数据分析
  17. mysql5.7第一次登录修改root密码
  18. 信号与系统(二):拉普拉斯变换的意义:谈H(s)、h(t)、δ(t)
  19. JOOQ 踩坑和评价
  20. 实验室-关于老铁整一个社会语录api与网抑云热评api(并引入百度语音tts)

热门文章

  1. 高光谱遥感--原理、技术与应用(童庆禧院士等)
  2. 《权威指南》笔记 -- 8.3 函数的实参和形参
  3. 随机搜索(Random Searching)算法概述
  4. 高德 android 多边形中心点,完美起航-android高德地图画多边形,已知中心点宽高画矩形,实际距离千米转地图坐标距离...
  5. Android基础:Android概念
  6. 在zabbix中实现发送带有图片的邮件和微信告警
  7. 在学RTX之前的操作系统知识
  8. 选购手机时,运行内存和处理器先考虑哪个?来说说你的观点
  9. 【论文】如何写文献综述
  10. 第48讲 Android Camera2 API FD人脸检测