C语言实现扫雷游戏完整实现(上)

文章目录

  • 前言
  • 一、新建好头文件和源文件
  • 二、实现游戏菜单选择功能
  • 三、定义游戏函数
  • 四、初始化棋盘
  • 五、 打印棋盘函数
  • 六、布置雷函数
  • 七、玩家排雷菜单
  • 八、标记功能的菜单
  • 九、标记功能菜单的实现
  • 总结


前言

C语言从新建文件到游戏菜单,游戏函数,初始化棋盘,打印棋盘,布置雷函数,玩家排雷菜单,标记功能菜单及实现等的操作。

一、新建好头文件和源文件

  • 库函数头文件常数都定义在game.h头文件中
  • 在test.c源文件和game.c源文件中通过#include "game.h"引入game.h头文件即可
    1. 在test.c源文件中实现菜单以及游戏函数的调用等功能。
    1. 在game.h头文件中主要完成游戏函数的声明等功能。
    1. 在game.c源文件中完成函数的定义/实现工程。

在这里插入图片描述

二、实现游戏菜单选择功能

// game.h 头文件
#include <stdio.h>

// test.c 源文件
#include "game.h"// 定义游戏菜单函数
void menu()
{printf("**********************\n");printf("*****   1. Play  *****\n");printf("*****   0. Quit  *****\n");printf("**********************\n");
}
int main()
{int input = 0; // 定义输入菜单选项的变量do{// 游戏菜单menu();printf("请选择:>");scanf("%d", &input);// 不同选择对应不同结果switch (input){case 1:printf("扫雷游戏开始!!!\n");break;case 0:printf("推出游戏!!!\n");break;default:printf("选择错误,请重新输入\n");break; // 因为要重新输入所以从菜单开始循环}} while (input); // 输入为0退出游戏,同时停止循环return 0;
}

三、定义游戏函数

  • 以9×9为例
  • 需要首先定义 11 × 11(为了便于检测棋盘边边位置的雷) 的棋盘(二维数组)
  • 打印9×9的棋盘即可
  • -需要定义两个棋盘
  • 一个用来存放布置雷的信息
  • 一个用来存放玩家操作信息
// game.h 头文件
#include <stdio.h>#define ROW 9
#define COL 9#define ROWS ROW + 2
#define COLS COL + 2

// test.c 源文件
#include "game.h"
// 定义游戏菜单函数
void menu()
{printf("**********************\n");printf("*****   1. Play  *****\n");printf("*****   0. Quit  *****\n");printf("**********************\n");
}
--------------------------------------------------------------
void game()
{// 定义两个二维数组char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };// 初始化棋盘
}
---------------------------------------------------------------
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("选择错误,请重新输入\n");break; // 因为要重新输入所以从菜单开始循环}} while (input); // 输入为0退出游戏,同时停止循环return 0;
}

四、初始化棋盘

  • 将存放布置雷信息的棋盘初始化为 ‘0’。----设计 ‘0’表示没有雷,‘1’表示雷。
  • 将玩家操作信息的棋盘初始化为 ‘*’。
// test.c --game函数
void game()
{// 定义两个二维数组char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };// 初始化棋盘InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');
}

// game.h 头文件
#include <stdio.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 sign);

// game.c 源文件
#include "game.h"// 初始化棋盘函数的定义
void InitBoard(char board[ROWS][COLS], int rows, int cols, char sign)
{int i = 0;for (i = 0; i < rows; i++){int j = 0;for (j = 0; j < cols; j++){board[i][j] = sign;}}
}

五、 打印棋盘函数

  • 只打印9×9的棋盘,所以传入参数 ROW 和 COL。
  • 打印棋盘的同时还可以打印出每行每列的数字,方便玩家操作。
  • 同时打印出分割线例如 -----------扫雷游戏---------------
//test.c 源文件
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);
}

//game.h 头文件
#include <stdio.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 sign);// 打印函数声明
void DisplayBoard(char board[ROWS][COLS], int row, int col);

//game.c 源文件
// 打印棋盘函数定义
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{// 打印游戏开头分割线printf("-----扫雷游戏------\n");int i = 0;// 打印每一列数字for (i = 0; i <= row; i++){printf("%d ", i); // 打印每一列数字}printf("\n");// 打印列数字完换行for (i = 1; i <= row; i++){// 打印每一列数字之前先打印出行号printf("%d ", i);int j = 0;for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}// 打印游戏结尾分割线printf("-----扫雷游戏------\n");
}

目前可以实现的效果如下图
在这里插入图片描述

六、布置雷函数

  • 在初始化棋盘和打印棋盘之间,应该先布置雷。在mine棋盘(数组)中布置。
  • 在game.h文件中定义常量 EASY_COUNT 来表示雷的数量。
  • 雷只用在9×9的范围内布置即可,所以传入参数 ROW 和 COL。
  • 通过生成9×9范围内的随机数,来布置雷。
  • 用到rand函数,引入 stdlib.h 和 time.h 头文件。
  • 为了保证随机数的随机性,需要在test.c的主函数一开始使用srand函数如下图
    在这里插入图片描述
//test.c 源文件 -- game函数
void game()
{// 定义两个二维数组char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };// 初始化棋盘InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');// 布置雷SetBoard(mine, ROW, COL);// 打印棋盘DisplayBoard(mine, ROW, COL);DisplayBoard(show, ROW, COL);
}

//game.h 头文件
#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_COUNT 10// 初始化函数声明
void InitBoard(char board[ROWS][COLS], int rows, int cols, char sign);// 打印函数声明
void DisplayBoard(char board[ROWS][COLS], int row, int col);// 布置雷函数声明
void SetBoard(char board[ROWS][COLS], int row, int col);

//game.c 源文件
// 布置雷函数定义
void SetBoard(char board[ROWS][COLS], int row, int col)
{int count = EASY_COUNT;int x = 0;int y = 0;while (count){x = rand() % row + 1;y = rand() % col + 1;if (board[x][y] == '0'){board[x][y] = '1';count--;}}
}

七、玩家排雷菜单

  • 玩家排雷之前要有标记,排雷,以及退出终止的菜单。
  • 菜单选择需要玩家输入,所以定义变量,如若出入错误,循环输入。
//test.c 源文件 --- game函数
void game()
{int choose = 0;// 定义两个二维数组char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };// 初始化棋盘InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');// 布置雷SetBoard(mine, ROW, COL);// 打印棋盘DisplayBoard(mine, ROW, COL);DisplayBoard(show, ROW, COL);// 玩家开始排雷do{printf("****************\n");printf("*** 1. 标记  ***\n");printf("*** 2. 排雷  ***\n");printf("*** 0. 退出  ***\n");printf("****************\n");printf("请选择:>");scanf("%d", &choose);if (1 == choose){printf("标记功能\n");}else if (2 == choose){printf("排雷功能\n");}else if (0 == choose){printf("退出游戏\n");break;}else{printf("输入错误,请重新输入\n");}} while (choose);}

实现效果如下图:
在这里插入图片描述

八、标记功能的菜单

  • 标记功能是玩家操作信息,传入show棋盘(数组)。
  • 玩家只在9×9棋盘中标记,所以使用 ROW 和 COL。
  • 标记功能应该有 1. 标记位置 2. 取消标记 3. 不标记了等三个功能。
  • 标记功能实现的同时对标记的雷进行计数,方便判断胜利。
//test.c 源文件 -- game函数
void game()
{int choose = 0;// 定义两个二维数组char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };// 初始化棋盘InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');// 布置雷SetBoard(mine, ROW, COL);// 打印棋盘DisplayBoard(mine, ROW, COL);DisplayBoard(show, ROW, COL);// 玩家开始排雷do{printf("****************\n");printf("*** 1. 标记  ***\n");printf("*** 2. 排雷  ***\n");printf("*** 0. 退出  ***\n");printf("****************\n");printf("请选择:>");scanf("%d", &choose);if (1 == choose){printf("标记功能\n");SignBoard(show, mine, ROW, COL);}else if (2 == choose){printf("排雷功能\n");}else if (0 == choose){printf("退出游戏\n");break;}else{printf("输入错误,请重新输入\n");}} while (choose);}

//game.h 头文件
#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_COUNT 10// 初始化函数声明
void InitBoard(char board[ROWS][COLS], int rows, int cols, char sign);// 打印函数声明
void DisplayBoard(char board[ROWS][COLS], int row, int col);// 布置雷函数声明
void SetBoard(char board[ROWS][COLS], int row, int col);// 标记功能函数声明
int SignBoard(char show[ROWS][COLS],char mine[ROWS][COLS], int row, int col);

//game.c 源文件 ---SignBoard函数
// 标记功能函数定义
int SignBoard(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{int choose = 0;do{printf("******************\n");printf("*** 1.标记位置 ***\n");printf("*** 2.取消标记 ***\n");printf("*** 0.不标记了 ***\n");printf("******************\n");printf("请选择:>");scanf("%d", &choose);if (1 == choose){printf("标记位置\n");}else if (2 == choose){printf("取消标记\n");}else if (0 == choose){printf("不标记了\n");break;}else{printf("输入错误,请重新输入\n");}} while (choose);
}

实现效果如下图:
在这里插入图片描述

九、标记功能菜单的实现

  • 标记位置需要玩家输入
  • 需要判断合法性
  • 需要判断是否被排查
  • 定义两个计数变量,若两变量相等,并且等于雷的个数时,判定排雷成功
  • 每次标记完成或取消标记后,打印棋盘
//game.c 源文件---SignBoard函数完整
// 标记功能函数定义
int SignBoard(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int choose = 0;static int sum = 0; // 定义标记的总数static int count = 0; // 定义标记的雷的总数do{printf("******************\n");printf("*** 1.标记位置 ***\n");printf("*** 2.取消标记 ***\n");printf("*** 0.不标记了 ***\n");printf("******************\n");printf("请选择:>");scanf("%d", &choose);if (1 == choose){printf("请输入标记坐标(空格隔开):>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col) // 判断坐标合法性{if (show[x][y] == '*') // 判断坐标是否排查过{show[x][y] = '$';sum++; // 没标记一个加1if (mine[x][y] == '1'){count++; // 标记的位置如果是雷 加1}}else{printf("坐标已经被排查过了,请勿重复排查\n");}}else{printf("超出棋盘范围,请重新输入\n");}DisplayBoard(show, ROW, COL);break;}else if (2 == choose){printf("请输入标记坐标(空格隔开):>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col) // 判断坐标合法性{if (show[x][y] == '$') // 判断坐标是否标记过{show[x][y] = '*';sum--; // 没标记一个加1if (mine[x][y] == '1'){count--; // 标记的位置如果是雷 加1}}else{printf("坐标未被标记,请重新选择\n");}}else{printf("超出棋盘范围,请重新输入\n");}DisplayBoard(show, ROW, COL);break;}else if (0 == choose){// 不标记直接跳转break;}else{printf("输入错误,请重新输入\n");}} while (choose);if (sum == count && count == EASY_COUNT){sum = 0;count = 0;return EASY_COUNT;}else{return 0;}}
  • 把雷的个数设置为1进行测试
  • 主要过程是
    1. 先标记一个不是雷的位置。
    1. 再标记雷的位置。
    1. 最后取消标记不是雷的位置。
    1. 测试是否判定成功。
  • 效果如下图:
    在这里插入图片描述

总结

C语言从新建文件到游戏菜单,游戏函数,初始化棋盘,打印棋盘,布置雷函数,玩家排雷菜单,标记功能菜单及实现等的操作及实现效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/2345.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言(static和extern)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…

【六十四】【算法分析与设计】699. 掉落的方块,离散化操作,线段树优化,区间查询sum+区间更新update

699. 掉落的方块 在二维平面上的 x 轴上&#xff0c;放置着一些方块。 给你一个二维整数数组 positions &#xff0c;其中 positions[i] [left(i), sideLength(i)] 表示&#xff1a;第 i 个方块边长为 sideLength(i) &#xff0c;其左侧边与 x 轴上坐标点 left(i) 对齐。 每个…

vuex数据永久存续

第一步下载 vuex 并创建store下js文件 第二步 npm install vuex-persistedstate 第三步 引用 vuex-persistedstate 配置 plugins 项 import createPersistedState from vuex-persistedstateplugins:[createPersistedState({//存储方式&#xff1a;localStorage\sessionStor…

【Linux】开关机命令和服务管理类命令

一般Linux是不会经常进行关机的,关机的正确流程是: sync->shutdown->reboot->poweroff sync: 将内存中的数据同步到硬盘中poweroff: 关闭系统,等同于shutdown -h nowreboot: 重启系统,等同于 shutdown -r nowshutdown[选项] [时间] shutdown命令常见用法: shutdown:…

锂电池3.7V-4.2V降3.3V2.8V同步降压WT6015

锂电池3.7V-4.2V降3.3V2.8V同步降压WT6015 WT6015 是一款高效单片同步步降稳压器&#xff0c;采用恒定频率和电流模式架构。该设备提供可调节版本&#xff0c;适应不同的应用需求。在无负载条件下&#xff0c;其电源电流仅为40微安&#xff0c;而在关断状态下&#xff0c;电流…

类之间的关系

文章目录 一、横向关系复合&#xff08;组合&#xff09;委托&#xff08;聚合&#xff09;依赖关联 二、纵向关系&#xff08;继承&#xff09;继承下构造析构执行的顺序继承方法继承中的作用域多重继承 总结 一、横向关系 复合&#xff08;组合&#xff09; 包含与被包含黑色…

目标检测——YOLOv6算法解读

论文&#xff1a;YOLOv6: A Single-Stage Object Detection Framework for Industrial Applications (2022.9.7) 作者&#xff1a;Chuyi Li, Lulu Li, Hongliang Jiang, Kaiheng Weng, Yifei Geng, Liang Li, Zaidan Ke, Qingyuan Li, Meng Cheng, Weiqiang Nie, Yiduo Li, Bo …

1212332

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

手机号码携号转网查询API接口是什么

手机号码携号转网查询API接口又叫运营商携号转网查询API接口&#xff0c;是指通过手机号精准查询该号码转网前及转网后所归属运营商。运营商携号转网查询API接口多用于营销场景&#xff0c;如运营商业务办理、客户信息查询、携号转网、电话营销等&#xff0c;接下来我们聊一聊怎…

【技巧】Git 版本控制工具没有图标提示怎么办?

Git 版本控制工具在日常开发中使用率是非常高的&#xff0c;多数情况下会安装 TortoiseGit 之类的插件&#xff0c;让文件夹显示图标&#xff0c;方便观察文件的状态。但是有时装完插件之后发现&#xff0c;文件夹/文件并没有图标显示&#xff0c;可以按照以下思路进行排查&…

【计算机毕业设计】药品销售系统产品功能介绍——后附源码

&#x1f389;**欢迎来到我的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 一名来自世界500强的资深程序媛&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 在深度学习任务中展现出卓越的能力&#xff0c;包括但不限于…

手把手教数据结构与算法:有序线性表设计

问题描述 设计一个有序线性表类&#xff0c;要求完成初始化&#xff0c;插入和遍历功能&#xff0c;使得表内元素实现有序排列&#xff08;从小到大&#xff09;。同时实现合并功能&#xff0c;使得两个线性表能够合并为一个线性表&#xff08;可能存在重复元素&#xff09;。…

【java】27:java绘图

坐标体系 - 介绍&#xff1a; 下图说明了Java坐标系。坐标原点位于左上角&#xff0c;以像素为单位。在Java坐标系中&#xff0c;第一个是x坐标&#xff0c;表示当前位置为水平方向&#xff0c;距离坐标原点个像素&#xff1b;第二个是y坐标&#xff0c;表示当前位置为垂直方向…

HTML使用jQuery实现两个点击按钮,分别控制改文本字体颜色和字体大小

jQuery 简介 jQuery 是一个广泛使用的 JavaScript 库&#xff0c;旨在简化对 HTML 文档的操作、事件处理、动画效果和 AJAX 等操作。 案例源码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name&q…

毕业撒花 流感服务小程序的设计与实现

目录 1.1 总体页面设计 1.1.1 用户首页 1.1.2 新闻页面 1.1.3 我的页面 1.1.5 管理员登陆页面 1.1.6 管理员首页 1.2 用户模块 1.2.1 体检预约功能 1.2.2 体检报告功能 1.2.4 流感数据可视化功能 1.2.5 知识科普功能 1.2.6 疾病判断功能 1.2.7 出示个人就诊码功能 …

【笔试强训】day9

1.添加逗号 思路&#xff1a; 没思路 代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include<string> #include<algorithm> using namespace std;int main() {string a;cin >> a;string ans;int p 1;for (int i a.si…

J8 inceptionv1

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 卷积神经网络大家族中有很多经典的网络&#xff0c;前面已经学习resnet,densenet相关网络&#xff0c;今天学习一种更久远的一种网络GoogLenet 网络结构…

【Java--数据结构】模拟实现ArrayList

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 LIst 顺序表ArrayList 顺序表优点 IList接口 ArrayList中定义要操作的数组 在MyArrayList中 重写接口方法 新增元素 在指定位置插入元素 pos不合法异常 判断和查找元素…

二维码相册怎么做?图片转换为二维码的方法

二维码现在可以用来承载大量的内容&#xff0c;通过扫描二维码即可通过扫描设备获取信息。图片生成二维码之后&#xff0c;用户可以在不保存图片直接扫码来查看图片&#xff0c;这种方式可以有效的提高图片的安全性&#xff0c;防止图片信息泄露。 怎么用二维码来作为相册展现…