C语言编写的扫雷程序(思路清晰、注释详细)

鉴于我上一个写的贪吃蛇程序把头文件和源文件分开写后有人可能会没看出来那是两个文件,本次把所有代码写在同一个文件里。下面是代码。本次程序没有去网上找一些好看的素材,所有的图案都是用EasyX图形库函数画的。你们若是有更好看的素材可以自己在这个程序上修改一下。我都在可以放图片的地方留下了注释。

==================================================================================================

#include
#include
#include
#include


#define ROW 9//行数
#define COL 9//列数
#define NUM 10//雷数
#define SIZE 50//图片大小

int count=0;//定义全局变量用来记录以点开格子的数量,此值若等于ROW*COL-NUM,则代表找到了所有的地雷,每次画0-8时计数加1

int map[ROW][COL];
//IMAGE img[12];//存图片,没有找到合适的素材暂时不用此方法。用EasyX画地雷和数字。

//初始化游戏
void init_game()
{
    int i=0;//用于循环
    int j=0;//用于循环
    int n=0,m=0;//用于遍历九宫格
    int r=0;//行
    int c=0;//列
    

    //初始化地图
    for(i=0;i     {
        for(j=0;j         {
            map[i][j]=0;
        }
    }

    //埋雷
    for(i=0;i     {
        //为避免重复,赢检验此位置是否埋过雷
        r=rand()%ROW;
        c=rand()%COL;
        if(map[r][c]==0)
        {
            map[r][c]=-1;
            i++;
        }
    }
    //确定其他元素的值,遍历所有不为-1的值
    for(i=0;i     {
        for(j=0;j         {
            if(map[i][j]!=-1)//不为-1的值,遍历九宫格
            {
                for(n=(i-1<0?0:i-1);n<=(i+1>ROW-1?ROW-1:i+1);n++)
                {
                    for(m=(j-1<0?0:j-1);m<=(j+1>COL-1?COL-1:j+1);m++)
                    {
                        if(map[n][m]==-1)
                        {
                            map[i][j]++;
                        }
                    }
                }
            }
        }
    }

    //加密以使得在游戏开始时不能发现那些是数字和雷,当鼠标点击时解密
    for(i=0;i     {
        for(j=0;j         {
            map[i][j]+=20;//加密后数字范围19--28
        }
    }
    //将素材加载下来
    //loadimage(&img[0],L"res/0.jpg",SIZE,SIZE);
    setbkcolor(WHITE);//设置窗口背景色
    cleardevice();//刷新窗口
}

//画数字
void draw_num(int r,int c)
{
    count++;//点开格子计数加1
    char a=map[r][c]+48;
    setfillcolor(RGB(0,0,255));
    settextcolor(RGB(255,0,0));
    settextstyle(30,0,L"华文琥珀");
    solidrectangle(r*SIZE+1,c*SIZE+1,(r+1)*SIZE-1,(c+1)*SIZE-1);
    outtextxy(r*SIZE+17,c*SIZE+10,a);
}

//画零
void draw_zero(int r,int c)
{
    count++;
    setfillcolor(RGB(0,0,255));
    settextstyle(30,0,L"华文琥珀");
    solidrectangle(r*SIZE+1,c*SIZE+1,(r+1)*SIZE-1,(c+1)*SIZE-1);
}
//画地雷
void draw_dilei(int r,int c)
{
    setfillcolor(RGB(255,0,0));
    solidcircle(r*SIZE+SIZE/2,c*SIZE+SIZE/2,SIZE/3);
    outtextxy((r+1)*SIZE,(c+1)*SIZE,L"踩到雷了,游戏失败!");

}
//画三角形
void draw_three(int r,int c)
{
    setfillcolor(RGB(255,0,0));
    POINT pts[] = { {r*SIZE+SIZE/2, c*SIZE+SIZE/4}, {r*SIZE+SIZE/4, c*SIZE+SIZE/4*3}, {r*SIZE+SIZE/4*3, c*SIZE+SIZE/4*3} };
    solidpolygon(pts, 3);
}
//删除三角形
void delete_three(int r,int c)
{
    POINT pts[] = { {r*SIZE+SIZE/2, c*SIZE+SIZE/4}, {r*SIZE+SIZE/4, c*SIZE+SIZE/4*3}, {r*SIZE+SIZE/4*3, c*SIZE+SIZE/4*3} };
    setfillcolor(RGB(0,255,0));
    solidpolygon(pts, 3);
    setfillcolor(RGB(255,0,0));
}

//画地图
void draw_map()
{
    int i=0;//用于循环
    int j=0;//用于循环
    
    for(i=0;i     {
        for(j=0;j         {    
            if(map[i][j]>=19 && map[i][j]<=28)//加密的数字
            {
                setfillcolor(RGB(0,255,0));
                solidrectangle(i*SIZE+1,j*SIZE+1,(i+1)*SIZE-1,(j+1)*SIZE-1);
            }
        }        
    }
}

//打开数字0周边的格子,因为0的周边可能还存在数字0,所以用递归函数
void open_zero(int i,int j)
{
    int n=0,m=0;//用于遍历九宫格

    map[i][j]-=20;
    draw_zero(i,j);

    for(n=(i-1<0?0:i-1);n<=(i+1>ROW-1?ROW-1:i+1);n++)
    {
        for(m=(j-1<0?0:j-1);m<=(j+1>COL-1?COL-1:j+1);m++)
        {
            if(map[n][m]>=21 && map[n][m]<=28)//加密的数字1-8
            {
                map[n][m]-=20;
                draw_num(n,m);
            }
            else if(map[n][m]==20)
            {
                open_zero(n,m);
            }

        }
    }

}
//玩游戏
int play_game()
{
    MOUSEMSG msg={0};
    msg=GetMouseMsg();//获得鼠标消息
    switch(msg.uMsg)
    {
    case WM_LBUTTONDOWN://左键
        {
            int r,c;//被选中的下标
            r=msg.x/SIZE;
            c=msg.y/SIZE;
            if(map[r][c]>=21 && map[r][c]<=28)//数字1-8对应的密码
            {
                map[r][c]-=20;//解密
                draw_num(r,c);
                return 0;
            }
            else if(map[r][c]==20)//数字0对应的密码
            {
                open_zero(r,c);//数字0比较特殊,因为如果这个数字是0代表太周边的所有小格都没有雷,可以通过函数把0附近的格子全打开
                return 0;
            }
            else if(map[r][c]==19)//地雷对应的密码
            {
                draw_dilei(r,c);
                return -1;
            }
        }
    case WM_RBUTTONDOWN://右键
        {
            int r,c;//被选中的下标
            r=msg.x/SIZE;
            c=msg.y/SIZE;
            if(map[r][c]>=19 && map[r][c]<=28)
            {
                map[r][c]+=20;//二次加密
                draw_three(r,c);
            }
            else if(map[r][c]>=39 && map[r][c]<=48)
            {
                map[r][c]-=20;//解二次加密
                delete_three(r,c);
            }

        }
    default:return 0;
    }
    return 0;
}

int main()
{
    srand((unsigned int)time(NULL));//随机数种子

    initgraph(ROW*SIZE,COL*SIZE);//初始化一个窗口

    init_game();//初始化游戏
    draw_map();//画地图

    while(1)//循环玩游戏
    {
        if(play_game()==-1)//如果踩到雷了结束
            break;
        if(count==ROW*COL-NUM)//排除了所有地雷结束
        {
            outtextxy(0,0,L"恭喜你排除了所有地雷!");
            break;
        }
    }

    system("pause");//程序暂停
    return 0;
}

==================================================================================

有不懂的可以在评论下方留言。

你可能感兴趣的:(C++,C语言)