c++实现扫雷游戏(控制台不闪屏版)

  

之前写了一个c++的控制台扫雷小游戏,但由于过度使用系统(cls)刷屏,导致闪屏,因此重写了一个改善的不闪屏版本,并把逻辑重新捋了一遍。

  

<强> map.h

        的ifndef MAP_H_   #定义MAP_H_      #定义MAX_WID 18   #定义MAX_LEN 32   #定义UP_EDGE 1//上边界   #定义LEFT_EDGE 1//左边界   #定义RIGHT_EDGE _len//右边界   #定义DOWN_EDGE _wid//下边界      结构位置{//用于表示位置   短x;   短y;   };      struct MapInfo{//表示扫雷图的信息   int n;//1表示地雷,0表示空格,1 ~ 8表示雷数   bool国旗;//是否已经被打开   };      空白gotoxy(短,短);//光标移动函数      类图{   私人:   int _len _wid;//图的长宽   int _mines平等;//雷数和空格数   pos位置;//光标位置   MapInfo数据[MAX_WID] [MAX_LEN];//地图      公众:   空白ChooseMode ();//选择游戏模式,初级,中级,高级   空白画();//画出地图   空白InitMap ();//初始化地图信息   空白SetMine ();//设置地雷   空白SetNum ();//根据周围地雷数计算数字   无效移动();//负责移动   空白OpenBlock ();//打开方块   空白OpenAll ();//如果触雷则全部打开   空打();//提供游戏操作接口   bool IfWin ();//判断输赢   bool IfLose ();//空白显示();   };      # endif      

<强>地图类的实现

  

map.cpp         # include“map.h”   # include & lt; iostream>   # include & lt; cstdio>   # include & lt; cstdlib>//提供随机函数,兰德(),将srand ()   # include & lt; ctime>//提供时间()函数   # include & lt; conio.h>//提供不回显的输入函数getch ()   # include & lt; windows.h>//提供系统()内命令      #定义GOTOXY (pos) GOTOXY (2 * (pos)。x - 1, (pos)。y - 1)   #定义POSITION_POS _wid + 1//游戏信息的位置,这里是位置信息   #定义POSITION_BLANKS _wid + 2//空格数位置   #定义POSITION_TIMES _wid + 3//时间显示位置   #定义POSITION_SITUATION _wid + 4//输赢状态位置      使用std:: cin;   使用std:: cout;      空白gotoxy (x、y){//自行百度   COORD pos={x, y};   处理胡特=GetStdHandle (STD_OUTPUT_HANDLE);   SetConsoleCursorPosition(胡特、pos);   }         空白地图:ChooseMode () {   系统(cls);//清屏   cout & lt; & lt;“请选择模式\ n”;   cout & lt; & lt;“1:初学者\ n”;   cout & lt; & lt;“2:中间\ n”;   cout & lt; & lt;“3:专家\ nYour模式:”;      字符模式;   ,cin祝辞的在模式;   而(模式!=' 1 ',,模式!=' 2 ',,模式!=' 3 '){//只接受1,2,3   cout & lt; & lt;“\ nWrong模式,请输入1、2、或3 \ nYour模式:”;   ,cin祝辞的在模式;   }   开关(模式){//根据模式改变地图信息   案例1:_len=_wid=8;_mines=10;打破;   “2”:_len=_wid=16;_mines=40;打破;   默认值:_len=30;_wid=16;_mines=99;   }   平等自愿=_len * _wid - _mines;//更新空格数   }         空白地图:画(){//画出地图   系统(cls);   SetConsoleOutputCP (437);//自行百度,否则无法显现方块而是显现?   for (int i=1;我& lt;=_wid;我+ +){   printf (“|”);   for (int j=1;j & lt;=_len;j + +)   printf (" % c ", 219);//219是方块   printf (" | \ n ");   }   gotoxy (0, POSITION_POS);   printf("位置:(% 2 d % 2 d) \ n”, pos.x, pos.y);   printf(“空白:% 2 d”,平等);   GOTOXY (pos);//查看地图。h内说明   }         空白地图:InitMap () {   for (int i=0;我& lt;=_wid + 1;我+ +)//从0 ~ _wid + 1是因为可以假设地图边界的空格存在,且为0,后面计算   for (int j=0;j & lt;=_len + 1;j + +) {   数据[我][j]。国旗=false;//设置为没有被打开   数据[我][j]。n=0;//全部设为空格   }   pos.x=pos.y=1;   }         空白地图:SetMine () {   int矿山=_mines;   int x, y;   移动();//先执行移动(),避免第一个空就触雷   将srand(时间(NULL));   而(矿山){   x=rand () % _wid + 1;   y=rand () % _len + 1;   如果数据(0==[x] [y]。n,,(x !=pos.x,,y !=pos.y)){//后面的条件可以避免第一个打开的空被设置为地雷,避免第一步就触雷   数据[x] [y]。n=1;//雷设为1   数据[x] [y]。国旗=true;//设为雷的格子标志置为真实的   矿山,;   }   }   }         空白地图:SetNum () {   for (int i=1;我& lt;=_wid;我+ +){   for (int j=1;j & lt;=_len;j + +){//逐个计算格子周围的8个格子的雷数   如果数据(1==[我][j] .)继续;   如果数据(1==[张][j - 1] .)数据[我][j] . + +;   如果(1==数据(张)[j] .)数据[我][j] . + +;   如果数据(1==[张][j + 1] .)数据[我][j] . + +;   如果数据(1==[我][j - 1] .)数据[我][j] . + +;   如果数据(1==[我][j + 1] .)数据[我][j] . + +;   如果数据(1==[i + 1] [j - 1] .)数据[我][j] . + +;   如果数据(1==[i + 1] [j] .)数据[我][j] . + +;   如果数据(1==[i + 1] [j + 1] .)数据[我][j] . + +;   }   }   OpenBlock ();//与SetMine()配套,这时才正好打开用户要打开的第一个空,避免第一步就触雷   }         空白地图:移动(){   char mv;   而(1){   mv=getch ();   如果(mv==' ')休息;//如果是“(空格),那么就结束移动,打开方块   如果(mv !=' w ',,mv !=' a ',,mv !=' s ',,mv !=' d ')继续;//移动只接受w s d四个键   开关(mv) {   例“w”:   如果(pos.y !=UP_EDGE) pos.y——;   打破;   例“s”:   如果pos.y !=DOWN_EDGE pos.y + +;   打破;   例a:   如果(pos.x !=LEFT_EDGE) pos.x——;   打破;   默认值:   如果pos.x !=RIGHT_EDGE pos.x + +;   }   POSITION_POS gotoxy(12日);//12,可以不用重新输入覆盖已经存在的“位置:”,而是接着输入   printf (" % 2 d % 2 d”, pos.x, pos.y);   GOTOXY (pos);//回到用户所指的位置   }   }         #定义IF_IN_EDGE (p) ((p。x祝辞=LEFT_EDGE,,p。x & lt;=RIGHT_EDGE),,(p。y祝辞=UP_EDGE,,p。y & lt;=DOWN_EDGE))//判断是否越界   #定义IF_PUSHIN_STACK (p)(数据[p.y] [p.x]。标志==false,,IF_IN_EDGE (p))//判断是否入栈,条件是:不越界且格子未被打开   #定义PUSHIN_STACK (p){堆栈(+ +顶级)=p;数据[p.y] [p.x]。国旗=true;平等自愿,;}//入栈,并设置为已打开,并减少空格数,用于定是否获胜      空白地图:OpenBlock () {   如果(数据[pos.y] [pos.x]。标志==true)返回;//如果格子打开过,就跳出函数   int num,=0;   堆栈位置[_len * _wid & lt; & lt;1);//栈,用于存位置   临时位置;   堆栈(顶级)=pos;   数据[pos.y] [pos.x]。国旗=true;//要打开的第一个格子设置为打开   平等自愿,;   而(!=1){   temp=堆栈(最高——);   GOTOXY(临时);   num=数据[temp.y] [temp.x] .;   如果(0==num) {   printf (" ");//如果是0,那么输出空格,并且判断一下周围8个是否要打开,如果不是地雷就打开   temp.y——;temp.x——;   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

c++实现扫雷游戏(控制台不闪屏版)