精英盒子 -> 程序设计 -> [C++源码]原创控制台扫雷 [打印本页]

jybox 2011-08-03 19:20

[C++源码]原创控制台扫雷

N久之前写的了,发上来
该程序不具有版权,大家随意。


注意,编译该程序需要使用例如VS2010的支持中文标识符的编译器,如果你的编译器不支持中文,那么请尝试把中文的变量和函数名改为英文
该程序仅仅一个文件,直接编译即可
本人没有义务提供技术支持
  1. /*
    扫雷.cpp
    (整个程序仅这一个文件,没有头文件,直接编译即可)

    By精英王子,于2011.1.2
    版本 B1.00

    邮箱:m@jybox.net
    网站:http://jybox.net
    */
    #include <iostream>
    #include <stdlib.h>
    #include <time.h>
    using namespace std;
    int mainmap[10][10];    //主地图,雷为10,非雷为数字0-8
    int usermap[10][10];    //用户进度地图,0为未挖,1为已挖,2为标记
    void 初始化地图()
    {
        for(int i=0;i<=9;i++)
        {
            for(int l=0;l<=9;l++)
                mainmap[i][l]=0;
        }
        for(int i=0;i<=9;i++)
        {
            for(int l=0;l<=9;l++)
                usermap[i][l]=0;
        }
    }
    int 随机数()                  //生成0-9的随机数
    {
        return rand() % 10;
    }
    void 生成地图()
    {
        //随机生成20个雷
        int tx=0,ty=0;
        srand(time(NULL));
        for(int k=1;k<=20;k++)
        {
            tx=随机数();
            ty=随机数();
            while(mainmap[tx][ty]==10)
            {
                tx=随机数();
                ty=随机数();
            }
            mainmap[tx][ty]=10;
        }
        //设置其他格子的数字
        int s=0;        //计数器
        for(int i=0;i<=9;i++)
        {
            for(int l=0;l<=9;l++)
            {
                if(!(mainmap[i][l]==10))      //如果这个格子不是雷
                {
                    s=0;                        //计数器归零
                    //向8个方向寻找雷(这个地方的代码有待精简)
                    if(l-1>=0)
                    {
                        if(mainmap[i][l-1]==10)
                            s++;
                    }
                    if(l+1<=10)
                    {
                        if(mainmap[i][l+1]==10)
                            s++;
                    }
                    if(i-1>=0)
                    {
                        if(mainmap[i-1][l]==10)
                            s++;
                    }
                    if(i+1<=10)
                    {
                        if(mainmap[i+1][l]==10)
                            s++;
                    }
                    if(l-1>=0 && i-1>=0)
                    {
                        if(mainmap[i-1][l-1]==10)
                            s++;
                    }
                    if(l-1>=0 && i+1<=10)
                    {
                        if(mainmap[i+1][l-1]==10)
                            s++;
                    }
                    if(l+1<=10 && i-1>=0)
                    {
                        if(mainmap[i-1][l+1]==10)
                            s++;
                    }
                    if(l+1<=10 && i+1<=10)
                    {
                        if(mainmap[i+1][l+1]==10)
                            s++;
                    }
                    mainmap[i][l]=s;
                }
            }
        }
    }
    void 输出地图()
    {
        cout<<"------------地图-------------"<<endl;
        for(int i=0;i<=9;i++)
        {
            for(int l=0;l<=9;l++)
            {
                if(usermap[i][l]==2)
                    cout<<"??";
                if(usermap[i][l]==1)
                    cout<<"0"<<mainmap[i][l];
                if(!usermap[i][l])
                    cout<<"**";
                cout<<" ";
            }
            cout<<endl;
        }
        cout<<"-----------------------------"<<endl;
    }
    int 获胜判定()
    {
        for(int i=0;i<=9;i++)
        {
            for(int l=0;l<=9;l++)
            {
                if(!((usermap[i][l]==2 && mainmap[i][l]==10)||usermap[i][l]==1))
                {
                    return 0;
                }
            }
        }
        return 1;
    }
    void maingame()
    {
        int ux=-1,uy=-1,uz=-1;
        初始化地图();
        生成地图();
        while(1)
        {
            system("cls");
            cout<<"默认为10*10方阵,20个雷"<<endl;
            cout<<"图例:  *:未挖开的区域,?:被标记的雷,(数字):被挖开的区域"<<endl;
            cout<<"扫雷--By精英王子"<<endl;
            输出地图();
            cout<<"请操作,共输入3个数字,第一个是要操作的区域的行(竖着的),第二个是列(横着的),第三个是操作类型(0为标记/取消标记,1为挖开),每输入一个数字按下回车"<<endl;
            cin>>uy>>ux>>uz;
            if(uz)
            {
                //进行挖开操作
                if(mainmap[ux-1][uy-1]==10)
                {
                    cout<<"中雷了!(请关闭程序吧)"<<endl;
                    int a;
                    cin>>a;
                    exit(0);
                }
                else
                {
                    usermap[ux-1][uy-1]=1;
                }
            }
            else
            {
                //进行标记操作
                if(usermap[ux-1][uy-1]==2)
                {
                    usermap[ux-1][uy-1]=0;
                }
                else
                {
                    if(!(usermap[ux-1][uy-1]==1))
                        usermap[ux-1][uy-1]=2;
                }
            }
            if(获胜判定())
            {
                cout<<"获胜了!(请关闭程序吧)"<<endl;
                int a;
                cin>>a;
                exit(0);
            }
        }
    }
    int main()
    {
        maingame();
        return 0;
    }



abreto 2011-08-03 19:22
防止码农,,其实你可以用我的中文编程库

jybox 2011-08-03 19:30
无聊,我们的目标是中文操作系统

zzh8829 2012-09-07 11:30
告诉你怎么精简找雷那部分的代码
本人做着类题做多了 经验一大把
首先定义方向数组
int d[16]={ 0,1, 1,1, 1,0, 1,-1, 0,-1, -1,-1, -1,0, -1,1};
代表了8个方向的 delta坐标
假设当前坐标为x,y; 雷数为s; mine数组里-1表示雷
for(int i=0;i!=8;i++)
if( mine[x+d[i*2]][y+d[i*2+1]] == -1)
s++;
直接3行秒杀你好几十行有木有!!!
如果怕出界 可以加一个int tmpx =x+ d[i*2] ,tmpy = y+d[i*2+1];if (tmpx .....tmpy.....) 这样最多5行

jybox 2012-09-07 16:59
zzh8829:告诉你怎么精简找雷那部分的代码
本人做着类题做多了 经验一大把
首先定义方向数组
int d[16]={ 0,1, 1,1, 1,0, 1,-1, 0,-1, -1,-1, -1,0, -1,1};
代表了8个方向的 delta坐标
....... (2012-09-07 11:30) 

确实,这段代码可能是~~~~2011年三月之前写的...

好久了

jybox 2012-09-07 17:00
zzh8829:告诉你怎么精简找雷那部分的代码
本人做着类题做多了 经验一大把
首先定义方向数组
int d[16]={ 0,1, 1,1, 1,0, 1,-1, 0,-1, -1,-1, -1,0, -1,1};
代表了8个方向的 delta坐标
....... (2012-09-07 11:30) 

确实,这段代码可能是~~~~2011年三月之前写的...

好久了

jybox 2012-09-07 17:00
好吧,开头有注释,是2011.1

1022 2012-09-08 00:40
jybox:[表情] 无聊,我们的目标是中文操作系统 (2011-08-03 19:30) 

中文操作系统? linux为内核的?已经开始做了还是?

jybox 2012-09-08 01:50
1022:中文操作系统? linux为内核的?已经开始做了还是? (2012-09-08 00:40) 

纯YY......

@OUTMAN正在学习制作操作系统.....

outman 2012-09-08 14:10
zzh8829:告诉你怎么精简找雷那部分的代码
本人做着类题做多了 经验一大把
首先定义方向数组
int d[16]={ 0,1, 1,1, 1,0, 1,-1, 0,-1, -1,-1, -1,0, -1,1};
代表了8个方向的 delta坐标
....... (2012-09-07 11:30) 

也许比较高效 但实际可读性很差 根据《linux/unix设计哲学》所说,牺牲可读性提高一点点的效率在计算机不断更新换代的今天是无意义的

outman 2012-09-08 14:11
1022:中文操作系统? linux为内核的?已经开始做了还是? (2012-09-08 00:40) 

linux是我学习的对象 不用其内核

outman 2012-09-08 14:11
jybox:纯YY......
@OUTMAN正在学习制作操作系统..... (2012-09-08 01:50) 

另外JY你这样是@不到我的

jybox 2012-09-08 22:41
outman:也许比较高效 但实际可读性很差 根据《linux/unix设计哲学》所说,牺牲可读性提高一点点的效率在计算机不断更新换代的今天是无意义的 [表情] (2012-09-08 14:10) 

我感觉可读性不差啊.......

用一个数组来写,能马上就看出要循环处理八个方向......

我原帖上的才叫可读性差呢...

1022 2012-09-11 22:47
outman:linux是我学习的对象 不用其内核 (2012-09-08 14:11) 

我只是问问而已




Powered by phpwind v8.7 Code ©2003-2011 phpwind
Time 0.059236 second(s),query:5 Gzip enabled