源代码链接:https://github.com/Sasura321/Minesweeper

扫雷游戏也算是一个简单的小项目,这儿是之前写的代码,来写成博文回顾一下。首先,代码要实现几个功能:

第一下扫雷时,即使踩中了雷也不能直接炸死;

扫雷时,坐标周围没有雷的地方可以实现展开;

统计展开的地方边缘处可能存在的雷的个数;

每次进入游戏,雷分布的地方都是随机的。

1.效果图

1)、程序总的构架:

2)、设计两个棋盘,一个是置放雷的棋盘,在测试中可以查看雷分布在哪些地方,不打印,如果玩家最终失败或者取得胜利,可以打印出来给玩家展示雷的分布。一个是展示给玩家的棋盘,打印,且会不断更新。

3)、游戏效果:

2.菜单

// 菜单

menu()

{

printf("*******************************\n");

printf("**** 欢迎来到扫雷游戏! ****\n");

printf("**** 1.进入游戏 ****\n");

printf("**** 0.退出游戏 ****\n");

printf("*******************************\n");

}

3.初始化棋盘

把棋盘初始化为0:

//初始化棋盘

void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)

{

memset(board, set, rows*cols*sizeof(board[0][0]));

}

4.打印棋盘

棋盘的打印要用到二维数组的知识,这里会涉及到数组越界的问题,比如我们如果要打印 (10 x 10)的棋盘,我们在设计算法时需要统计周围 8 个方位的雷的个数,那么在统计边界周围雷的个数时就产生了数组越界的问题。为了解决这个问题,在棋盘周围多加一圈,即是如果是10x10,就变成了12x12,多出来的已全部打印出来。

//打印棋盘

void DisplayBoard(char board[ROWS][COLS], int row, int col)

{

int i = 0;

int j = 0;

printf(" ");

for (i = 0; i < row; i++)

{

printf(" %d ", i + 1);

}

printf("\n");

for (j = 0; j < col+1; j++)

{

printf("---|");

}

printf("\n");

for (i = 0; i < row; i++)

{

printf(" %d |", i + 1);

for (j = 0; j < col; j++)

{

printf(" %c |", board[i][j]);

}

printf("\n");

printf(" |", i + 1);

for (j = 0; j < col; j++)

{

printf("---|");

}

printf("\n");

}

printf("\n");

}

5.在棋盘上布雷

利用函数 strand() 函数和 rand() 函数在棋盘上随机地方布置雷,有雷的地方标记为 1 ,没有雷的地方标记为 0。

//布置雷

void ScMinc(char board[ROWS][COLS], int row, int col)

{

int x = 0;

int y = 0;

int count = EASY_COUNT;

while (count)

{

x = rand() % 9 + 1;

y = rand() % 9 + 1;

if (board[x][y] == '0')

{

board[x][y] = '1';

count--;

}

}

}

6.一次展开周围无雷的地方

扫雷时,坐标周围没有雷的地方展开,并统计展开的地方边缘处可能存在的雷的个数。

先设计一个函数 GetMineCount()用来统计雷周围雷的的数,如果为 0,则排除这个区域即置为 ‘    ’ ,并递归周围的 8 个位置,如果还出现为 0 的情况则继续递归,递归完成后打印展开的地方边缘处可能存在的雷的个数。

//统计周围雷的个数

static 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';

}

//用递归排除周围没有雷的区域

static void NoMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)

{

int ret = GetMineCount(mine, x, y);

if (ret == 0)

{

show[x][y] = ' ';

if ((x-1)>0 && (y-1)>0 && (show[x-1][y-1] == '*'))

NoMine(mine, show, x - 1, y - 1);

if ((x - 1)>0 && (y)>0 && (show[x - 1][y] == '*'))

NoMine(mine, show, x - 1, y);

if ((x - 1)>0 && (y + 1)>0 && (show[x - 1][y + 1] == '*'))

NoMine(mine, show, x - 1, y + 1);

if ((x)>0 && (y - 1)>0 && (show[x][y - 1] == '*'))

NoMine(mine, show, x, y - 1);

if ((x)>0 && (y + 1)>0 && (show[x][y + 1] == '*'))

NoMine(mine, show, x, y + 1);

if ((x + 1)>0 && (y - 1)>0 && (show[x + 1][y - 1] == '*'))

NoMine(mine, show, x + 1, y - 1);

if ((x + 1)>0 && (y)>0 && (show[x + 1][y] == '*'))

NoMine(mine, show, x + 1, y);

if ((x + 1)>0 && (y + 1)>0 && (show[x + 1][y + 1] == '*'))

NoMine(mine, show, x + 1, y + 1);

}

else

show[x][y] = ret + '0';

}

7.排雷

在排雷过程中,用一个循环,如果踩中的不是雷,用 win 来统计非雷个数 ,如果踩中雷,立即炸死,结束循环。在循环结束后,如果非雷个数  win 正好等于使用的棋盘区域个数减去雷的个数的值,则成功排雷。

//排雷

void FindMind(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)

{

int x = 0;

int y = 0;

int win = 0; //统计不是雷的个数

int ret = 0; //统计周围雷的个数

while (win < ROW*COL - EASY_COUNT)

{

int select = 0;

system("CLS"); //清屏,优化界面

DisplayBoard(show, ROW, COL);

printf("----- 1.扫雷 --- 2.标记雷 -----\n");

printf("请选择:>");

scanf("%d", &select);

if (select == 1)

{

printf("请输入要排查的坐标:>");

scanf("%d %d", &x, &y);

if (x >= 1 && x <= row && y >= 1 && y <= col)

{

if (mine[x-1][y-1] == '0' && show[x-1][y-1] == '*')

{

NoMine(mine, show, x-1, y-1);

DisplayBoard(show, ROW, COL);

win = win + 8;

}

if (mine[x-1][y-1] == '1' && show[x-1][y-1] == '*')

{

show[x-1][y-1] = 'S';

DisplayBoard(show, ROW, COL);

printf("很遗憾,你被炸死了\n\n");

DisplayBoard(mine, row, col);

break;

}

}

else

{

printf("坐标非法\n");

}

}

if (select == 2)

{

printf("请输入要标记雷的坐标:>");

scanf("%d %d", &x, &y);

if (show[x-1][y-1] == '*')

{

show[x-1][y-1] = '@'; //用于玩家标记已经确定的雷

DisplayBoard(show, ROW, COL);

}

else

{

printf("坐标非法\n");

}

}

}

//只剩下有雷的区域(EASY_COUNT:雷的总个数)

if (win = ROW*COL - EASY_COUNT)

{

printf("恭喜你,排雷成功!\n");

DisplayBoard(mine, row, col);

}

}

8.游戏执行

void game()

{

char mine[ROWS][COLS] = { 0 }; //置放雷的棋盘

char show[ROWS][COLS] = { 0 }; //展示给玩家的棋盘

InitBoard(mine, ROWS, COLS,'0');

InitBoard(show, ROWS, COLS, '*');

ScMinc(mine, ROW, COL); //置雷

DisplayBoard(mine, ROW, COL);

DisplayBoard(show, ROW, COL);

FindMind(mine, show, ROW, COL);//排雷

}

void test()

{

int input = 0;

srand((unsigned int)time(NULL));

do

{

menu();

printf("请选择:>");

scanf("%d", &input);

switch (input)

{

case 1:

game();

break;

case 0:

printf("退出游戏\n");

break;

default:

printf("输入错误\n");

}

} while (input);

}

int main()

{

test();

return 0;

}

9.头文件

#ifndef __GAME_H__

#define __GAME_H__

# define _CRT_SECURE_NO_WARNINGS

#include #include #include #include #define ROW 9

#define COL 9

#define ROWS ROW+2

#define COLS COL+2

#define EASY_COUNT 10

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

void DisplayBoard(char board[ROWS][COLS], int row, int col);

void ScMinc(char board[ROWS][COLS], int row, int col);

void FindMind(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

char FistStep(char mine[ROWS][COLS], int row, int col, int x, int y);

#endif __GAME_H__

10.附:game.c 的源码

#include "game.h"

//初始化棋盘

void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)

{

memset(board, set, rows*cols*sizeof(board[0][0]));

}

//打印棋盘

void DisplayBoard(char board[ROWS][COLS], int row, int col)

{

int i = 0;

int j = 0;

printf(" ");

for (i = 0; i < row; i++)

{

printf(" %d ", i + 1);

}

printf("\n");

for (j = 0; j < col+1; j++)

{

printf("---|");

}

printf("\n");

for (i = 0; i < row; i++)

{

printf(" %d |", i + 1);

for (j = 0; j < col; j++)

{

printf(" %c |", board[i][j]);

}

printf("\n");

printf(" |", i + 1);

for (j = 0; j < col; j++)

{

printf("---|");

}

printf("\n");

}

printf("\n");

}

//布置雷

void ScMinc(char board[ROWS][COLS], int row, int col)

{

int x = 0;

int y = 0;

int count = EASY_COUNT;

while (count)

{

x = rand() % 9 + 1;

y = rand() % 9 + 1;

if (board[x][y] == '0')

{

board[x][y] = '1';

count--;

}

}

}

//统计周围雷的个数

static 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';

}

//用递归排除周围没有雷的区域

static void NoMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)

{

int ret = GetMineCount(mine, x, y);

if (ret == 0)

{

show[x][y] = ' ';

if ((x-1)>0 && (y-1)>0 && (show[x-1][y-1] == '*'))

NoMine(mine, show, x - 1, y - 1);

if ((x - 1)>0 && (y)>0 && (show[x - 1][y] == '*'))

NoMine(mine, show, x - 1, y);

if ((x - 1)>0 && (y + 1)>0 && (show[x - 1][y + 1] == '*'))

NoMine(mine, show, x - 1, y + 1);

if ((x)>0 && (y - 1)>0 && (show[x][y - 1] == '*'))

NoMine(mine, show, x, y - 1);

if ((x)>0 && (y + 1)>0 && (show[x][y + 1] == '*'))

NoMine(mine, show, x, y + 1);

if ((x + 1)>0 && (y - 1)>0 && (show[x + 1][y - 1] == '*'))

NoMine(mine, show, x + 1, y - 1);

if ((x + 1)>0 && (y)>0 && (show[x + 1][y] == '*'))

NoMine(mine, show, x + 1, y);

if ((x + 1)>0 && (y + 1)>0 && (show[x + 1][y + 1] == '*'))

NoMine(mine, show, x + 1, y + 1);

}

else

show[x][y] = ret + '0';

}

//排雷

void FindMind(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)

{

int x = 0;

int y = 0;

int win = 0; //统计不是雷的坐标数

int ret = 0; //统计周围雷的个数

while (win < ROW*COL - EASY_COUNT)

{

int select = 0;

//system("CLS"); //清屏,优化界面

DisplayBoard(show, ROW, COL);

printf("----- 1.扫雷 --- 2.标记雷 -----\n");

printf("请选择:>");

scanf("%d", &select);

if (select == 1)

{

printf("请输入要排查的坐标:>");

scanf("%d %d", &x, &y);

if (x >= 1 && x <= row && y >= 1 && y <= col)

{

if (mine[x-1][y-1] == '0' && show[x-1][y-1] == '*')

{

NoMine(mine, show, x-1, y-1);

DisplayBoard(show, ROW, COL);

win = win + 8;

}

if (mine[x-1][y-1] == '1' && show[x-1][y-1] == '*')

{

show[x-1][y-1] = 'S';

DisplayBoard(show, ROW, COL);

printf("很遗憾,你被炸死了\n\n");

DisplayBoard(mine, row, col);

break;

}

}

else

{

printf("坐标非法\n");

}

}

if (select == 2)

{

printf("请输入要标记雷的坐标:>");

scanf("%d %d", &x, &y);

if (show[x-1][y-1] == '*')

{

show[x-1][y-1] = '@'; //用于玩家标记已经确定的雷

DisplayBoard(show, ROW, COL);

}

else

{

printf("坐标非法\n");

}

}

}

if (win > ROW*COL - EASY_COUNT)

{

printf("恭喜你,排雷成功!\n");

DisplayBoard(mine, row, col);

}

}

java递归排雷_C语言实现扫雷小游戏相关推荐

  1. 【C语言】扫雷小游戏详解

    [C语言]扫雷小游戏详解 前言: 还记得大明湖畔的夏雨荷,电脑课上的扫雷吗? ---------------------------是 他 吗--------------------------- 没 ...

  2. c语言字符游动程序,C语言实现扫雷小游戏详解

    本文实例为大家分享了C语言实现扫雷小游戏的具体代码,供大家参考,具体内容如下 一.实现功能 首先显示一个小菜单,选择是否玩游戏.当用户选择退出时,程序运行结束,当用户选择玩游戏时,将提示用户输入扫雷位 ...

  3. 只用c语言不用图片的游戏,使用C语言实现扫雷小游戏

    本文实例为大家分享了C语言实现扫雷小游戏的具体代码,供大家参考,具体内容如下 游戏规则 在一个9*9的地图上一共有十个雷,翻开所有不是雷的位置 游戏即为胜利, 如果踩到雷,游戏结束 设计思路 1.创建 ...

  4. C语言实现扫雷小游戏(排雷时可展开)

    游戏介绍 扫雷想必大家都听说过吧?我们今天写的小游戏就是扫雷,只不过我们只使用C语言写.我们能够做到的就是实现扫雷的基本逻辑,没有图形化界面. 源代码 这次游戏程序的写法和上一次的三子棋的模式很像,也 ...

  5. C语言实现扫雷小游戏(下)(用递归实现了展开)

      穷且益坚,不坠青云之志.   上篇博客实现了鸡肋的扫雷小游戏,不能实现雷盘(场)的展开,体验不是很好,这篇博客对其进行优化了,实现了展开功能. 文章目录 一.新的头文件 二.游戏框架 三.功能函数 ...

  6. 用C语言实现扫雷小游戏(附上思路+项目展示+源代码)

    文章目录 前言 一.扫雷小游戏整体思路讲解. 二.game.c各游戏功能函数的讲解 1.InitBoard 初始化数组函数讲解 2.DisplayBoard 打印格子函数讲解 3.Setmine 电脑 ...

  7. C语言实现扫雷小游戏 纯小白 非黑窗口

    C语言实现一个普通的扫雷小游戏 纯小白所编(含代码非黑窗口!) 扫雷 主要功能 1.创建一个图形界面 2.了解扫雷游戏的原理 3.随机生成雷的位置 4.为整个数组加密,并在雷周围的位置加一 5.导入图 ...

  8. 用c语言实现扫雷小游戏。

    相信小伙伴在学习c语言的时候想做一些小趣事,下面就是用c语言来实现一个扫雷小游戏,不过是简单的实现扫雷(只是通过数组的方式来实现),适合新手学习. 我用的是vs敲的这个代码,大家可以用vs运行(可能有 ...

  9. C语言编写扫雷小游戏

    该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/104992377 扫 ...

最新文章

  1. PMCAFF微课堂(已结束) | 典典养车新媒体负责人亲授:如何运营百万级企业服务号
  2. golang go mod包管理自定义包及init初始化函数介绍
  3. python2升级python3后_Centos7 Python2 升级到Python3
  4. Undefined Reference to Typeinfo
  5. 0.IT-解决方案-0-VOIP
  6. A+B and C (64bit)
  7. 游戏程序中的骨骼插件
  8. AjaxPro实现方法
  9. 微服务学习之Hystrix容错保护【Hoxton.SR1版】
  10. 一个完整的person类
  11. VMware vSphere 服务器虚拟化之二十七桌面虚拟化之View中使用Thinapp软件虚拟化
  12. 区块链对人类产生的变革
  13. CSR867x — 说说什么是ANC、CVC、DSP降噪
  14. 数据库设计 | 需求分析
  15. 签名证书(.keystore)生成指南
  16. 循环双链表的p所指的结点之前插入q所指结点的操作为()
  17. 【日志分析】Web日志分析
  18. 【百度地图】城市中心点坐标
  19. 【Python爬虫】 爬取京东商品图片并下载
  20. SteamVR使用Curved UI实现与UI的交互

热门文章

  1. 数据挖掘公司D square nv 完成500万欧元B轮融资
  2. sublime text3 前端插件介绍
  3. 如何彻底卸载mysql(xp)
  4. 小鱼提问1 类中嵌套public修饰的枚举,外部访问的时候却只能Class.Enum这样访问,这是为何?...
  5. 《虚拟化与云计算》读书感(三)数据中心的概述
  6. [流水账]毕业?工作?
  7. CF1148F - Foo Fighters
  8. 实现nginx上配置免费证书Let's Encrypt
  9. Zend Framework Mail通过网易免费邮箱发送邮件
  10. vue-cli 使用小技巧