C语言项目:扫雷大战精简版

        一直说写个几百行的小项目,于是我写了一个控制台的扫雷,没有想到精简完了代码才200行左右,不过考虑到这是我精简过后的,浓缩才是精华嘛,我就发出来大家一起学习啦,看到程序跑起来能玩,感觉还是蛮有成就感的~~~

        扫雷应该属于一款大众游戏,从我初中使用计算机开始,它就被集成到了windows系统中,虽然他是这么经典,我还是要介绍一下他的玩法,然后再考虑在控制台中怎么实现它。

640?wx_fmt=jpeg

编辑


请点击输入图片描述


1、游戏的主界面,是一个一个小方格,在小方格上单击左键,可以翻开小方格看看后面有什么。

2、在这些小方格的背后隐藏着雷,如果不幸点中了雷,那么就GameOver了。

3、如果点中的不是一个雷,那么就是一块空地,这个时候会出现两种情况:

(1)用鼠标点中的空地周围八个点内有雷,那么就显示雷的个数

(2)用鼠标点中的空地周围没有雷,这个时候就将周围的空地全部显示出来,遇到该显示数字的空地,就将数字显示出来。(仔细观察你会发现,数字会将空地围起来,这是一句废话,但是也值得想一想这是为什么)

4、在小方格上,点击鼠标的右键,可以将一个空地标记为雷,当然这个功能只是为了方便你记忆你之前确定是雷的地方。(还有左右键都点,和点击右键出现?标记,这里就不谈啦)

5、当空地上剩余的格子数和雷的个数一样多,那么这个时候就应该算是胜利啦。


        OK~游戏流程说完了,这个时候该谈谈如何实现了。

1、首先需要一张地图,一般情况下我们都可以用一个二维数组表示一个地图,每一个元素代表着扫雷中的一个小方格。相应元素存储0,那么地图上的这个位置就是空地,相应元素存储1,那么就代表这个位置就一颗雷。

2、在控制台上依照二维数组长度和宽度,打印相应的小方块。

3、然后就用鼠标点击那些小方块,对于控制台来讲,在黑框框的区域中是有坐标的,可以使用一些函数捕获到你点击了屏幕的哪一个坐标。

4、对于控制台来说,打印一个字符,有的字符横向占一个位置比如普通的字母数字,有的字符横向占两个位置比如一些图形字符: ①②③■◆等等,这点在控制台编程的时候要注意。

5、当点击屏幕的时候,获取到点击的坐标后,去二维数组中查看相应的位置是雷还是空地,从而做相应的处理。

(1)假如点击到了雷,那么就控制游戏结束

(2)假如点击到了空地有两种情况

(1)点击的空地周围有雷,那么就将雷的个数显示出来

(2)假如点击的空地周围没有雷,那么就使用递归的方法去探测周围的点,探测出与其相连的所有周围有雷的点。


下面就是代码啦:

// saolei.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"

#include <windows.h>

#include <stdlib.h>

#include <time.h>

#define Boom 10

int a[10][10] = {0};

COORD TempPos[100] ={0};

int nSign = 0;

/************************************

函数名 : WriteWchar

函数作用: 在控制台相应的坐标上显示一串字符

返回值 : void

参数 : int x 横坐标

参数 : int y 纵坐标

参数 : char szString[] 要显示的字符串

说明 :

************************************/

void WriteWchar(int x,int y,char szString[])

{

HANDLE hOut= GetStdHandle(STD_OUTPUT_HANDLE);

COORD pos = {x*2,y};

SetConsoleCursorPosition(hOut,pos);

printf("%s",szString);

}

/************************************

函数名 : DrawNumber

函数作用: 在相应的坐标上,根据传入的数字,打印相应的数字字符

返回值 : void

参数 : COORD pos 要打印的位置

参数 : int nNumber 要打印的数字

说明 :

************************************/

void DrawNumber(COORD pos,int nNumber)

{

switch (nNumber)

{

case 1:

WriteWchar(pos.X,pos.Y,"①");

break;

case 2:

WriteWchar(pos.X,pos.Y,"②");

break;

case 3:

WriteWchar(pos.X,pos.Y,"③");

break;

case 4:

WriteWchar(pos.X,pos.Y,"④");

break;

case 5:

WriteWchar(pos.X,pos.Y,"⑤");

break;

case 6:

WriteWchar(pos.X,pos.Y,"⑥");

break;

case 7:

WriteWchar(pos.X,pos.Y,"⑦");

break;

case 8:

WriteWchar(pos.X,pos.Y,"⑧");

break;

default:

break;

}

}

/************************************

函数名 : GetNumber

函数作用: 获取一个点的四周有几颗雷

返回值 : int

参数 : COORD pos 要探测的点的坐标

说明 :

************************************/

int GetNumber(COORD pos)

{

int nCount = 0;

for(int i = pos.X-1;i<=pos.X+1;i++)

for (int j = pos.Y-1;j<=pos.Y+1;j++)

{

if (a[j][i] == Boom)

{

nCount++;

}

}

return nCount;

}

/************************************

函数名 : Drawmap

函数作用: 打印一下地图

返回值 : void

说明 :

************************************/

void Drawmap()

{

for (int i =0;i<10;i++)

{

for (int j =0;j<10;j++)

{

WriteWchar(j,i,"■");

}

}

}

/************************************

函数名 : Init

函数作用: 随机生成10个地雷,然后存到数组中

返回值 : void

说明 :

************************************/

void Init()

{

srand(time(NULL));

for (int i =0;i<10;i++)

{

int Temp_x = rand()%10;

int Temp_y = rand()%10;

//判断这个地方是不是已经生成一个雷了,如果没有,赋值为雷

if (a[Temp_x][Temp_y]!=Boom)

{

a[Temp_x][Temp_y] = Boom;

}

//如果是雷,就相当于本次生成没有发生过。。。。。

else

{

i--;

}

}

Drawmap();

}

/************************************

函数名 : IsClose

函数作用: 判断是不是已经探测过的点,由于使用的8方向递归的探测,这样避免重复

返回值 : bool

参数 : COORD posTemp

说明 :

************************************/

bool IsClose(COORD posTemp)

{

for (int i =0;i<nSign;i++)

{

if(TempPos[i].X == posTemp.X&&TempPos[i].Y == posTemp.Y)

return true;

}

return false;

}

/************************************

函数名 : IsKongdi

函数作用: 判断一个点是空地,还是雷,如果是空地,需要做其他处理

返回值 : void

参数 : COORD pos

说明 :

************************************/

bool IsKongdi(COORD pos)

{

int nNumber = 0;

//1 如果是雷,就直接返回一个false说明要挂了

if (a[pos.Y][pos.X] == Boom)

{

return false;

}

//2 如果不是雷,那么就做后续处理

else

{

//2.1先判断一下周围有几颗雷

nNumber = GetNumber(pos);

if (nNumber!=0){

//有几颗雷,就打印这个数字

DrawNumber(pos,nNumber);

return true;

}

else

{

//如果没有雷,那就先画空地出来,然后向周围扩散去探测其他点

WriteWchar(pos.X,pos.Y," ");

}

}

//2.2点到了空地,但是周围没有雷的情况的处理,继续去探测周围8个点

for(int i = -1;i<=1;i++)

for (int j = -1;j<=1;j++)

{

COORD posTemp = {pos.X+i,pos.Y+j};

//是不是越界了

if (i==0&&j==0||posTemp.X==-1||posTemp.Y==-1||posTemp.X==10||posTemp.Y==10)

continue;

//这个点是不是已经探测过了

if (IsClose(posTemp))

continue;

//这个点没有探测过,就将其加入到数组中,然后使其在以后的探测中,存入

TempPos[nSign++] =posTemp;

IsKongdi(posTemp);

}

return true;

}

/************************************

函数名 : GetMousePosition

函数作用: 获取鼠标点击的位置,假如没有获取到,就返回(-1,-1)

返回值 : COORD 鼠标点击的坐标

说明 :

************************************/

COORD GetMousePosition()

{

HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);

INPUT_RECORD stcInput = {0};

DWORD buffer;

COORD pos = {-1,-1};

ReadConsoleInput(hIn,&stcInput,1,&buffer);

if (stcInput.EventType == MOUSE_EVENT)

{

MOUSE_EVENT_RECORD stcMouseEnent = stcInput.Event.MouseEvent;

if (stcMouseEnent.dwButtonState ==FROM_LEFT_1ST_BUTTON_PRESSED )

{

pos = stcMouseEnent.dwMousePosition;

pos.X/=2;

}

}

return pos;

}

int _tmain(int argc, _TCHAR* argv[])

{

Init();

COORD pos;

//开始游戏

while(1)

{

//获取鼠标点击位置

pos = GetMousePosition();

if (pos.X!=-1)

{

//如果鼠标点击的位置被探测过了,就开始下一次循环

if (IsClose(pos))

{

continue;

}

TempPos[nSign++] =pos;

bool bIskongdi = IsKongdi(pos);

//点到雷了,就直接退出游戏了。

if (false ==bIskongdi)

{

system("cls");

WriteWchar(20,10,"you lose");

getchar();

break;

}

//检测是不是赢了,赢的条件就是没有被探测的点的个数和雷的个数相等

if (nSign ==90)

{

system("cls");

WriteWchar(20,10,"you win");

}

}

}

return 0;

}

项目不是很长,但是注释我写的还算明白,估计大家都可以看得懂,希望对于新手们有一定的帮助,最后,谢谢大家的支持!!!

640?wx_fmt=jpeg

关注点赞

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

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

相关文章

mysql ignore 1 lines_MYSQL使用笔记(1)

创建用户 用户名 dnsexpuser 密码&#xff1a;dnsexp1347insert into mysql.user(Host,User,Password) values (localhost,dnsexpuser,password(dnsexp1347)) ;创建数据库分配数据库权限create database wap_tagdb ;grant all privileges on wap_tagdb.*to waptaglocalhost ide…

C语言十大经典例题:附答案

1、/*输出9*9口诀。共9行9列&#xff0c;i控制行&#xff0c;j控制列。*/#include <stdio.h>int main(){ int i,j,result;for (i1;i<10;i){ for(j1;j<10;j){resulti*j;printf("%d*%d%-3d",i,j,result);/*-3d表示左对齐&#xff0c;占3位*/}printf(&qu…

C语言项目:图形马赛克处理技术

每个人都有讨厌的人&#xff0c;例如我就比较讨厌三个姓马的人&#xff0c;马云、马化腾和马赛克。马云骗女人的钱&#xff0c;马化腾骗孩子的钱&#xff0c;马赛克阻挡了人们的分享和交流 。那么大家是不是知道我们今天要分享的项目是什么啦&#xff1f;马赛克处理技术莫非就是…

C语言项目:灰度处理技术

Hello&#xff0c;今天给大家带来的是一个比较简单的图形处理技术-灰度处理技术。那么到底什么是灰度处理技术呢&#xff1f;简单来说&#xff0c;所谓的灰度处理技术就是把一张彩色的图片变成一张灰色的图片。如下图所示&#xff0c;左边是原图&#xff0c;右边则是已经被处理…

C语言项目:推箱子大战

还记得大家小时候玩过的游戏吗&#xff1f;曾经的坦克大战、推箱子、贪吃蛇都是我们以前玩过的小游戏&#xff0c;然而现在随着大型单机、网络游戏的光芒照耀下&#xff0c;那些曾经的小游戏都渐渐消失了&#xff0c;也或许是我们都已经长大了吧。那么今天&#xff0c;我给大家…

java项目加减乘除验证码_课堂Java小程序(加减乘除与验证码)

一、编写一个程序&#xff0c;用户输入两个数&#xff0c;求出其加减乘除&#xff0c;并用消息框显示计算结果。1.设计思想&#xff1a;从键盘输入两个数字和运算符&#xff0c;然后计算。将输入的数字及运算符由字符型转换为整型&#xff0c;再用if判断输入的运算符&#xff0…

C语言绘图:可爱叮当猫

大家对于叮当猫可以说是很熟悉了吧&#xff0c;他还有另外一个名字&#xff0c;也就是哆啦a梦。即便你没有看过他的电影动画&#xff0c;也总会听说过的。叮当猫神奇的口袋总是能够掏出我们幻想功能的任何道具&#xff0c;任意门能够带我们去到任何地方&#xff0c;以及插在头上…

jgit git pull_使用JGit API探索Git内部

jgit git pull您是否想过提交及​​其内容如何存储在Git中&#xff1f; 好吧&#xff0c;我有&#xff0c;在上一个下雨的周末我有一些空闲时间&#xff0c;所以我做了一些研究。 因为我对Java的感觉比对Bash的感觉要多&#xff0c;所以我使用JGit和一些学习测试来探究提交的G…

MFC实现Windows锁屏

编辑Windows锁屏锁屏软件相信大家都见过&#xff0c;以前我去网吧上网的时候也用过这个功能&#xff0c;当你有事情需要立即离开&#xff0c;而又不想让别人碰你的电脑&#xff0c;就需要用扫锁屏软件啦&#xff0c;锁住屏幕之后等回来的时候再输入密码解锁。同样的&#xff0c…

学习红客技术必备

互联网时代已悄悄来临&#xff0c;作为新时代的人们&#xff0c;我们日常生活、工作、学习方面都需要借助互联网来完成&#xff0c;这样&#xff0c;又产生一种新的问题&#xff0c;那就是网络安全的问题&#xff0c;有时我们拼命加班好不容易完成的东西&#xff0c;在一夜之间…

md5withrsa java_浏览器运行java插件报错:Algorithm constraints check failed: MD5withRSA

今天使用kvm管理机房机器的时候发现一只连不上&#xff0c;报以下错误&#xff1a;sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Algorithm constraints check failed: MD5withRSA我确认我已经把…

今晚课题:2019-3-20

今晚课题C/C万年历技术实现原理上课时间&#xff1a;20:30--22:30上课老师&#xff1a;杰越教育-Larry老师上课地址&#xff1a;https://ke.qq.com/course/353889 课程内容&#xff1a;1、C/Cfor逻辑原理2、重要点数据结构分析3、万年历效果实现展示赢在别人休息时&#xff0c;…

新版本的Selenium 4 Alpha会有什么期望?

我们所有人都属于测试领域&#xff0c;他们熟悉Selenium&#xff0c;Selenium是业界最流行的开源自动化工具之一。 Selenium的创始成员Simon Stewart在2018年8月正式宣布Selenium 4的发布日期以及它将为用户带来哪些新功能时&#xff0c;我们感到非常兴奋。 与Selenium 3一样&…

今晚课题:2019-3-22

今晚课题数据结构必会重点集合上课时间&#xff1a;20:30--22:30上课老师&#xff1a;杰越教育-Larry老师上课地址&#xff1a;https://ke.qq.com/course/353889 课程内容&#xff1a;1、C/C技术工作运用2、数据结构重点数组定义特点3、工作项目数组合理使用赢在别人休息时&…

Drools DMN最新开源引擎性能改进

我们一直在寻求改善Drools DMN开源引擎的性能。 我们最近审查了DMN用例&#xff0c;其中输入数据节点的实际输入总体有所不同。 这突出显示了引擎的次佳性能&#xff0c;我们在最新版本中对此进行了改进。 我想分享我们的发现&#xff01; 基准制定 当我们开始为该用例运行一个…

今晚课题:2019-3-23

今晚课题剖析《服务器高并发-IOCP模型架构》上课时间&#xff1a;2019/03/23 20:30--22:30授课讲师&#xff1a;杰越教育C/C学院--Vico课程链接&#xff1a;https://ke.qq.com/course/353889?tuin7472c9c 课程内容&#xff1a; 1、C/C编程语言入门精通 2、C线程技术在服务器…

使用Selenium WebDriver测试自动化的22条实用技巧

使用Selenium进行测试自动化已使全球的网站测试人员能够轻松执行自动化的网站测试。 Webdriver是Selenium框架的核心组件&#xff0c;通过它您可以针对不同类型的浏览器&#xff08;例如Google Chrome&#xff0c;Mozilla Firefox&#xff0c;Safari&#xff0c;Opera&#xff…

这么奇葩搞笑的代码注释你见过吗

程序员作为一种“异类”&#xff0c;虽然他们平时给人们的留下的印象并不太好&#xff0c;觉得他们只会写代码。但是有的时候不得不佩服他们天马行空的想象力&#xff0c;他们可能会利用注释让你噗嗤一笑&#xff0c;下面我们来看看那些奇葩搞笑的代码注释吧。注释1&#xff1a…

C语言与Java的深情对话:儿子,还得多练几年啊!老子还是老子

很多小伙伴都老是会碰到疑问&#xff0c;其实还是基础没打扎实&#xff0c;这些题如果你不看答案你能知道多少呢&#xff1f;如果还有很多不知道就证明基础没打扎实&#xff0c;如果你还在入门纠结&#xff0c;如果你还在苦恼怎么入门&#xff01;小编有个建议&#xff0c;可以…

BAT人脸识别功能第二步-人脸检测

今晚课题点击【阅读原文】或长按图片【识别图中的二维码】即可参加今晚的课程。