复制代码
模拟鼠标各种按键
左键  翻开
右键  标雷
左右键  翻开周围 
        先判断当前点是否为已翻开的点
时间
地雷计数器
清屏
展开
    大于8时不管
    小于等于8时翻开本身
    为0时翻开周围的
输出
    同雷数图
雷区判断
判断游戏结束
    剩下的是否和雷数相等
    *标记出所有的雷
    踩到雷了
动态数组
 
第一次操作时才开始布雷
布雷后制作雷数图
0无雷  9本身是雷  10已经翻开的
10+X 表示 已经翻开的有数字的
20+X 表示 标了雷区的  (29则为正确标注的)
20表示边界
雷数选择范围
*翻开标记为雷区的点时进行确认操作
*选择重新开始等
    接着这盘游戏
    仅悔一步
*保存游戏?
*作弊功能?
//11.27
传值参数有很多的相似,可以进行封装:结构体,容器,数组
复制代码
 
复制代码
#include <iostream>
#include<vector>
#include<string>
#include"function.h"
using namespace std;
int main()
{
    int hight;
    int width;   //6*6开始
    int bob;
    while(1){
        cout<<"请输入雷阵高度(6-99):   " ;
        cin>>hight;
        if(hight<100 && hight >5){
            break;
        }
    }
    while(1){
        cout<<"请输入雷阵宽度(6-99):   " ;
        cin>>width;
        if(width<100 && width >5){
            break;
        }
    }
    while(1){
        cout<<"请输入地雷数目(8-"<<( width*hight/10*9) <<"):   " ;
        cin>>bob;
        if(bob<= (width*hight/10*9) && bob >7){
            break;
        }
    }
vector<vector<int> > map( hight+2, vector<int>(width+2,0) ); //创建地图
#if 0
    map[0][0]=9;
    map[0][width-1]=9;
    map[hight-1][0]=9;
    map[hight-1][width-1]=9;
#endif
    setGame(map, hight, width, bob);
    playGame(map, hight, width, bob);
}
复制代码
 
复制代码
#include"function.h"
#include<ctime>
#include<vector>
using namespace std;
void setBob(vector<vector<int>> & map, int bob ,int r, int w)
//开始随机布雷,并使得刚开始挖的点不为雷区
{
    //变量声明,确定map的高度和宽度等
    vector<vector<int>>::difference_type hight = map.end() - map.begin();
    vector<int>::difference_type width = map[0].end() - map[0].begin();
    vector<vector<int>>::size_type tmpH;
    vector<int>::size_type tmpW;
    //开始随机布雷
    srand(static_cast<int>(time(0))); 
    for(int i=0;i!=bob;++i){
        tmpH = rand() % (hight-2) +1;
        tmpW = rand() % (width-2) +1;
        if(map[tmpH][tmpW] == 9){
            --i;
        }
        else{
            map[tmpH][tmpW] = 9;
        }
    }
    //使刚开始挖的点不为雷区
    if(map[r][w] == 9){
        do{
            tmpH = rand() % (hight-2) +1;
            tmpW = rand() % (width-2) +1;
        }while(map[tmpH][tmpW] != 9);
    }
    map[tmpH][tmpW] = 9;
    map[r][w] = 0;
    
}
void setMap(vector<vector<int>> & map)
//设置每格中显示的雷数
{
    //变量声明,确定map的高度和宽度等
    vector<vector<int>>::difference_type hight = map.end() - map.begin();
    vector<int>::difference_type width = map[0].end() - map[0].begin();
    for(int i=1;i!=hight-1;++i){
        for(int j=1;j!=width-1;++j){
            if(map[i][j] > 8){
                ++map[i-1][j-1];
                ++map[i-1][j];
                ++map[i-1][j+1];
                ++map[i][j-1];
                ++map[i][j+1];
                ++map[i+1][j-1];
                ++map[i+1][j];
                ++map[i+1][j+1];
            }
        }
    }
    for(int i=1;i!=hight;++i){
        for(int j=1;j!=width;++j){
            if(map[i][j] > 9){
                map[i][j] = 9;
            }
        }
    }
    //设置边界的数值为20
    for(int i=0;i!=width;++i){
        map[0][i] = 20;
        map[hight-1][i] = 20;
    }
    for(int i=1;i!=hight;++i){ 
        map[i][0] = 20;
        map[i][width-1] = 20;
    }
}
int digBob(vector<vector<int>> & map ,int r ,int w)
//挖雷,返回已经挖开点的总数
//-1表示挖到雷了
{
    static int count = 0;
    if(map[r][w]>9 ){
        return count;          //挖的点已经翻开,或为边界,或标为雷区
    }
    else if(map[r][w] == 9){
        endGame(map,0,0);
        return -1;
    }
    else{
        map[r][w]+=10;
        ++count;           //挖点记数器
        //当前点的周围雷数为0则继续挖周围的点
        if(map[r][w] == 10){
            digBob(map,r-1,w-1);
            digBob(map,r-1,w);
            digBob(map,r-1,w+1);
            digBob(map,r,w-1);
            digBob(map,r,w+1);
            digBob(map,r+1,w-1);
            digBob(map,r+1,w);
            digBob(map,r+1,w+1);
        }
        
        return count;
    }
}
复制代码
 
复制代码
#include"function.h"
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int getCmd(int & hight, int & width)
//获取用户指令,返回坐标(通过引用)和操作类型
//如输入错误则返回相应错误代码:
   //-1:输入错误   -2:坐标越界
//hight及width的值可能会被修改
{
    int temp;            //存放坐标
    string cmd;
    do{
        cout<<"请输入指令:";
        getline( cin,cmd);
    }
    while(cmd.empty());
    int sizeCmd = cmd.size();
    if(sizeCmd == 4 || sizeCmd == 5){        //用户输入4或5个字符的可能性最大
        //检查输入是否正确
        for(int i=0;i!=4;++i){
            if(cmd[i]<48 || cmd[i]>57){
                return -1;
            }
        }
        temp = (cmd[0]-48)*10 + (cmd[1]-48);
        //检查输入坐标是否越界
        if(temp <= hight){
            hight = temp;
        }
        else{
            return -2;
        }
        temp = (cmd[2]-48)*10 + (cmd[3]-48);
        if(temp <= width){
            width = temp;
        }
        else{
            return -2;
        }
        if(sizeCmd == 4){
            return 1;     //默认返回值
        }
        else{
            if(cmd[4]>51 || cmd[4]<49){
                return -1;
            }
            else{
                return ( cmd[4]-48 );
            }
        }
    }
    else if(sizeCmd == 1){
        switch(cmd[0])
        {
        case ‘?‘:
        case ‘h‘:
        case ‘H‘:
            return 4;    //帮助
            break;
        case ‘r‘:
        case ‘R‘:
            return 5;    //重新开始
            break;
        case ‘e‘:
        case ‘E‘:
            return 6;    //退出
            break;
        default:
            return -1;
        }
    }
    else {
        return -1;
    }
    
}
void setGame(vector<vector<int>> & map, int hight,int width, int bob)
{
    outpMethod();
    setMap(map);
    outpMap(map);
    int hightGet;         
    int widthGet;
    while( 1 ){
        hightGet = hight;
        widthGet = width;
        switch( getCmd(hightGet, widthGet) ){
        case -1:
            cout<<"输入错误,请重新输入"<<endl;
            break;
        case -2:
            cout<<"坐标越界,请重新输入"<<endl;
            break;
        case 1: 
            setBob(map, bob, hightGet, widthGet);
            setMap(map);
            if( digBob(map, hightGet, widthGet) == hight*width-bob){
                endGame(map,0,1);
            }
            else{
                outpGame(map,bob);      
            }
            return;              //退出函数
        case 2:
        case 3:
            cout<<"游戏刚开始还是挖雷吧"<<endl;
            break;
        case 4:
            outpHelp();
            outpMethod();
            outpMap(map);
            break;
        case 5:
            //还没想好怎么重新开始
            break;
        case 6:
            exit(0);
            break;
        default :
            ;
        }
    }
    
}
void playGame(vector<vector<int>> & map , int hight, int width, int bob)
{
    int hightGet;         
    int widthGet;
    int pointAmount = hight * width;
    int digCount = 0;
    int flatCount = 0;
    bool flat = 1; 
    while( flat ){
        hightGet = hight;
        widthGet = width;
        switch( getCmd(hightGet, widthGet) ){
        case -1:
            cout<<"输入错误,请重新输入"<<endl;
            break;
        case -2:
            cout<<"坐标越界,请重新输入"<<endl;
            break;
        case 1: 
            //挖雷
            digCount = digBob(map, hightGet, widthGet);
            outpGame(map, bob-flatCount);
            if(digCount + bob == pointAmount){
                flat = 0;
                endGame(map,0,1);
            } 
            break;
        case 2:
            //标记/取消标记 雷区
            if(map[hightGet][widthGet] < 10){
                map[hightGet][widthGet] += 20;
                ++flatCount;
                outpGame(map, bob-flatCount);
            }
            else if(map[hightGet][widthGet] > 19 
                    && map[hightGet][widthGet] != 30)
            {
                map[hightGet][widthGet] -= 20;
                --flatCount;
                outpGame(map, bob-flatCount);
            }
            else{
                cout<<"这个点已经被挖过了"<<endl;
            }
            break;
        case 3:
            //翻开周围
            if(map[hightGet][widthGet]<11 
                    || map[hightGet][widthGet]>18) 
            {
                cout<<"不能对该点进行此操作"<<endl;
                break;
            }
            else{
                int ardigCount = 0;
                if(map[hightGet-1][widthGet-1] >20){
                    ++ardigCount;}
                if(map[hightGet-1][widthGet]   >20){
                    ++ardigCount;}
                if(map[hightGet-1][widthGet+1] >20){
                    ++ardigCount;}
                if(map[hightGet][widthGet-1]   >20){
                    ++ardigCount;}
                if(map[hightGet][widthGet+1]   >20){
                    ++ardigCount;}
                if(map[hightGet+1][widthGet-1] >20){
                    ++ardigCount;}
                if(map[hightGet+1][widthGet]   >20){
                    ++ardigCount;}
                if(map[hightGet+1][widthGet+1] >20){
                    ++ardigCount;}
                if(ardigCount == map[hightGet][widthGet]-10){
                        digBob(map, hightGet-1, widthGet-1);
                        digBob(map, hightGet-1, widthGet);
                        digBob(map, hightGet-1, widthGet+1);
                        digBob(map, hightGet, widthGet-1);
                        digBob(map, hightGet, widthGet+1);
                        digBob(map, hightGet+1, widthGet-1);
                        digBob(map, hightGet+1, widthGet);
                        digCount = digBob(map, hightGet+1, widthGet+1);
                        outpGame(map, bob-flatCount);
                }
                else{
                    cout<<"暂时不能对该点进行此操作"<<endl;
                }
                if(digCount + bob == pointAmount){
                    flat = 0;
                    endGame(map,0, 1);
                } 
            }
            break;
        case 4:
            outpHelp();
            outpGame(map, bob-flatCount);
            break;
        case 5:
            //还没想好怎么重新开始
            break;
        case 6:
            exit(0);
            break;
        default :
                ;
        }        //switch语句
    }            //里层while循环
}
void endGame(vector<vector<int>> & map,int bobLeft, int flat)
//结束游戏. 
//1表示成功 0表示失败:
{
    outpGame(map,bobLeft,1);
}
复制代码
复制代码
#include"function.h"
#include"windows.h"
#include<cstdio>
#include<ctime>
using namespace std;
//inline in function.h
void outpGame(vector<vector<int>> & map, int flat = 0);
void outpHelp( )
//输出操作提示
{
    system("cls");             //清屏
    
    printf("\
操作提示:  xxyyt\n\
其中 xx表示第xx行,yy表示第yy列,t表示进行的操作\n\
1:挖雷(不输入t值则默认此项)   2; 标记/取消标记 雷区   3; 翻开周围区域\n\
如 05061\n\
请按任意键继续\
    ");                        // "\"
    getchar( );
    system("cls");             //清屏
}
void outpMap(vector<vector<int>> & map, int flat)
//输出图形,以及坐标
//flat默认为0
{
    //顶排输出横坐标
    printf("   ");
    int i=1;
    for(int amount = map[0].end()-map[0].begin(); i <= amount; i+=2){
        printf("  %02d",i);
    }
    printf("\n");
    i=0;
    for(vector<vector<int> >::iterator iterL = map.begin();
                iterL != map.end(); ++iterL)
    {
        putchar(‘ ‘);
        //左排纵坐标
            if( !(i%2) ){
                printf("%02d",i);
            }
            else{
                printf("  ");
            }
        for(vector<int>::iterator iter = (*iterL).begin();
                    iter != (*iterL).end(); ++iter)
        {
            
#if 0
            cout<<setw(3)<<setfill(‘ ‘)<<*iter;
#else
            //显示雷区
            if(flat && *iter%10 == 9){
                printf("★" );
            }
            //未翻开
            else if(*iter < 10 ){
                printf("■");
            }
            //已翻开且周围无雷
            else if(*iter == 10){
                printf("·");
            }
            //已翻开且周围有雷
            else if(*iter < 19){
                printf(" %d",*iter-10);
            }
            //边界
            else if(*iter == 20){
                printf("·");
            }
            //标记为雷区
            else {
                printf("▲");
            }
            
            
#endif
        }
        
        //右排纵坐标
        if(i%2){
            printf("%02d",i);
        }
        ++i;
        printf("\n");
    }
    //底排输出横坐标
    printf(" ");
    i=0;
    for(int amount = map[0].end()-map[0].begin(); i < amount; i+=2){
        printf("  %02d",i);
    }
    printf("\n");
}
void outpState(int bobLeft)
//输出当前状态:使用时间,剩余雷数
{
    static unsigned long long timeBegin = time(0);
    printf("已用时间:  %d秒\t\t",time(0)-timeBegin);
    printf("剩下地雷:  %d个\n",bobLeft);
    printf("--------------------------------------------------------------------\n");
}
void outpMethod()
{
    printf("1:挖雷(默认)  2:标记/取消标记雷区  3:翻开周围   ?:查看帮助  e:退出\n");
    printf("--------------------------------------------------------------------\n");
}
复制代码
 
在这,碰到了一个比较郁闷的问题:如何清空输入流。如过当前的输入非法,那么当前流得不到释放,会影响下次的输入效果。且C++的流IO效率不是很高。
当时写这个程序的时候,还不会类,而且map的数据结构很有问题,效率低且占用内存大,等以后学习了更多的知识后,将进行修改。
http://www.cnblogs.com/h46incon/archive/2011/01/20/1939843.html
原文:http://www.cnblogs.com/findumars/p/6328392.html