先说明一下,本来这个文章我在新浪博客上发过一次,但是不知道最近怎么回事新浪总登不上去= =再加CSDN是专门为IT类服务的(我刚刚注册的号,给我的印象是这样)就在这再写一次吧,这次我会尽量写的详细一点。
鄙人呢是个小白,会的不多也就是C++了,而且目前还是命令行版本的,图形部分还没学会,有的地方还很麻烦,总之不管怎么说吧算是稀里糊涂的写出来了,发在这和大家交流一下,恭请各路大神赐教~~
扫雷,作为一款小游戏可以说非常成功,一段时间内风靡全世界,也是您在空余时间不多时用来消遣的比较好的一个选择(怎么像打广告一样= =)相信大家对它的规则应该不陌生吧,不过呢我在这还是再啰嗦一会。
1.点击一个方格,如果翻开是地雷的话则失败
2.如果翻开不是地雷的话,若为非零数字则表示周围若干个格子中地雷的个数(中间部分则为周围8个格子,边缘非顶点处则为5个格子,顶点处为3个格子)
3.若为0则会向外拓展
4.若玩家可以确定一个地方为地雷则可以对此进行标记
5.当非地雷格子被全部翻开时则获胜
扫雷的算法里,我想最复杂的地方我不细说大家也应该知道,就是空格的处理。尤其是遇到一大片空地时,简直就是多米诺效应。这种情况下,我想最好的方法恐怕也就是递归了。
我这里写的是40/16*16的扫雷,也就是16*16的地图40个地雷,属于中等难度。想调的话,改动几个地方的数即可
无心之举,难免有纰漏之处,各路大神若有改进之言,在下洗耳恭听。
好了废话不多说了,上代码,我会尽量把注释加全。
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<conio.h>//代码中的getche()在这个头文件里,只取一个字符
#include<windows.h>//代码中用到了部分windowsAPI函数
#define LANDMINE 16
using namespace std;
int field[16][16],show[16][16]={
{0}};//field数组是指整个地图的实际情况,show数组是指地图的探测情况,0-未翻开且未标记,1-翻开,2-标记
char answer[16][16];//正确答案,当用户失败时输出
int mine[40];//mine数组用于存储地雷位置,具体为16*行数+列数
void gotoxy(int x,int y)/*该函数用于移动光标,其中SetConsoleCursorPosition函数请看这里<a target=_blank href="http://baike.sogou.com/v73182107.htm?fromTitle=SetConsoleCursorPosition">http://baike.sogou.com/v73182107.htm?fromTitle=SetConsoleCursorPosition</a> */
{
COORD pos;
pos.X=2*x;
pos.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
void color(int a)/*该函数用于改变输出字符颜色,其中SetConsoleTextAttribute函数请看这里<a target=_blank href="http://baike.sogou.com/v72432554.htm?fromTitle=SetConsoleTextAttribute">http://baike.sogou.com/v72432554.htm?fromTitle=SetConsoleTextAttribute</a> */
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}
int once(int mine[],int key,int j)//布雷时用到,观看取到随机数之前是否出现过,出现过则返回0,否则为1
{
int i;
for(i=0;i<j;i++)
{
if(mine[i]==key)
return 0;
}
return 1;
}
int count(int field[][16],int i,int j)/*这个函数我知道我写的很麻烦= =用于得到布雷后非雷格子对应的数字,由于中间部分、边缘和顶点有一些很小的差别,我这就分了好多情况……*/
{
int d=0;
int k,l;
if(i>0&&i<15&&j>0&&j<15)
{
for(k=i-1;k<=i+1;k++)
{
for(l=j-1;l<=j+1;l++)
{
if(field[k][l]==LANDMI