【18.7.25】扫雷c语言小游戏,展开与防第一次炸死功能

递归看了N遍终于写出来了展开功能,心塞。
上效果图
打开代码,control+F5,走!

这里写图片描述

输入1开始游戏

这里写图片描述

密集恐惧症,心里一万只草泥马路过。。。
未打开前都是‘*’号,玩家根据行标和列标输入需要扫雷的位置

这里写图片描述

就快要赢了,当然这个难度可能比较低,但是可以自行设置难度,我自己默认的是20*20的表格,20个大雷子。

Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()//设计菜单
{
    printf("■■■■■■ 扫雷游戏 ■■■■■■\n");
    printf("■■■■■■■■■■■■■■■■■\n");
    printf("■■■■■■■■■■■■■■■■■\n");
    printf("■■■■■■1.开始游戏■■■■■■\n");
    printf("■■■■■■■■■■■■■■■■■\n");
    printf("■■■■■■0.退出游戏■■■■■■\n");
    printf("■■■■■■■■■■■■■■■■■\n");
}

void game()//游戏函数
{
    int i = 0;//循环变量
    int x = 0;//玩家输入行标
    int y = 0;//玩家输入列标
    char Hidemap[ROW][COL] = {0};//开发者棋盘;
    char Showmap[ROW][COL] = {0};//玩家棋盘;
    srand((unsigned int)time(NULL));//增加随机性;
    Initmap(Hidemap,Showmap,ROW,COL);//初始化棋盘;
    Devicemine(Hidemap,ROW,COL,Mine);//布置地雷;
    Printmap(Showmap,ROW,COL);//打印玩家棋盘;
    for(i=0;i<((ROW-2)*(COL-2)-Mine);i++)//循环做多循环表格里除了地雷数的所有地方,但也可提前跳出
    {
        printf("请输入需要打开的坐标:");
        scanf("%d%d",&x,&y);
        if(x>=1&&x<=ROW&&y>=1&&y<=COL)
        {
            if(i==0)
            {
                Savepleyer(Hidemap,ROW,COL,x,y);//增加玩家游戏体验,防止第一次就炸死
            }
            if(Open(Hidemap,Showmap,x,y))//打开坐标,如果不是雷继续,是雷就执行else。
            {
                ;
            }
            else
            {
                break;
            }
            if(Countshowmine(Showmap,ROW,COL)==Mine)//判定条件,全部雷被找出,玩家就赢了
            {
                printf("恭喜玩家获胜/n");
                break;
            }
            Printmap(Showmap,ROW,COL);
        }
        else
        {
            printf("对不起,您的输入有误,请重新输\n");
        }
    }
}
void test()
{
    int input = 0;
    do
    {
        menu();//打印菜单;
        printf("请输入指令:");
        scanf("%d",&input);
        switch(input)//玩家是否开始游戏
        {
        case 0://推出游戏
            printf("即将退出游戏\n");
            Sleep(2000);
            system("cls");
            break;
        case 1://开始游戏
            printf("游戏即将开始\n");
            Sleep(2000);
            system("cls");
            game();//进入游戏函数
            break;
        default :
            printf("输入错误,请您重新输入\n");
            break;
        }
    }
    while(input);
}

int main()//主函数入口进入
{
    test();
    return 0;
}



这里注意,创建数组是一个是开发者,显示的是雷的布局,为玩家棋盘服务的数组。
比如我们玩10*10的表格,但是要创建12*12的表格,原因是如果玩家探索边缘的地方,在统计的时候,统计周围八个地区,就会存在数组的越界,但是我们如果多创建2行2列,但是雷都布置到内10行10列中,就可以避免这个问题。打印同样也只打印内10行10列。

Game.c

游戏核心文件

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void Initmap(char Hidemap[ROW][COL],char Showmap[ROW][COL],int row,int col)//初始化两个数组
{
    memset(Hidemap,'0',row*col*sizeof(Hidemap[0][0]));//开发者棋盘初始化全0
    memset(Showmap,'*',row*col*sizeof(Showmap[0][0]));//玩家棋盘未扫区域为*
}
void Devicemine(char Hidemap[ROW][COL],int row,int col,int mine)
{
    int x = 0;
    int y = 0;
    while(mine)
    {
        x = rand() % (row-2);//产生0-row的余数
        y = rand() % (col-2);//产生0-col的余数
        if(Hidemap[x+1][y+1] == '0')//仅在1-(row-1)区域内布雷
        {
            Hidemap[x+1][y+1] = '1';//仅在1-(col-1)区域内布雷
            mine--;
        }
    }

}
int Countmine(char Hidemap[ROW][COL],int x,int y)//记雷数函数
{
    int count = 0;
    if(Hidemap[x-1][y-1] == '1')//统计周围八个地区的雷数
    {
        count++;
    }
    if(Hidemap[x-1][y] == '1')
    {
        count++;
    }
    if(Hidemap[x-1][y+1] == '1')
    {
        count++;
    }
    if(Hidemap[x][y-1] == '1')
    {
        count++;
    }
    if(Hidemap[x][y+1] == '1')
    {       
        count++;   
    }
    if(Hidemap[x+1][y-1] == '1')
    {
        count++;
    }
    if(Hidemap[x+1][y] == '1')
    {
        count++;
    }
    if(Hidemap[x+1][y+1] == '1')
    {
        count++;
    }
    return count;//返回周围雷的个数
}

int Open(char Hidemap[ROW][COL],char Showmap[ROW][COL],int x,int y)//打开需要排查地方
{
    if(Showmap[x][y]=='*')
    {
        if(Hidemap[x][y]=='0')
        {
            if(Countmine(Hidemap,x,y)!=0)//如果周围有雷,就正常显示周围雷的个数
            {
                Showmap[x][y] =Countmine(Hidemap,x,y)+'0';
            }
            else
            {
                Unfoldmap(Hidemap,Showmap,x,y);//如果周围没雷就得展开这个区域
            }
        }
        else
        {
            printf("你踩到雷了!\n");
            return 0;
        }
    }
    return 1;
}





void Printmap(char arr[ROW][COL],int row,int col)
{

        int i = 0;
        int j = 0;
        printf(" 0 ");
        for(i=1;i<=(col-2);i++)//打印列标
        {
            printf("%   3d ",i);
        }
        printf("\n");
        printf("  ┏");//打印装饰表格
        for(j=0;j<col-3;j++)
        {
            printf("━┳");
        }
        printf("━┓\n");
        for(i=1;i<=(row-2);i++)
        {
            printf("%2d┃",i);//打印行标
            for(j=1;j<=(col-2);j++)
            {
                printf(" %c",arr[i][j]);
                printf("┃");
            }
            printf("\n");
            if(i<row-2)
            {
                printf("  ┣");
                for(j=0;j<col-3;j++)
                {
                    printf("━╋");
                }
                printf("━┫\n");
            }
        }
        printf("  ┗");
        for(j=0;j<col-3;j++)
        {
            printf("━┻");
        }
        printf("━┛\n");
}
void Savepleyer(char Hidemap[ROW][COL],int row,int col,int x,int y)
{
    int ret = 1;
    if(Hidemap[x][y]=='1')
    {
        Hidemap[x][y] = '0';
        while(ret)
        {
            x = rand() % row;
            y = rand() % col;
            if(Hidemap[x+1][y+1] == '0')
            {
                Hidemap[x+1][y+1] = '1';
                ret--;
            }
        }
    }
}
void Unfoldmap(char Hidemap[ROW][COL],char Showmap[ROW][COL],int x,int y) 
{
    Showmap[x][y] = ' ';//周围没雷,直接显示空格,并且自动打开周围的几个区域
    Open(Hidemap,Showmap,(x+1),(y+1));
    Open(Hidemap,Showmap,(x+1),(y-1));
    Open(Hidemap,Showmap,(x+1),(y));
    Open(Hidemap,Showmap,(x),(y+1));
    Open(Hidemap,Showmap,(x),(y-1));
    Open(Hidemap,Showmap,(x-1),(y+1));
    Open(Hidemap,Showmap,(x-1),(y-1));
    Open(Hidemap,Showmap,(x-1),(y));
}
int Countshowmine(char Showmap[ROW][COL],int row,int col)//判断剩余未知区域的个数,个数为雷数时玩家赢
{
    int count = 0;
    int i = 0;
    int j = 0;
    for(i=1;i<=(row-2);i++)
    {
        for(j=1;j<=(col-2);j++)
        {
            if (Showmap[i][j] == '*')
            {
                count++;
            }
        }

    }
    return count;
}
注意这里的传参问题。

Game.h头文件

#ifndef __GAME_H__
#define __GAME_H__


#define ROW 22
#define COL 22
#define Mine 20

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>


void Initmap(char Hidemap[ROW][COL], char Showmap[ROW][COL], int row, int col);
void Devicemine(char Hidemap[ROW][COL], int row, int col, int mine);
int Countmine(char Hidemap[ROW][COL], int x, int y);
int Open(char Hidemap[ROW][COL], char Showmap[ROW][COL], int x, int y);
void Printmap(char arr[ROW][COL], int row, int col);
void Savepleyer(char Hidemap[ROW][COL], int row, int col, int x, int y);
void Unfoldmap(char Hidemap[ROW][COL], char Showmap[ROW][COL], int x, int y);
int Countshowmine(char Showmap[ROW][COL], int row, int col);

#endif //__GAME_H__
整个程序就完了,扫雷是一个不错的练手题,难度有,但是对于我们这种初学者来说,完全可以解决。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值