本次讲解扫雷小游戏(小小升级的版本)

文章目录

  • 前言
  • 一、game.h
  • 二、test.c
    • 1.主函数 main() 的编写
    • 2.游戏系列函数编写game.c
  • 整体代码

前言

游戏规则:根据电脑提示输入位置,当输入的位置让有雷,游戏结束;输入的位置是哪个没有雷,游戏继续,并且会显示周围八个位置的雷的情况


为了让代码更加模块化,首先我们需要分别创建game.h game.c test.c

一、game.h

game.h 里面存放的是头文件的声明、函数的声明、以及雷盘大小的自由化改动

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
//包含头文件
#include <stdio.h>
#include <stdlib.h>
#include <time.h>//方便修改雷盘大小
#define ROW 3
#define COL 3
#define ROWS ROW+2
#define COLS COL+2//声明初始化雷盘函数
void InitBoard(char board[ROWS][COLS], int rows, int cols, char ret);//声明打印雷盘函数
void PrintBoard(char board[ROWS][COLS], int row, int col);//声明布置雷函数
void setmine(char board[ROWS][COLS], int row, int col, int num);//声明排查雷的函数
void findmine(char secret[ROWS][COLS], char show[ROWS][COLS], int row,int col,int num);

二、test.c

1.主函数 main() 的编写

根据游戏需求,我们需要一个可以提供玩家选择的游戏菜单

void menu()
{printf("*************---------------***************\n");printf("******---------            ---------*******\n");printf("******--------- 1.玩游戏   ---------*******\n");printf("\n");printf("******--------- 0.退出游戏 --------********\n");printf("******---------            ---------*******\n");printf("*************---------------***************\n");}

玩家按照菜单的内容进行选择,根据不同的选择编写 switch 语句

int main()
{srand((unsigned int)time(NULL));int input = 0;do{menu();printf("请选择:");scanf("%d", &input); switch (input){case 0:system("cls");system("pause");printf("欢迎您的下一次体验,再见!\n");break;case 1:game();break;default:printf("输入错误,请重新选择\n");break;}} while (input);
}

2.游戏系列函数编写game.c

创建一个理想雷盘

char Secret[ROWS][COLS] = { 0 };  //秘密雷盘
char Show[ROWS][COLS] = { 0 };//展示的雷盘

正常来说,扫雷游戏只需要一个雷盘,但是这里设置了两个雷盘的原因是: Secret雷盘是用来存储雷的信息的,这里不能给玩家看;Show雷盘是玩家进行游戏的雷盘,两者有不同的作用,所以需要设置两个规模一样的雷盘。

初始化雷盘

void InitBoard(char board[ROWS][COLS], int rows, int cols, char ret)
{memset(board, ret, sizeof(board[0][0]) * rows * cols);
}

因为这里是char类型的数组,所以直接使用memset初始化。

雷盘打印

void PrintBoard(char board[ROWS][COLS], int row, int col)
{printf("------------------------扫雷游戏-------------------\n");int i = 0, j = 0;printf(" ");for (i = 1; i <= row; i++){printf("%3d ", i);}printf("\n");printf("  +");for (i = 0; i < row; i++){printf("---+");}printf("\n");for (i = 1; i <= row; i++){printf("%2d", i);printf("|");for (j = 1; j <= col; j++){printf(" %c |", board[i][j]);}printf("\n");printf("  +");for (j = 0; j < col; j++){printf("---+");}printf("\n");}printf("------------------------扫雷游戏-------------------\n");
}

布置雷盘

void setmine(char board[ROWS][COLS], int row, int col, int num)
{//随机布雷int x = 0;int y = 0;for (int i = 0; i < num; ){x = rand() % row + 1;  //x产生[1,row]之间的坐标y = rand() % col + 1;  //y产生[1,col]之间的坐标if (board[x][y] == '0'){board[x][y] = '1';i++; }}
}

模式选择
玩家可以自行选择困难模式,也可以自定义模式

int ModeSelection()
{int num = 0;
again:  //玩家选择模式错误时返回到这里printf("欢迎玩家来到扫雷游戏\n");printf("\n请选择扫雷难度: (num的代表雷的数量)\n");printf("A.轻松模式:num=5  B.皱眉头模式:num=15  C.出汗模式:num=30  D.DIY难度(玩家自行输入雷的个数)\n ");char pattern = 0;getchar();//清空缓存区scanf("%c", &pattern);switch (pattern){case 'A':case 'a':printf("轻松模式:num=5\n");num = 5;return num;break;case 'B':case 'b':printf("皱眉头模式:num=15\n");num = 15;return num;break;case 'C':case 'c':printf("出汗模式:num=30\n");num = 30;return num;break;case 'D':case 'd':printf("DIY模式:\n");printf("请输入想要布置雷的个数:\n");getchar();//清楚缓存区int intput = 0;scanf("%d", &intput);//用户自定义的雷的个数num = intput;return num;break;default:printf("\n******不好意思,皮蛋还没有此功能按键,请重新选择:******\n\n");goto again;break;}
}

排查雷

  1. 首先需要知道玩家输入的坐标是否合法
  2. 其次需要判断此位置有没有被排查过
  3. 如果没有被排查过,就需要进行递归显示周围雷的数量
void findmine(char secret[ROWS][COLS], char show[ROWS][COLS], int row, int col, int num)
{int x = 0;int y = 0;int win = 0;  //被排查的个数while ((row * col - num) > win){printf("请输入排雷坐标(格式:行号 列号)\n");scanf("%d%d", &x, &y);if (show[x][y] != '*'){printf("该坐标已经被排查过了 请重新输入:\n");continue;}if (x >= 1 && x <= row && y >= 1 && y <= col){if (secret[x][y] == '1')//如果是1就代表是雷,游戏结束{printf("很遗憾,你失败了\n");printf("请看答案:\n");PrintBoard(secret, ROW, COL);//失败后,给玩家看答案雷盘break;}else{Recursive(secret, show, ROW, COL, x, y);  //自动递归排雷函数win = is_win(show, ROW, COL);  //计算已经被排查的位置PrintBoard(show, ROW, COL);//打印给玩家的雷盘}}else{printf("坐标非法,请重新输入:\n");}}if (win == (row * col - num)){printf("恭喜你排雷成功\n");}
}

递归进行自动排雷(显示周围雷的情况)

Recursive(char secret[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{if (x >= 1 && x <= row && y >= 1 && y <= col){int count = countmine(secret, x, y);//计算该坐标周围有几个雷if (count == 0){show[x][y] = ' ';//周围没有雷的坐标变为空格int i = 0, j = 0;for (i = x - 1; i <= x + 1; i++)//观察周围八个坐标{for (j = y - 1; j <= y + 1; j++){if (show[i][j] == '*' && (i != x || j != y))//防止重新递归show[x][y]坐标{Recursive(secret, show, ROW, COL, i, j);}}}}else{show[x][y] = count + '0';}}
}

计算周围雷的个数

int countmine(char secret[ROWS][COLS], int x, int y)
{int ret = secret[x - 1][y - 1] + secret[x - 1][y] + secret[x - 1][y + 1]+ secret[x][y - 1] + secret[x][y + 1]+ secret[x + 1][y - 1] + secret[x + 1][y] + secret[x + 1][y + 1] - 8 * '0';return ret;
}

计算已经被排查过的位置,进而判断是否还有空位进行排雷游戏

int is_win(char show[ROWS][COLS], int row, int col)
{int count1 = 0;//已经被排查的坐标个数int i = 0, j = 0;for (i = 1; i <= row; i++){for (j = 1; j <= col; j++){if (show[i][j] != '*')//只要不是*,表示该坐标已经被排查了.{count1++;}}}return count1;
}

整体代码

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//声明初始化雷盘函数
void InitBoard(char board[ROWS][COLS], int rows, int cols, char ret);//声明打印雷盘函数
void PrintBoard(char board[ROWS][COLS], int row, int col);//声明布置雷函数
void setmine(char board[ROWS][COLS], int row, int col, int num);//声明排查雷的函数
void findmine(char secret[ROWS][COLS], char show[ROWS][COLS], int row,int col,int num);

test.c

#include "game.h"
void menu()
{printf("*************---------------***************\n");printf("******---------            ---------*******\n");printf("******--------- 1.玩游戏   ---------*******\n");printf("\n");printf("******--------- 0.退出游戏 --------********\n");printf("******---------            ---------*******\n");printf("*************---------------***************\n");}void game()
{//创建雷盘char Secret[ROWS][COLS] = { 0 };  //秘密雷盘char Show[ROWS][COLS] = { 0 };//展示的雷盘//初始化雷盘InitBoard(Secret, ROWS, COLS,'0'); //初始化的答案雷盘InitBoard(Show, ROWS, COLS, '*');  //初始化的玩家雷盘//打印雷盘PrintBoard(Show, ROW, COL); //打印给玩家看的雷盘//布置雷int num = ModeSelection(); //模式选择函数,返回雷的数量setmine(Secret, ROW, COL, num); //布置雷函数//排查雷findmine(Secret, Show, ROW, COL, num);
}
int main()
{srand((unsigned int)time(NULL));int input = 0;do{menu();printf("请选择:");scanf("%d", &input); switch (input){case 0:system("cls");system("pause");printf("欢迎您的下一次体验,再见!\n");break;case 1:game();break;default:printf("输入错误,请重新选择\n");break;}} while (input);
}

game.c

#include "game.h"//初始化雷盘函数的定义
void InitBoard(char board[ROWS][COLS], int rows, int cols, char ret)
{memset(board, ret, sizeof(board[0][0]) * rows * cols);
}//打印雷盘函数的定义
void PrintBoard(char board[ROWS][COLS], int row, int col)
{printf("------------------------扫雷游戏-------------------\n");int i = 0, j = 0;printf(" ");for (i = 1; i <= row; i++){printf("%3d ", i);}printf("\n");printf("  +");for (i = 0; i < row; i++){printf("---+");}printf("\n");for (i = 1; i <= row; i++){printf("%2d", i);printf("|");for (j = 1; j <= col; j++){printf(" %c |", board[i][j]);}printf("\n");printf("  +");for (j = 0; j < col; j++){printf("---+");}printf("\n");}printf("------------------------扫雷游戏-------------------\n");
}//模式选择函数的定义(返回设置雷的个数)
int ModeSelection()
{int num = 0;
again:  //玩家选择模式错误时返回到这里printf("欢迎玩家来到扫雷游戏\n");printf("\n请选择扫雷难度: (num的代表雷的数量)\n");printf("A.轻松模式:num=5  B.皱眉头模式:num=15  C.出汗模式:num=30  D.DIY难度(玩家自行输入雷的个数)\n ");char pattern = 0;getchar();//清空缓存区scanf("%c", &pattern);switch (pattern){case 'A':case 'a':printf("轻松模式:num=5\n");num = 5;return num;break;case 'B':case 'b':printf("皱眉头模式:num=15\n");num = 15;return num;break;case 'C':case 'c':printf("出汗模式:num=30\n");num = 30;return num;break;case 'D':case 'd':printf("DIY模式:\n");printf("请输入想要布置雷的个数:\n");getchar();//清楚缓存区int intput = 0;scanf("%d", &intput);//用户自定义的雷的个数num = intput;return num;break;default:printf("\n******不好意思,皮蛋还没有此功能按键,请重新选择:******\n\n");goto again;break;}
}//定义布置雷函数
void setmine(char board[ROWS][COLS], int row, int col, int num)
{//随机布雷int x = 0;int y = 0;for (int i = 0; i < num; ){x = rand() % row + 1;  //x产生[1,row]之间的坐标y = rand() % col + 1;  //y产生[1,col]之间的坐标if (board[x][y] == '0'){board[x][y] = '1';i++; }}
}//统计坐标周围雷的数量
int countmine(char secret[ROWS][COLS], int x, int y)
{int ret = secret[x - 1][y - 1] + secret[x - 1][y] + secret[x - 1][y + 1]+ secret[x][y - 1] + secret[x][y + 1]+ secret[x + 1][y - 1] + secret[x + 1][y] + secret[x + 1][y + 1] - 8 * '0';return ret;
}//自动排雷函数定义
Recursive(char secret[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{if (x >= 1 && x <= row && y >= 1 && y <= col){int count = countmine(secret, x, y);//计算该坐标周围有几个雷if (count == 0){show[x][y] = ' ';//周围没有雷的坐标变为空格int i = 0, j = 0;for (i = x - 1; i <= x + 1; i++)//观察周围八个坐标{for (j = y - 1; j <= y + 1; j++){if (show[i][j] == '*' && (i != x || j != y))//防止重新递归show[x][y]坐标{Recursive(secret, show, ROW, COL, i, j);}}}}else{show[x][y] = count + '0';}}
}//计算已经被排查的位置
int is_win(char show[ROWS][COLS], int row, int col)
{int count1 = 0;//已经被排查的坐标个数int i = 0, j = 0;for (i = 1; i <= row; i++){for (j = 1; j <= col; j++){if (show[i][j] != '*')//只要不是*,表示该坐标已经被排查了.{count1++;}}}return count1;
}//定义排查雷的函数
void findmine(char secret[ROWS][COLS], char show[ROWS][COLS], int row, int col, int num)
{int x = 0;int y = 0;int win = 0;  //被排查的个数while ((row * col - num) > win){printf("请输入排雷坐标(格式:行号 列号)\n");scanf("%d%d", &x, &y);if (show[x][y] != '*'){printf("该坐标已经被排查过了 请重新输入:\n");continue;}if (x >= 1 && x <= row && y >= 1 && y <= col){if (secret[x][y] == '1')//如果是1就代表是雷,游戏结束{printf("很遗憾,你失败了\n");printf("请看答案:\n");PrintBoard(secret, ROW, COL);//失败后,给玩家看答案雷盘break;}else{Recursive(secret, show, ROW, COL, x, y);  //自动递归排雷函数win = is_win(show, ROW, COL);  //计算已经被排查的位置PrintBoard(show, ROW, COL);//打印给玩家的雷盘}}else{printf("坐标非法,请重新输入:\n");}}if (win == (row * col - num)){printf("恭喜你排雷成功\n");}
}

C语言实现扫雷游戏(自动排雷)相关推荐

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

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

  2. 超详细分解c 语言——实现扫雷游戏(详解)

    之前利用三子棋程序,介绍探讨了 c语言简单游戏编写主要模块及使用方法. 今天,我们就利用这个经典扫雷游戏,来加强对于程序思路的编写及思路. 目录 前引 游戏规则介绍 一.基本游戏思路(游戏实现方法) ...

  3. C语言实现扫雷游戏(超详细讲解+全部源码)

    电子信息 工科男 一点一点努力! 文章目录 前言 一.游戏介绍 二.游戏设计思路 二.具体步骤 1.创建test.c和game.c源文件以及 game.h头文件 2.创建菜单 3.创建雷盘 4.初始化 ...

  4. c语言程序设计扫雷游戏实验报告,C语言程序设计扫雷游戏实验报告.doc

    C语言程序设计扫雷游戏实验报告 中南大学 程序设计基础实践报告 题 目 设计一个和window系统类似的小游戏[挖地雷] 学生姓名 张兰兰 学 院 信息科学与工程学院 专业班级 物联网工程1301班 ...

  5. 用c语言编写最大最小值_C语言学习教程,用C语言编写扫雷游戏

    本文实例为大家分享了C语言实现扫雷游戏及其优化的具体代码,供大家参考,具体内容如下 关于扫雷优化 1.核心思想:使用两个二维数组进行设计,一个用于显示,一个用于后台雷的布置. 2.使用宏常量,后期可以 ...

  6. c++扫雷游戏代码_C语言学习教程,用C语言编写扫雷游戏

    本文实例为大家分享了C语言实现扫雷游戏及其优化的具体代码,供大家参考,具体内容如下 关于扫雷优化 1.核心思想:使用两个二维数组进行设计,一个用于显示,一个用于后台雷的布置. 2.使用宏常量,后期可以 ...

  7. c语言—实现扫雷游戏

    文章目录 什么是扫雷游戏 一.实现思路 二.头文件 三.主函数文件 1.菜单函数 2.主函数 四.游戏文件 1.地图初始化 2.展示地图 3.埋雷函数 4.判断该位置附近雷的个数 5.主游戏函数 五. ...

  8. 用C语言实现扫雷游戏

    用C语言实现扫雷游戏 -扫雷游戏的基本思路 1.打印游戏的菜单 2.为了便于后面排查周围雷的个数,初始化两个二维数组,一个作为向玩家显示的面板,一个作为布雷的面板.两个数组嵌套在一起.如下图所示: 3 ...

  9. C语言编写扫雷游戏,超简单

    C语言编写扫雷游戏,超简单 1.扫雷游戏的流程 2.代码编写 3.总结 通过学习C语言的基础知识,基本上是理解了大部分内容,现在就通过所学的知识,写个简单的扫雷游戏,加深对基础知识的理解,正所谓实践是 ...

  10. c语言扫雷程序设计流程图,c语言程序设计扫雷游戏实验报告

    c语言程序设计扫雷游戏实验报告 中南大学 程序设计基础实践报告 题 目 设计一个和window系统类似的小游戏[挖地雷]学生姓名 张兰兰 学 院 信息科学与工程学院 专业班级 物联网工程1301班 完 ...

最新文章

  1. H5调用Android播放视频
  2. oracle sid环境变量,ORACLE_SID环境变量设置的问题
  3. 白话Elasticsearch47-深入聚合数据分析之Cardinality Aggs-cardinality算法之优化内存开销以及HLL算法
  4. JSP简单练习-一个简单的计数器
  5. Linux环境下C语言模拟内存负载测试
  6. BOOST_LOCAL_FUNCTION宏用法的测试程序
  7. django前后端结合_简单4步用FLASK/Django部署你的Pyecharts项目
  8. java栈实现简易计算器算法
  9. python开发实践教程_Python开发实践教程
  10. Facebook隐私泄露事件继续发酵,黑客明码标价出售聊天信息
  11. mysql动态代理_超全MyBatis动态代理详解(绝对干货)
  12. hdu 2586 How far away ?(LCA模板)(倍增法)
  13. WINDOWS系统自动登录设置
  14. tomcat事件处理机制
  15. Nginx 为什么快到停不下来?
  16. MATLAB学习八(二):标准差std
  17. SCT2650,4.5V-60V电压,芯洲降压DCDC转换器,参数
  18. 红帽子linux装mysql_红帽学习之Linux安装
  19. Android Studio 中集成 ASSIMP
  20. win7计算机怎么找管理员,win7如何获得管理员权限?

热门文章

  1. bond解除 centos7_Centos7 / RHEL 7 双网卡绑定
  2. crmeb 短信配置相关说明教程
  3. cesium系列 - 错误收集
  4. Windows XP十五周年:由爱生恨的系统长者
  5. 钢铁一般的“移动策略”是怎样炼成的
  6. 程序员小白入行区块链的六种方式
  7. LXC 和 LXD 容器总结
  8. [学习记录]回溯算法及其应用
  9. macOS软件打不开的解决方法
  10. 中高级测试工程师基础知识必备之selenium篇