随笔 - 3,  文章 - 0,  评论 - 1,  阅读 - 895

在b站学了两周的c语言,跟着老师的节奏写了这个扫雷小游戏,感觉还不错!

 

game.h

复制代码
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <windows.h>
/*
#include <stdlib.h>,使用ystem(),rand()函数需要导入
#include <stdio.h>,标准输入输出
#include <time.h>,使用time()函数需要导入
#include <windows.h>,使用Sleep()函数需要导入
*/

//定义游戏地图的长ROW、宽COL和地雷数MINE_NUM,实际设计时地图大小ROWS和COLS比原地图大一圈是为了方便实现
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define MINE_NUM 10

//声明方法
void menu();//打印菜单
void start();//开始游戏
void about();//关于游戏
void init_map(char map[ROWS][COLS],int row,int col,char ch);//初始化地图
void put_mine(char map[ROWS][COLS],int row,int col,int num);//埋雷
void print_map(char map[ROWS][COLS],int row,int col);//打印地图
void clear(char mine_map[ROWS][COLS],char clear_map[ROWS][COLS],int row,int col,int num);//扫雷
void number(char mine_map[ROWS][COLS],char clear_map[ROWS][COLS],int x,int y);//显示周围雷的数量
void print_win_map(char mine_map[ROWS][COLS],char clear_map[ROWS][COLS],int row,int col);//打印游戏结束时的地图
int is_win(char clear_map[ROWS][COLS],int row,int col,int num);//判断玩家是否获胜
复制代码

test.c

复制代码
#include "game.h"

int main()
{
    //随机种子
    srand((unsigned)time(NULL));
    int flag;
    do
    {
        system("cls");//清屏
        menu();//打印菜单
        scanf("%d",&flag);
        switch(flag)
        {
            //退出游戏
            case 0:
                break;
            //开始游戏
            case 1:
                start();
                break;
            //关于游戏
            case 2:
                about();
                break;
            default:
                printf("\n您的输入有有误,请重新输入!");
                Sleep(1000);
                break;            
        }
        
    }
    while(flag);
    
    printf("\n\n游戏已退出,欢迎下次再来!");
    Sleep(1000);
    system("puse");
    
    return 0;
}
复制代码

game.h

复制代码
#include "game.h"

//菜单
void menu()
{
    printf("******************************\n");
    printf("*******    扫   雷   *********\n");
    printf("******************************\n");
    printf("*******0.退出游戏    *********\n");
    printf("*******1.开始游戏    *********\n");
    printf("*******2.关于游戏    *********\n");
    printf("******************************\n");
    printf("\n\n\n请选择:");
}

//关于游戏
void about()
{
    system("cls");
    printf("******************************\n");
    printf("*******    关   于     *******\n");
    printf("******************************\n");
    printf("*******date:2022.4.18 *******\n");
    printf("*******author:null    *******\n");
    printf("*******content:null   *******\n");
    printf("******************************\n");
    printf("\n\n\n输入任意字符退出:");
    scanf("%s");
}

//开始游戏
void start()
{
    //地图大小
    int row = ROWS;
    int col = COLS;
    //雷的数量
    int num = MINE_NUM;
    //创建布雷的地图
    char mine_map [row][col];
    //创建扫雷的地图
    char clear_map[row][col];
    
    //初始化地图
    init_map(clear_map,row,col,'*');//*号表示没扫雷的区域
    init_map(mine_map,row,col,'0');//0表示安全,1表示有雷
    put_mine(mine_map,row,col,num);//布雷
    
    //打印地图
    //print_map(clear_map,row,col);
    //print_map(mine_map,row,col);
    
    //开始扫雷
    clear(mine_map,clear_map,row,col,num);
}

//初始化地图
void init_map(char map[ROWS][COLS],int row,int col,char ch)
{
    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < col; j++)
        {
            map[i][j] = ch;
        }        
    }
    
}

//布雷
void put_mine(char map[ROWS][COLS],int row,int col,int num)
{
    
    //生成雷的数量
    int mine = 0;
    
    do
    {
        //随机生产雷的坐标,因为地图比实际的大了一圈,所以坐标范围是(1-10)
        int x = rand()%(row-2) + 1;
        int y = rand()%(row-2) + 1;
        if(map[x][y] == '0')
        {
            map[x][y] = '1';
            mine++;
        }    
    }
    while(!(mine == num));
}

//打印地图
void print_map(char map[ROWS][COLS],int row,int col)
{
    printf("\n\n");
    //打印0-10行,其中第0行被行号占用,所以打印的是1-10行
    for(int i = 0; i < row-1; i++)
    {
        printf("  %d",i);//显示行号
        //打印1-10列
        for(int j = 1; j < col-1; j++)
        {
            if(i == 0)
                printf("   %d",j);//显示列号
            else
                printf("   %c",map[i][j]);
        }        
        printf("\n\n");
    }
    
}


//开始扫雷
void clear(char mine_map[ROWS][COLS],char clear_map[ROWS][COLS],int row,int col,int num)
{
    //用户输入的坐标
    int x,y;
    
    do{    
        //打印地图
        system("cls");
        printf("游戏开始:\n\n");
        //print_map(mine_map,row,col);
        print_map(clear_map,row,col);
        
        //用户输入雷的坐标
        printf("\n\n请输入要扫雷的坐标,格式(行号 列号):");
        scanf("%d %d",&x,&y);
        
        //判断坐标是否合法
        if(x <= row-2 && x > 0 && y <= col-2 && y > 0)
        {
            //判断是否踩雷
            if(mine_map[x][y] == '1')
            {
                system("cls");
                printf("游戏结束!\n\n");
                print_win_map(mine_map,clear_map,row,col);//打印扫完雷的地图
                printf("\n\n哎呀,踩到雷了,你输了!");
                break;;
            }
            else
            {
                //扫雷
                number(mine_map,clear_map,x,y);
                
                //判断是否赢
                if(is_win(clear_map,row,col,num))
                {
                    system("cls");
                    printf("游戏结束!\n\n");
                    print_win_map(mine_map,clear_map,row,col);//打印扫完雷的地图
                    printf("\n\n恭喜你,你赢了!");
                    break;
                }
            }
        }
        else
        {
            printf("\n您的输入有有误,请重新输入!");
            Sleep(1000);
        }
    }
    while(1);
    
    printf("\n\n输入任意字符退出:");
    scanf("%s");
}


//显示非雷位置周围一圈范围内的雷数量
void number(char mine_map[ROWS][COLS],char clear_map[ROWS][COLS],int x,int y)
{
    //判断是否是空位置
    if(clear_map[x][y] == '*' && x > 0 && y > 0 && x < ROWS-1 && y < COLS-1)
    {
        //周围的雷数
        int num = 0;
    
        //判断周围8个方向是否有雷
        if(mine_map[x-1][y-1] == '1')
            num++;
        if(mine_map[x-1][y] == '1')
            num++;
        if(mine_map[x-1][y+1] == '1')
            num++;
        if(mine_map[x][y-1] == '1')
            num++;
        if(mine_map[x][y+1] == '1')
            num++;
        if(mine_map[x+1][y-1] == '1')
            num++;
        if(mine_map[x+1][y] == '1')
            num++;
        if(mine_map[x+1][y+1] == '1')
            num++;
        
        //如果没有雷就继续扫周围,周围有雷就显示雷的数量
        if(num == 0)
        {
            clear_map[x][y] = ' ';
            
            //递归继续扫空白位置
            number(mine_map,clear_map,x-1,y-1);
            number(mine_map,clear_map,x-1,y);
            number(mine_map,clear_map,x-1,y+1);
            number(mine_map,clear_map,x,y-1);
            number(mine_map,clear_map,x,y+1);
            number(mine_map,clear_map,x+1,y-1);
            number(mine_map,clear_map,x+1,y);
            number(mine_map,clear_map,x+1,y+1);
        }
        else
        {
            clear_map[x][y] = num+48;//加48是为了把数字转成ASCII字符数字
        }
    }
    
}

//打印扫完雷的地图
void print_win_map(char mine_map[ROWS][COLS],char clear_map[ROWS][COLS],int row,int col)
{
    for(int i = 1; i < row - 1; i++)
    {
        for(int j = 1; j < col - 1; j++)
        {
            //显示雷#
            if(mine_map[i][j] == '1')
                clear_map[i][j] = '#';
            //显示周围雷的数量
            else
                number(mine_map,clear_map,i,j);
        }    
    }
    print_map(clear_map,row,col);//打印地图
}

//判断是否赢
int is_win(char clear_map[ROWS][COLS],int row,int col,int num)
{
    int lei = 0;
    for(int i = 1; i < row - 1; i++)
    {
        for(int j = 1; j < col - 1; j++)
        {
            if(clear_map[i][j] == '*')
                lei++;
        }    
    }
    //如果没扫过的区域数量不大于雷的数量,说明剩下的这些区域都是雷即获胜
    return lei > num ? 0 : 1;
}
复制代码

 

posted on   讨厌鬼  阅读(72)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示