目录

1.完整代码

2.实现效果

3.各函数剖析

4.总结


1.完整代码

game.h:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 1//初始化数组
void InitBoard(char board[ROWS][COLS], int row, int col, char set);//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);//设置雷
void SetMine(char mine[ROWS][COLS], int row, int col);//查找雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//该坐标不是雷且周围八个坐标也不是雷,全展开
void OpenBoard(char mine[ROWS][COLS], char show[ROWS][COLS],int row,int col, int x, int y, int* pcount);//标记雷
void MarkBoard(char mine[ROWS][COLS], char show[ROWS][COLS],int row,int col,int* plcount);//取消标记
void CancelMark(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int* plcount);

game.c

#include"game.h"void InitBoard(char board[ROWS][COLS], int row, int col, char set)
{int i = 0;int j = 0;for (i = 0; i < ROWS; i++){for (j = 0;j < COLS; j++){board[i][j] = set;}}
}void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;printf("-------------扫雷-------------\n");for (j = 0; j <= col; j++) //打印列号{printf("%d ", j);}printf("\n");for (i = 1; i <= row; i++){printf("%d ", i);      //打印行号for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}printf("-------------扫雷-------------\n");
}void SetMine(char mine[ROWS][COLS], int row, int col)
{//布置10个雷int count = EASY_COUNT;while (count){//产生随机下标int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}}
}int get_mine(char mine[ROWS][COLS], 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 game_menu()
{printf("*************************\n");printf("****** 1.标记雷   *******\n");printf("****** 2.取消标记 *******\n");printf("****** 0.查找雷   *******\n");printf("*************************\n");
}void choice(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int* plcount)
{int input = 0;do{game_menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1:MarkBoard(mine, show, ROW, COL,plcount);break;case 2:CancelMark(mine,show,ROW,COL,plcount);break;case 0:break;default:printf("输入错误,请重新输入\n");break;}} while (input);
}void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{//首先,判断输入坐标的合法性//如果查找的坐标在mine[ROWS][COLS]=='1',该坐标为雷,被炸死了//如果输入坐标合法且非雷,返回周边八个位置的雷的数量int x = 0;int y = 0;int win = 0;int* pcount =&win;int left_mine = EASY_COUNT;int* plcount = &left_mine;   //计算标记后剩余雷的个数while (1){choice(mine, show, ROW, COL,plcount);if (*plcount == 0){break;   //如果标记出了所有的雷,那么扫雷成功}printf("请输入要查找的坐标:>");scanf("%d %d", &x, &y);system("cls");//判断坐标的合法性if (x >= 1 && x <= row && y >= 1 && y <= col){if (show[x][y] != '*'){DisplayBoard(show, ROW, COL);printf("该坐标已经查找过了,请重新输入\n");continue;}if (mine[x][y] == '1'){printf("你被炸死了!\n");DisplayBoard(mine, ROW, COL);break;}else{int n = get_mine(mine, x, y);/*show[x][y] = n + '0';win += 1;*///如果该坐标不是雷且周围八个坐标也没有雷,展开if (n == 0){OpenBoard(mine, show, row, col, x, y, pcount);}else{show[x][y] = n + '0';win++;}DisplayBoard(show, ROW, COL);//判断获胜条件if (win == ROW * COL - EASY_COUNT)break;}}else{DisplayBoard(show, ROW, COL);printf("输入坐标非法,请重新输入\n");}}if (win == ROW * COL - EASY_COUNT)  //如果已经查了ROW*COL-EASY_COUNT,那么扫雷成功{DisplayBoard(mine, ROW, COL);printf("恭喜你,扫雷成功!\n");}else if (*plcount == 0){DisplayBoard(mine, ROW, COL);printf("恭喜你,扫雷成功!\n");  //如果标记出了所有的雷,那么扫雷成功}elseprintf("游戏失败\n");
}void OpenBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row,int col,int x, int y, int* pcount)
{//判断坐标合法性if (x >= 1 && x <= row && y >= 1 && y <= col&&show[x][y]=='*'){//该坐标不是雷if (mine[x][y] != '1'){int ret = get_mine(mine, x, y);//该坐标周围八个位置也不是雷if (ret == 0){show[x][y] = ' ';*pcount=*pcount+1;}else{show[x][y] = ret + '0';*pcount = *pcount + 1;}//该坐标八个位置也不是雷,展开if (show[x][y] == ' '){OpenBoard(mine, show, row, col, x-1, y-1, pcount);OpenBoard(mine, show, row, col, x-1, y, pcount);OpenBoard(mine, show, row, col, x-1, y+1, pcount);OpenBoard(mine, show, row, col, x, y-1, pcount);OpenBoard(mine, show, row, col, x, y+1, pcount);OpenBoard(mine, show, row, col, x+1, y-1, pcount);OpenBoard(mine, show, row, col, x+1, y, pcount);OpenBoard(mine, show, row, col, x+1, y+1, pcount);}}}
}void MarkBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int* plcount)
{int x = 0;int y = 0;while (1){printf("请输入要标记的坐标:>");scanf("%d %d", &x,&y);system("cls");//判断合法性if (x >= 1 && x <= row && y >= 1 && y <= col){//该坐标没有被下过且没有被标记if (show[x][y] == '*'){show[x][y] = '#';DisplayBoard(show, row, col);//如果该坐标为雷,则剩余雷数-1if (mine[x][y] == '1'){*plcount = *plcount - 1;}printf("剩余雷数:%d\n", *plcount);if (*plcount == 0){printf("恭喜你标记出了所有的雷,请再输入一次0,结束游戏!\n");}break;}else{DisplayBoard(show, ROW, COL);printf("该坐标已被下过或标记过,无法标记,请重新选择\n");}}else{DisplayBoard(show, ROW, COL);printf("输入坐标非法,请重新输入\n");}}
}void CancelMark(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int* plcount)
{int x = 0;int y = 0;while (1){printf("请输入要取消标记的坐标:>");scanf("%d %d", &x, &y);system("cls");//判断合法性if (x >= 1 && x <= row && y >= 1 && y <= col){//该坐标为被标记的坐标if (show[x][y] == '#'){show[x][y] = '*';DisplayBoard(show, row, col);//如果该坐标为雷,则剩余雷数+1if (mine[x][y] == '1'){*plcount = *plcount + 1;}printf("剩余雷数:%d\n", *plcount);break;}else{printf("该坐标未被标记,无法取消标记,请重新选择\n");}}else{printf("输入坐标非法,请重新输入\n");}}
}

test.c:

#include"game.h"void menu()
{printf("***********************\n");printf("******  1.play  *******\n");printf("******  0.exit  *******\n");printf("***********************\n");
}void game()
{char mine[ROWS][COLS] = { 0 };  //放置雷的信息char show[ROWS][COLS] = { 0 };  //放置棋盘的信息InitBoard(mine, ROWS, COLS,'0'); //初始化棋盘InitBoard(show, ROWS, COLS,'*');//DisplayBoard(mine, ROW, COL);  //打印棋盘DisplayBoard(show, ROW, COL);SetMine(mine, ROW, COL);   //设置雷DisplayBoard(mine, ROW, COL);  //打印设置好的雷FindMine(mine, show, ROW, COL); //查找雷
}void test()
{srand((unsigned int)time(NULL));int input = 0;do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;defualt:printf("输入错误,请重新输入\n");break;}} while (input);
}int main()
{test();return 0;
}

2.实现效果

 

以上就是一些游戏内部的展示画面,基本逻辑是:先出现一个 1.play 0.exit 的是否进入游戏的菜单,玩家选择 1 进入游戏。接着会打印出棋盘,并让玩家选择 1.标记雷 2.取消标记 0.exit ,当玩家输入选择和坐标后,会打印出当前棋盘状况。然后,游戏会在此界面循环,直到标记出所有的雷或者排除完所有的非雷区域,获胜。

3.各函数剖析

test.c

game.c

4.总结

从最基本的扫雷,不断扩展功能,难度还是比较大的。但是,只要一步步思考,当然,也可以多多借鉴别人思考,还是能够完成的。不过,这个优化版的扫雷仍存在缺陷--当,已经选择标记雷、取消标记、查找雷,就必须执行完相应的操作,否则无法退出。期待后来者,能够更近一步!

扫雷--优化版实现(可以自动展开、标记雷、取消标记,并加入了标记出所有的雷直接获胜、自动清屏)相关推荐

  1. c语言扫雷游戏计时功能_C语言实现扫雷游戏(可以自动展开)

    前言 本篇博客主要介绍如何使用C语言实现扫雷游戏. 一.游戏规则 在一张ROW行COL列的地图上存在MINE_COUNT个地雷.玩家输入坐标翻开格子,若没有踩雷,则计算此格子周围8个格子的地雷总数,并 ...

  2. 【C语言实现】全面的扫雷小游戏(包括空白展开、标记等)具体步骤加代码分析

    文章目录 前言 一.问题描述 二.基本框架构思 三.具体实现 1.扫雷接口实现 2.地图初始化 3.设置雷 4.显示界面 5.开始扫雷 6.计算周围雷的数量 7.排查雷 8.空白展开 9.标记雷 10 ...

  3. 冰冰学习笔记:扫雷游戏的实现:展开,排查,标记,取消标记

    扫雷游戏的实现和三子棋的实现方式从差不多 也是分成三个模块实现 主函数实现---test.c 里面包含主逻辑运行函数,以及菜单函数,主游戏逻辑实现 具体游戏函数代码实现---game.c 里面包含游戏 ...

  4. ALLyeSNO 优化版浩方 第二版 Ver 2007 06 15 清除广告 自动挤房间

    分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow allyesno ...

  5. ALLyeSNO 优化版浩方 第二版 Ver:2007.06.15 清除广告 自动挤房间

    allyesno 优化版浩方 第二版 Ver:2007.06.15 正式发布 ALLyeSNO优化版浩方 2007.06.15 1.按Ctrl+F1挤房间 按Ctrl+F2停止挤房间 (一般情况下会自 ...

  6. c语言扫雷(强化版)(可展开)(后附完整代码)

    扫雷 一.简介 二 .扫雷游戏 1.游戏前置步骤 2.布置棋盘 1.为何创建两个棋盘 2.为何创建11*11的棋盘 3.初始化数组 4.打印棋盘 3.布置雷 4.排查雷 1.大概框架 2.统计周围雷的 ...

  7. 二维数组应用——扫雷进阶版

    C语言实现进阶版扫雷小游戏 游戏简介: 电脑随机设置10个雷,用户输入坐标,若坐标下是雷则结束游戏,不是则该位置显示周围的雷数. 相较于之前优化的点在于: 1>保证第一次不被炸死(功能实现见Sa ...

  8. 47. 对数组进行冒泡排序,实现冒泡排序的基础版与优化版

    //冒泡排序: //优化版口诀:序而不排 -> 优化原理:证实已经有序,不需要再次循环 -> 代码角度实现优化:内重循环已证实有序,外重循环不需要再次循环可以停止了.建立flag标记告诉外 ...

  9. php图片传入及改名代码,WordPress添加媒体中文名图片上传改名(优化版)

    WordPress是国外程序,对中文命名的图片不友好,所以上传后就会出现错误.但是我们有时候保存在桌面或者其他地方的图片就是中文命名,现在要上传到WordPress多媒体中,或者上传到文章中,我们改怎 ...

最新文章

  1. 如何在OpenStack环境中实现多Region
  2. 数据中心网络架构 — 传统数据中心网络 — 胖树型三层网络架构
  3. python中一共有多少个关键字-Python中所有的关键字
  4. SAP Fiori国际化支持之UI5 RTL support的实现原理
  5. 设备的dpr_湘潭污水处理设备_处理污水设备生产厂
  6. 动态网页开发技术(三):jsp
  7. ANSI,Unicode,UTF-8网页编码的区别【转】
  8. Android开发笔记(一百一十六)网络学习资源
  9. tshark (wireshark)笔记
  10. Python中的目录树列表
  11. 构建freeswitch, make cd-moh-install下载不了文件怎么办?
  12. 阿里云解决方案架构师徐翔:云上安全建设实战
  13. 计算机视觉项目-银行卡卡号自动识别
  14. 对vue初学者建议 vue如何上手
  15. 头部导航栏和底部 图片pic 字体图标设置文字大小
  16. php可以用wamp哪个好,phpstudy和wamp哪个好
  17. NFM 网络介绍与源码浅析
  18. win10 ISO镜像下载
  19. 要怎么在计算机里清除桌面内存,怎么清理运行内存占用_怎么清理电脑运行内存-win7之家...
  20. 地图APP的产品分析-驴迹导游

热门文章

  1. vue 搜索关键字并实现高亮功能
  2. c语言中tr1=1,TR1C转矩转速采集仪
  3. 考研计算机考多少算高分,计算机考研高分经验 效率是关键
  4. python sum函数用法_python3中sum函数大全
  5. 【转载】晶圆级封装(WLCSP) 倒片封装(Flip-Chip)
  6. Pytorch搭建YoloV5目标检测平台
  7. ubuntu没有interfaces文件_ubuntu14.4系统配置interfaces文件不生效
  8. 韩顺平满汉楼java源码_图书商城app
  9. Current charset is UTF-8. If password has been set using other charset... 解决办法
  10. SAP物料分类账理解