/ Vijos / 讨论 / 游戏 /

C++扫雷

完美复原windows扫雷,包括颜色,除最后windows扫雷只显示雷的位置,我的还显示了数字的位置
代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<conio.h>
#include<windows.h>
#include<cstdlib>
#include<ctime>
using namespace std;

#define MAXN 35
#define MIDX 10
#define MIDY 40
#define CG 25
#define CK 80

int G,K,Lnum,Wnum;//G为地图高,K为地图,Lnum为地图中的雷数,Wnum为剩余的小旗数
int nx,ny;//现在光标所在的位置
bool QR=0,Lose=0,is_flag_true[MAXN][MAXN];//QR为确认模式是否打开,Lose为是否输,第三个是这个位置上的旗是否放对
char map[MAXN][MAXN],tmap[MAXN][MAXN];//第一个是只有雷和空地的地图,第二个是玩家能看到的地图
int map1[MAXN][MAXN],mapc[MAXN][MAXN];//map1为数字的地图,其中0代表空地,-1为雷,1-8为周围雷的个数
//mapc为当前格子的颜色
int col[10]={240,249,242,252,241,244,243,240,248};//col[i]表示windows扫雷中i的颜色,col[0]为空格的颜色
int d[10][4]={{0},{0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};//8个方向
bool ZB;//作弊是否打开

/*各种函数*/
void color(int);//颜色
void gto(int,int);//光标位置
void make();//制作随机地图
void print();//打印地图等
bool check(int,int);//判断坐标是否合法
bool is_win();//判断是否赢
bool is_lose();//是否输
void dfs(int,int);//用深搜来打开方块
void st(int,int);//试探,即windows扫雷中的左右键同时按
void flag(int,int);//小旗
void bj(int,int);//标记
void swt();//确认模式
void again();//重新开始
void zb();//作弊模式
void mainmain();//主函数
void print_real_map();//打印最终的地图
void begin();//各种操作

int main()
{
    mainmain();
}


void color(int a){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);}
void gto(int x,int y)
{
    COORD pos;pos.X=y;pos.Y=x;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

void make()
{
    for(int i=1;i<=G;i++)
        for(int j=1;j<=K;j++)
            map[i][j]='#';//初始化
    for(int i=1;i<=Lnum;i++)
    {
        int x=rand()%G+1,y=rand()%K+1;
        while(map[x][y]=='O')
            x=rand()%G+1,y=rand()%K+1;
        map[x][y]='O';
    }//随机放雷
    for(int i=1;i<=G;i++)
        for(int j=1;j<=K;j++)
        {
            if(map[i][j]=='O')map1[i][j]=-1,mapc[i][j]=240;//如果是雷
            else
            {
                for(int k=1;k<=8;k++)
                    if(map[i+d[k][0]][j+d[k][1]]=='O')
                        map1[i][j]++;//计算周围雷的个数
                mapc[i][j]=col[map1[i][j]];//根据格子上的数设置颜色
            }
        }
    for(int i=1;i<=G;i++)
        for(int j=1;j<=K;j++)
            if(mapc[i][j]==0)//空地
                mapc[i][j]=240;
}
void print()
{
    system("cls");
    gto(0,MIDY-4); color(233); printf("扫雷");
    color(240);
    gto(1,MIDY);
    for(int i=2;i<=G+1;i++)
    {
        gto(i,0);
        for(int j=1;j<=K;j++)
            printf("#"),tmap[i-1][j]='#';//初始化玩家所看到的地图
    }

    gto(2,0);
    nx=2,ny=0;
    color(15);
    printf("@");

    color(15);
    gto(2,2*K+5);printf("-----规则-----");
    gto(3,2*K+5);printf("wasd:选择位置");
    gto(4,2*K+5);printf("空格:打开");
    gto(5,2*K+5);printf("1键:试探周围8个方块,如果其中有雷则不会打开,无");
    gto(6,2*K+5);printf("     雷或旗帜标对了则会将周围无雷的位置打开,");
    gto(7,2*K+5);printf("     如果试探时周围有标错的旗帜,则会游戏失败");
    gto(8,2*K+5);printf("     必须额外确认一次,以便查看周围被试探的区域");
    gto(9,2*K+5);printf("2键:放置/取消小旗(F)");
    gto(10,2*K+5);printf("3键:放置/取消标记(?)");
    gto(11,2*K+5);printf("4键:打开/关闭确认模式,即每次操作需再按一次确认");
    gto(12,2*K+5);printf("5键:打开/关闭作弊模式,即显示原本地图");
    gto(13,2*K+5);printf("0键:重新开始");//打印规则

    gto(G+4,0);printf("-----操作提示-----\n");
    printf("请选择方块进行操作");

    gto(1,2*K+10);color(12);printf("剩余小旗数:%d",Wnum=Lnum);
}

bool check(int x,int y){return y>=0&&y<K&&x>=2&&x<G+2;}
//因为地图是从2行0列开始打的,而地图是从1行1列开始存的,所以gto(x,y)走到的是map[x-1][y+1]
bool is_win()
{
    int cnt=0;
    for(int i=1;i<=G;i++)
        for(int j=1;j<=K;j++)
            if(map[i][j]=='#'&&map1[i][j]==-1)
                cnt++;
    if(cnt==Lnum) return 1;
    //所有没被打开的方块都是雷=>胜利
    for(int i=1;i<=G;i++)
        for(int j=1;j<=K;j++)
            if((tmap[i][j]!='F'&&map1[i][j]==-1)||(tmap[i][j]=='F'&&map1[i][j]!=-1))
                return 0;
    return 1;
    //所有雷都标有旗
}
bool is_lose(){return Lose;}

void dfs(int x,int y)
{
    if(map1[x-1][y+1]>0)//只要边界全部是数字就return
    {
        gto(x,y),color(mapc[x-1][y+1]),printf("%d",map1[x-1][y+1]);
        tmap[x-1][y+1]=map1[x-1][y+1]+'0';
        return;
    }
    gto(x,y);color(255);
    tmap[x-1][y+1]=' ';
    printf(" ");//因为下面判断了雷,上面判断了数字,这里就一定是空地
    for(int i=1;i<=8;i++)
    {
        int xx=x+d[i][0]-1,yy=y+d[i][1]+1;//这里的xx和yy是在map中的,而不是gto中的
        if(check(xx+1,yy-1)&&tmap[xx][yy]=='#'&&map1[xx][yy]!=-1)//所以check和dfs的参数要变化
            dfs(xx+1,yy-1);
    }
}
void st(int x,int y)
{
    for(int i=1;i<=8;i++)
    {
        int xx=x+d[i][0],yy=y+d[i][1];
        if(check(xx,yy))
        {
            gto(xx,yy);
            if(tmap[xx-1][yy+1]!='#')
                color(mapc[xx-1][yy+1]-128);//减去128使周围的8个格子的背景颜色变为灰色
            else
                color(112);//这里特判一下'#',应该可以不用
            printf("%c",tmap[xx-1][yy+1]);
        }
    }
    gto(G+5,0),color(15),printf("请确认                                      ");
    //试探必须额外确认一次,规则上有说
    char c=getch();
    if(c=='1')
    {
        for(int i=1;i<=8;i++)
        {
            int xx=x+d[i][0],yy=y+d[i][1];
            if(check(xx,yy))
                if(tmap[xx-1][yy+1]=='F'&&map1[xx-1][yy+1]!=-1)//试探时有格子的小旗标错了=>失败
                {
                    Lose=1;
                    return;
                }
        }
        for(int i=1;i<=8;i++)
        {
            int xx=x+d[i][0],yy=y+d[i][1];
            if(check(xx,yy))
                if(map1[xx-1][yy+1]==-1&&tmap[xx-1][yy+1]!='F')//试探是有格子为雷=>取消打开
                    return;
        }
        for(int i=1;i<=8;i++)
        {
            int xx=x+d[i][0],yy=y+d[i][1];
            if(check(xx,yy)&&tmap[xx-1][yy+1]=='#')//打开周围8个格子
                dfs(xx,yy);
        }
    }
}
void flag(int x,int y)
{
    x-=1,y+=1;
    if(tmap[x][y]=='F')//原本为小旗=>取消小旗
    {
        tmap[x][y]='#';mapc[x][y]=240;
        gto(x+1,y-1),color(240),printf("#");
        Wnum++;//更新小旗数
    }
    else//否则就放置小旗
    {
        is_flag_true[x][y]=map1[x][y]==-1;//判断小旗是否放对
        tmap[x][y]='F';mapc[x][y]=253;
        gto(x+1,y-1),color(253),printf("F");
        Wnum--;//更新小旗数
    }
    gto(1,2*K+10);color(12);printf("剩余小旗数:       ");
    gto(1,2*K+22);printf("%d",Wnum);//更新小旗数
}
void bj(int x,int y)//和放小旗差不多,只是不用更新is_flag_true
{
    x-=1,y+=1;
    if(tmap[x][y]=='?')
    {
        gto(x+1,y-1),color(240),printf("#");
        tmap[x][y]='#';mapc[x][y]=240;
    }
    else
    {
        if(tmap[x][y]=='F')//如果原本这个位置上是小旗,而你把它变为了标记,就要更新小旗数
        {
            Wnum++;
            gto(1,2*K+10);color(12);printf("剩余小旗数:       ");
            gto(1,2*K+22);printf("%d",Wnum);
        }
        gto(x+1,y-1),color(240),printf("?");
        tmap[x][y]='?';mapc[x][y]=240;
    }
}
void swt(){QR=!QR;}
void zb()
{
    if(ZB)//如果本来作弊打开了就把作弊地图清除
    {
        for(int i=1;i<=G;i++)
        {
            gto(i+1,K+2);
            for(int j=1;j<=K;j++)
                color(15),printf(" ");
        }
        ZB=0;
    }
    else//否则打印作弊地图
    {
        for(int i=1;i<=G;i++)
        {
            gto(i+1,K+2);
            for(int j=1;j<=K;j++)
            {
                color(mapc[i][j]);
                if(map1[i][j]==-1) printf("O");
                else if(map1[i][j]>0) printf("%d",map1[i][j]);
                else printf(" ");
            }
        }
        ZB=1;
    }
}
void again()
{
    G=K=Lnum=nx=ny=Lose=ZB=0;
    QR=0;
    memset(is_flag_true,0,sizeof(is_flag_true));
    memset(map,0,sizeof(map));
    memset(tmap,0,sizeof(tmap));
    memset(map1,0,sizeof(map1));
    memset(mapc,0,sizeof(mapc));
    color(15);
    system("cls");//初始化
    mainmain();
}

void begin()//各种操作
{
    char c=getch(); 
    gto(G+5,0),color(15),printf("请选择方块进行操作");
    color(240);
    if(c=='w'&&check(nx-1,ny))
    {
        gto(nx,ny);
        if(tmap[nx-1][ny+1]!='#'||tmap[nx-1][ny+1]==' ')
            color(mapc[nx-1][ny+1]);
        printf("%c",tmap[nx-1][ny+1]);
        gto(nx-=1,ny);color(15);printf("@");
    }
    else if(c=='s'&&check(nx+1,ny))
    {
        gto(nx,ny);if(tmap[nx-1][ny+1]!='#'||tmap[nx-1][ny+1]==' ')color(mapc[nx-1][ny+1]);printf("%c",tmap[nx-1][ny+1]);
        gto(nx+=1,ny);color(15);printf("@");
    }
    else if(c=='a'&&check(nx,ny-1))
    {
        gto(nx,ny);if(tmap[nx-1][ny+1]!='#'||tmap[nx-1][ny+1]==' ')color(mapc[nx-1][ny+1]);printf("%c",tmap[nx-1][ny+1]);
        gto(nx,ny-=1);color(15);printf("@");
    }
    else if(c=='d'&&check(nx,ny+1))
    {
        gto(nx,ny);if(tmap[nx-1][ny+1]!='#'||tmap[nx-1][ny+1]==' ')color(mapc[nx-1][ny+1]);printf("%c",tmap[nx-1][ny+1]);
        gto(nx,ny+=1);color(15);printf("@");
    }
    //上下左右移动
    else
    {
        if(c==' '&&(!(tmap[nx-1][ny+1]<='9'&&tmap[nx-1][ny+1]>='0'))&&tmap[nx-1][ny+1]!='F')
        {
            mapc[nx-1][ny+1]=col[map1[nx-1][ny+1]];//如果本来放了标记,mapc[nx-1][ny+1]的颜色为黑色,在打开时里面的颜色却不一定是黑色
            if(QR)
            {
                gto(G+5,0),color(15),printf("请确认                                      ");
                if(getch()==' ')
                {
                    if(map1[nx-1][ny+1]==-1) {Lose=1;return;}
                    dfs(nx,ny);
                }
            }
            else
            {
                if(map1[nx-1][ny+1]==-1) {Lose=1;return;}
                dfs(nx,ny);
            }
        }
        else if(c=='1')
        {
            if(QR)
            {
                gto(G+5,0),color(15),printf("请确认                                      ");
                if(getch()=='1') st(nx,ny);
            }
            else st(nx,ny);
            for(int i=1;i<=8;i++)
            {
                int xx=nx+d[i][0],yy=ny+d[i][1];
                if(check(xx,yy))
                {
                    gto(xx,yy);
                    if(tmap[xx-1][yy+1]!='#') color(mapc[xx-1][yy+1]);
                    else color(240);
                    printf("%c",tmap[xx-1][yy+1]);
                }
            }
        }
        else if(c=='2'&&(tmap[nx-1][ny+1]>'9'||tmap[nx-1][ny+1]<'1'))
        {
            if(QR)
            {
                gto(G+5,0),color(15),printf("请确认                                      ");
                if(getch()=='2') flag(nx,ny);
            }
            else flag(nx,ny);
        }
        else if(c=='3'&&(tmap[nx-1][ny+1]>'9'||tmap[nx-1][ny+1]<'1'))
        {
            if(QR)
            {
                gto(G+5,0),color(15),printf("请确认                                      ");
                if(getch()=='3') bj(nx,ny);
            }
            else bj(nx,ny);
        }
        else if(c=='4')
        {
            if(QR)
            {
                gto(G+5,0),color(15),printf("请确认                                      ");
                if(getch()=='4') swt();
            }
            else swt();
        }
        else if(c=='5')
        {
            if(QR)
            {
                gto(G+5,0),color(15),printf("请确认                                      ");
                if(getch()=='5') zb();
            }
            else zb();
        }
        else if(c=='0')
        {
            if(QR)
            {
                gto(G+5,0),color(15),printf("请确认                                      ");
                if(getch()=='0') again();
            }
            else again();
        }
    }
}

void mainmain()
{
    system("mode con cols=120 lines=35");//设置窗口大小
    srand((unsigned)time(NULL));
    int mode;
    printf("1.初级\n2.中级\n3.高级\n4.自定义\n");
    scanf("%d",&mode);if(mode>4) mode=4;
    if(mode==1) G=9,K=9,Lnum=10;
    else if(mode==2) G=16,K=16,Lnum=40;
    else if(mode==3) G=16,K=30,Lnum=99;//三种等级的参数
    else
    {
        printf("请输入雷区高度:");scanf("%d",&G);
        printf("请输入雷区宽度:");scanf("%d",&K);
        printf("请输入雷个数(建议不超过总大小的三分之一):");scanf("%d",&Lnum);
        if(G>24) G=24;if(K>30) K=30;
        if(G<9) G=9;if(K<9) K=9;
        if(Lnum<10) Lnum=10;if(Lnum>G*K*9/10) Lnum=G*K*9/10;
        //控制参数的范围,最后一个if是雷的数量不超过地图大小的9/10
    }
    make();
    print();
    while(1)
    {
        begin();
        bool f1=is_win(),f2=is_lose();
        if(f1||f2)
        {
            gto(0,0);
            if(f1)
                color(202),gto(0,0),printf("你 赢 了!!是否重来?(y/n)");
            if(f2)
                color(137),gto(0,0),printf("你 输 了!!是否重来?(y/n)");//输赢
            print_real_map();
            char c=getch();
            if(c=='y'||c=='Y') again();
            else
            {
                color(15);
                system("cls");
                gto(MIDX,MIDY-5);
                printf("欢迎下次再来");
                return;
            }
        }
    }
}
void print_real_map()
{
    color(240);
    for(int i=1;i<=G;i++)
    {
        gto(i+1,0);
        for(int j=1;j<=K;j++)
        {
            if(tmap[i][j]=='F'&&is_flag_true[i][j]==0)//如果旗标错了显示红色的X
                color(252),printf("X");
            else if(map1[i][j]==-1)//雷为黑色O
                color(240),printf("O");
            else if(map1[i][j]==0)//空
                color(240),printf(" ");
            else//数字
                color(mapc[i][j]),printf("%d",map1[i][j]);
        }
    }
}

17 条评论

  • @ 2019-07-27 16:01:12

    膜拜大佬

  • @ 2019-07-11 19:16:06

    不一样的扫雷代码,了解一下

    #include<stdio.h>
    #include<windows.h>
    #include<stdlib.h>
    #include<time.h>
    #include<conio.h>
    #include<queue>
    #include<ctype.h>
    #define A 17 //地图的高
    #define B 17 //地图的宽
    #define C 30 //雷的总数
    using namespace std;

    //全局变量
    DWORD a,b;
    char map[A][B],news,spare;
    int BoomTotalNum,floatx,floaty,flag[A][B],flagnum,mode,slect[A][B],game;

    //颜色属性
    const WORD FORE_BLUE = FOREGROUND_BLUE; //蓝色文本属性
    const WORD FORE_GREEN = FOREGROUND_GREEN; //绿色文本属性
    const WORD FORE_RED = FOREGROUND_RED; //红色文本属性

    //开垦地图结构体
    struct node {
    int x;
    int y;
    };
    queue <node> dui;

    //打印位置
    void position(int x,int y) {
    COORD pos={x,y};
    HANDLE Out=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(Out,pos);
    }

    //隐藏光标
    void Hide() {
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);

    CONSOLE_CURSOR_INFO CursorInfo;

    GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息

    CursorInfo.bVisible = false; //隐藏控制台光标

    SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态

    }

    //初始化
    void Beginning() {
    while(!dui.empty()) {
    dui.pop();
    }
    game=1;
    //BoomTotalNum=C;
    floatx=A/2;
    floaty=B/2;
    flagnum=0;
    BoomTotalNum=C;
    mode=0;
    HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄

    CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体

    GetConsoleScreenBufferInfo(handle_out, &csbi); //获得窗口缓冲区信息
    int x,y;
    srand((unsigned)time(0));
    for(int i=0;i<A;i++) for(int j=0;j<B;j++) {
    map[i][j]=' ';
    flag[i][j]=0;
    slect[i][j]=0;
    }
    while(BoomTotalNum) {
    x=rand()%A;
    y=rand()%B;
    if(map[x][y]==' ') {
    map[x][y]='@';
    BoomTotalNum--;
    }
    }
    SetConsoleTextAttribute(handle_out, FORE_GREEN);

    for(int i=0;i<A;i++) {
    for(int j=0;j<B;j++) printf("??");
    printf("\n");
    }
    position(floaty*2,floatx);
    SetConsoleTextAttribute(handle_out, FORE_RED);

    printf(""); //光标位置
    position(44,9);
    printf("扫雷模式");
    position(44,5);
    printf("剩余雷数:%d ",C-flagnum);
    SetConsoleTextAttribute(handle_out, FORE_GREEN);

    position(5,22);
    printf("按“空格”切换模式");
    position(5,23);
    printf("按“Enter”确认");
    position(5,24);
    printf("按“方向键”选择方块");

    }

    //打印地图的一块儿
    void Lump(int xx,int yy) {
    switch(map[xx][yy]) {
    case '1' : printf("①");break; //周围雷的数量(下同)
    case '2' : printf("②");break;
    case '3' : printf("③");break;
    case '4' : printf("④");break;
    case '5' : printf("⑤");break;
    case '6' : printf("⑥");break;
    case '7' : printf("⑦");break;
    case '8' : printf("⑧");break;
    case ' ' :
    if(xx==floatx&&yy==floaty) {
    if(flag[xx][yy]==0) {
    if(mode%2==0) printf("");
    else printf("");
    }
    else printf("");
    }
    else {
    if(flag[xx][yy]==0) printf("??");
    else printf("");
    }
    break;
    case '@' :
    if(xx==floatx&&yy==floaty) {
    if(flag[xx][yy]==0) {
    if(mode%2==0) printf("");
    else printf("");
    }
    else printf("");
    }
    else {
    if(flag[xx][yy]==0) printf("??");
    else printf("");
    }
    break;
    case 'x' : if(floatx==xx&&floaty==yy) printf(""); else printf(" ");break; //已经挖开的空白
    }
    }

    //移动光标
    void Move() {
    HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄

    CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体

    GetConsoleScreenBufferInfo(handle_out, &csbi); //获得窗口缓冲区信息
    int xxx,yyy;
    xxx=floatx;
    yyy=floaty;
    switch(news) {
    case 72 : floatx--;break; //上
    case 80 : floatx++;break; //下
    case 75 : floaty--;break; //左
    case 77 : floaty++;break; //右
    }
    if(floatx==-1) floatx=A-1; floatx%=A; //两端穿模处理
    if(floaty==-1) floaty=B-1; floaty%=B;

    position(yyy*2,xxx);
    SetConsoleTextAttribute(handle_out, FORE_GREEN);
    Lump(xxx,yyy); //删除原位置

    if(map[floatx][floaty]=='x') {
    position(floaty*2,floatx);
    printf(" ");
    }

    position(floaty*2,floatx);
    SetConsoleTextAttribute(handle_out, FORE_BLUE);

    Lump(floatx,floaty); //更新新位置
    }

    //插旗和排雷模式切换
    void Mode() {
    HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄

    CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体

    GetConsoleScreenBufferInfo(handle_out, &csbi); //获得窗口缓冲区信息
    mode++;
    SetConsoleTextAttribute(handle_out, FORE_BLUE);
    position(floaty*2,floatx);
    if(mode%2==0) printf("");
    else printf("");

    position(44,9);
    if(mode%2==0) {
    SetConsoleTextAttribute(handle_out, FORE_BLUE);

    printf("扫雷模式");
    }
    else {
    SetConsoleTextAttribute(handle_out, FORE_RED);

    printf("插旗模式");
    }
    }

    //该点周围地雷数
    int Boomnum(int xx,int yy) {
    int num=0;
    if((xx-1>=0)&&(yy-1>=0)&&(map[xx-1][yy-1]=='@')) num++;
    if((xx-1>=0)&&(yy+0>=0)&&(map[xx-1][yy]=='@')) num++;
    if((xx-1>=0)&&(yy+1<B) &&(map[xx-1][yy+1]=='@')) num++;
    if((xx+0>=0)&&(yy-1>=0)&&(map[xx][yy-1]=='@')) num++;
    if((xx+0>=0)&&(yy+1<B) &&(map[xx][yy+1]=='@')) num++;
    if((xx+1<A)&&(yy-1>=0) &&(map[xx+1][yy-1]=='@')) num++;
    if((xx+1<A)&&(yy+0>=0) &&(map[xx+1][yy]=='@')) num++;
    if((xx+1<A)&&(yy+1<B) &&(map[xx+1][yy+1]=='@')) num++;
    return num;
    }

    //更新地图
    void Open() {
    node c;
    node d;
    while(!dui.empty()) {
    dui.pop();
    }
    c.x=floatx;
    c.y=floaty;
    dui.push(c);
    slect[c.x][c.y]=1;
    while(!dui.empty()) {
    c=dui.front();
    dui.pop();
    if(Boomnum(c.x,c.y)!=0) {
    map[c.x][c.y]=(Boomnum(c.x,c.y)+48);
    continue;
    }
    else {
    map[c.x][c.y]='x';

    if((c.x-1>=0)&&(c.y-1>=0)&&(map[c.x-1][c.y-1]==' ')&&(slect[c.x-1][c.y-1]==0)) {
    d.x=c.x-1;
    d.y=c.y-1;
    dui.push(d);
    slect[d.x][d.y]=1;
    }
    if((c.x-1>=0)&&(c.y-0>=0)&&(map[c.x-1][c.y]==' ')&&(slect[c.x-1][c.y]==0)) {
    d.x=c.x-1;
    d.y=c.y-0;
    dui.push(d);
    slect[d.x][d.y]=1;
    }
    if((c.x-1>=0)&&(c.y+1<B)&&(map[c.x-1][c.y+1]==' ')&&(slect[c.x-1][c.y+1]==0)) {
    d.x=c.x-1;
    d.y=c.y+1;
    dui.push(d);
    slect[d.x][d.y]=1;
    }
    if((c.x-0>=0)&&(c.y-1>=0)&&(map[c.x][c.y-1]==' ')&&(slect[c.x][c.y-1]==0)) {
    d.x=c.x-0;
    d.y=c.y-1;
    dui.push(d);
    slect[d.x][d.y]=1;
    }
    if((c.x-0>=0)&&(c.y+1<B)&&(map[c.x][c.y+1]==' ')&&(slect[c.x][c.y+1]==0)) {
    d.x=c.x-0;
    d.y=c.y+1;
    dui.push(d);
    slect[d.x][d.y]=1;
    }
    if((c.x+1<A)&&(c.y-1>=0)&&(map[c.x+1][c.y-1]==' ')&&(slect[c.x+1][c.y-1]==0)) {
    d.x=c.x+1;
    d.y=c.y-1;
    dui.push(d);
    slect[d.x][d.y]=1;
    }
    if((c.x+1<A)&&(c.y-0>=0)&&(map[c.x+1][c.y]==' ')&&(slect[c.x+1][c.y]==0)) {
    d.x=c.x+1;
    d.y=c.y-0;
    dui.push(d);
    slect[d.x][d.y]=1;
    }
    if((c.x+1<A)&&(c.y+1<B)&&(map[c.x+1][c.y+1]==' ')&&(slect[c.x+1][c.y+1]==0)) {
    d.x=c.x+1;
    d.y=c.y+1;
    dui.push(d);
    slect[d.x][d.y]=1;
    }
    }
    }
    }

    int main() {
    freopen("排名.txt","r",stdin);
    Relife: //重玩处
    HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄

    CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体

    GetConsoleScreenBufferInfo(handle_out, &csbi); //获得窗口缓冲区信息

    Hide(); //隐藏光标
    Beginning();//初始化地图
    a=GetTickCount();
    while(1) {
    if(kbhit()!=0) {
    spare=getch();

    //按其他
    if((spare!=(-32))&&(spare!=13)&&(spare!=' ')) continue;//跳过

    //按Enter
    if(spare==13) { //确认
    //排雷
    if(mode%2==0) {
    if(map[floatx][floaty]=='@'&&flag[floatx][floaty]==0) {
    break; //触雷
    game=0;
    }

    if(flag[floatx][floaty]==1) continue; //有旗跳过
    Open();
    position(0,0);
    SetConsoleTextAttribute(handle_out, FORE_GREEN);
    for(int i=0;i<A;i++) {
    for(int j=0;j<B;j++) Lump(i,j);
    printf("\n");
    }
    position(floaty*2,floatx);
    SetConsoleTextAttribute(handle_out, FORE_BLUE);
    Lump(floatx,floaty);
    }

    //插拔旗
    else {

    //不能插旗的地方
    if(map[floatx][floaty]=='x'||(map[floatx][floaty]>'0'&&map[floatx][floaty]<'9'))
    continue; //跳过

    //插旗
    if(flag[floatx][floaty]==0) {
    flagnum++;
    flag[floatx][floaty]=1;
    position(floaty*2,floatx);
    SetConsoleTextAttribute(handle_out, FORE_BLUE);
    Lump(floatx,floaty);
    }

    //拔旗
    else {
    flagnum--;
    flag[floatx][floaty]=0;
    position(floaty*2,floatx);
    SetConsoleTextAttribute(handle_out, FORE_BLUE);
    Lump(floatx,floaty);
    }
    }
    }

    //按空格
    if(spare==' ') Mode(); //切换模式

    //按方向键
    if(spare==-32) {
    news=getch();
    Move(); //移动光标
    }
    for(int i=0;i<A;i++) for(int j=0;j<B;j++) if(map[i][j]=='x'||(map[i][j]>'0'&&map[i][j]<'9')) game++;
    if(game==A*B-C+1) break;
    else game=1;
    SetConsoleTextAttribute(handle_out, FORE_RED);
    position(44,5);
    printf("剩余雷数:%d ",C-flagnum);
    }
    else Sleep(10);
    b=GetTickCount();
    SetConsoleTextAttribute(handle_out, FORE_RED);
    position(44,7);
    printf("用时:"); //用时
    if((b-a)/60000<10) printf("0");
    printf("%d:",(b-a)/60000);
    if(((b-a)/1000)%60<10) printf("0");
    printf("%d:",((b-a)/1000)%60);
    if(((b-a)/10)%100<10) printf("0");
    printf("%d",((b-a)/10)%100);
    }
    SetConsoleTextAttribute(handle_out, FORE_RED);
    position(5,5);
    if(game==1) printf("游戏结束!");
    else printf("恭喜通关!");
    position(5,8);
    printf("任意键重玩");
    scanf("%c%c",&spare,&spare);
    system("cls");
    position(0,0);
    goto Relife;
    }

  • @ 2019-01-05 15:53:47

    wow居然有人

  • @ 2018-11-29 21:40:24

    TQL!!!%%%

  • @ 2018-11-27 08:37:45

    菜鸟一枚

  • @ 2018-11-27 08:37:31

    有没有大佬教我

  • @ 2018-11-27 08:37:18

    怎么去运行啊

    • @ 2019-01-05 15:55:10

      如果你不能直接编译运行出来,我也没有办法

  • @ 2018-09-08 14:50:20

    %%%

  • @ 2018-09-05 20:01:37

    我有还简单的,(勿扰。。。)

  • @ 2018-09-03 20:41:42

    向大佬献上我的膝盖

  • @ 2017-08-13 18:07:46

    orz
    虽然我学的是Pascal

  • @ 2017-08-12 15:41:35

    666

  • @ 2017-07-27 12:32:28

    hhh

  • @ 2017-07-26 16:58:55

    233

  • @ 2017-07-26 13:50:48

    这eeeeeeeeeeeeeeeeeeeeeeeeeeee么厉害

  • @ 2017-07-25 11:18:50

  • @ 2017-07-21 14:26:07

    Good!

  • 1