C语言版本扫雷游戏

C语言版本扫雷游戏,第1张

复杂的逻辑,都是可以通过简单的尝试轻松实现的!

扫雷游戏的想法:

(1)我们想要一个9*9的数组,其中存放了每个格子是否有雷(1代表有雷,0代表没有雷)

(2)为了防止冲突,我们还想要一个9*9的数组,其中放置提示雷数量的相关信息

(3)不知道周围雷的数目时,我们标记格子为*,保留神秘感

(4)为了使得格子中既能放置数字也可以放置字符,我们选择两个char类型的数组

(5)将mine数组中均标记为1,将show数组中均标记为*

(6)show每个格子的计算规则是统计在mine中的对应格子周围的8个格子中0的个数(注意判断是否越界!!)

(7)为了放置越界问题的产生,不妨将mine数组自动改成11*11大一号的数组

(8)为了两个数组之间抓换的麻烦,将show数组也改为11*11的数组

(9)以do while结构放置函数主体,一旦input为0则停止游戏,一旦input为1则开始扫雷游戏,其他输入提示输入错误

(10)需要menu函数提示你的输入

(11)在game函数中实现具体的扫雷游戏的过程

(12)分别创建mine和show两个数组分别表示布置好的雷的数组和排查出的雷的信息

(13)InitBoard函数用来创建初始化的数组,同时为了满足既能初始化mine也能初始化show数组,可以传递一个set参数来区分初始化的数组对象,传递的参数还有ROWS和COLS

(14)把棋盘打印出来看一下初始化的结果,用DisplayBoard函数,但是注意传递参数是ROW和COL。虽然传递的参数是ROW,但是由于原数组的ROWS行数,所以函数体中还是ROWS

(15)打印时为了清楚,标记上具体的行号和列号

(16)SetMine函数用以在show数组中随机放入10个雷,为了使每一次放置的雷的数目不尽相同,用当前时间作为随机数的产生根写在主函数中

(17)get_mine_count函数用以提示如果你寻找的位置不是雷,则提供给你在该位置附近有几个雷的有用信息,方式是通过计算8个格子中雷的数目并加和。注意其中的0和1存储的是字符,如果要进行加减法的运算要记得转换成数字0和1

(18)如果碰到雷,就被炸死了,并展示show数组中全部的10个雷的位置

(19)胜利条件是除了标记有雷的10个方格之外其他方格均被访问过一遍

(20)避免被排查过的坐标再次被排查

#include 
#include 
#include 

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 10

void menu()
{
    printf("***************************\n");
    printf("******      1. play      **\n");
    printf("******      0. exit      **\n");
    printf("***************************\n");
    printf("***************************\n");
}

void InitBoard(char board[ROWS][COLS], int rows,int cols, char set)
{
    int i = 0;
    int j = 0;
    for(i = 0; i < rows; i++)
    {
        for(j = 0; j < cols; j++)
        {
            board[i][j] = set;
        }
    }
}

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
    int i = 0;
    int j = 0;
    printf("———扫雷游戏———\n");
    for(j = 0; j <= col; j++)
    {
        printf("%d ",j);
    }
    printf("\n");
    for(i = 1; i <= row; i++)
    {
        printf("%d ",i);
        for(j = 1; j <= col; j++)
        {
            printf("%c ",board[i][j]);
        }
        printf("\n");
    }
    printf("———扫雷游戏———\n");
}

void SetMine(char board[ROWS][COLS], int row, int col)
{
    int count = EASY_COUNT;
    while(count)
    {
        int x = rand() % row + 1;
        int y = rand() % col + 1;

        if(board[x][y] == '0')
        {
            board[x][y] = '1';
            count--;
        }
    }

}

int get_mine_count(char board[ROWS][COLS], int x, int y)
{
    return (board[x-1][y-1]+
            board[x-1][y]+
            board[x-1][y+1]+
            board[x][y-1]+
            board[x][y+1]+
            board[x+1][y-1]+
            board[x+1][y]+
            board[x+1][y+1] - 8 * '0');
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x = 0;
    int y = 0;
    int win = 0;//找到非雷的个数
    while(win < col * row - EASY_COUNT)
    {
        while(1)
        {
            printf("请输入要排查的坐标:>");
            scanf("%d%d", &x, &y);
            if(x >= 1 && x <= row && y >= 1 && y <= row)
            {
                if(show[x][y] != '*')
                    printf("该坐标被排查过了,不能重复排查\n");
                else
                {
                    //如果是雷
                    if(mine[x][y] == '1')
                    {
                        printf("很遗憾,你被炸死了\n");
                        DisplayBoard(mine,ROW,COL);
                        break;
                    }
                    //如果不是雷
                    else
                    {
                        win++;
                        //统计mine数组中x,y坐标周围有几个雷
                        int count = get_mine_count(mine,x,y);
                        show[x][y] = count + '0';//转换成数字字符
                        DisplayBoard(show,ROW,COL);
                    }
                }
            }
            else
            {
                printf("输入的坐标非法,请重新输入:>");
            }

        }
    }
    if(win < col * row - EASY_COUNT)
    {
        printf("恭喜你,排雷成功\n");
        DisplayBoard(mine,ROW,COL);
    }

}

void game()
{
    char mine[ROWS][COLS] = {0};//存放布置好的雷的信息
    char show[ROWS][COLS] = {0};//存放排查出的雷的信息
    //初始化数组的内容为指定的内容
    //mine数组在没有布置雷时,都是0
    InitBoard(mine,ROWS,COLS,'0');
    //show数组在没有排查雷时,都是'*'
    InitBoard(show,ROWS,COLS,'*');

//    DisplayBoard(mine,ROW,COL);
    //设置雷
    SetMine(mine,ROW,COL);
//    DisplayBoard(mine,ROW,COL);
    DisplayBoard(show,ROW,COL);

    FindMine(mine,show,ROW,COL);
}

int main()
{
    //设置随机数的生成起点
    srand((unsigned int)time(NULL));
    int input = 0;
    do
    {
        menu();
        printf("请选择:>");
        scanf("%d",&input);
        switch(input)
        {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戏\n");
            break;
        default:
            printf("选择错误\n");
            break;
        }
    }
    while (input);
    return 0;
}

但是该代码只完成了基础功能,欢迎大家在评论区讲这个基础代码进行改进:

其中可改进的功能包括但不限于:

(1)可标记功能——已知某个位置有雷,可以标记一下以方便记忆

(2)展开一片功能:该坐标不是雷,该坐标周围没有雷且该坐标没有被排查过(可以用递归算法分别检查其周围的8个坐标是否满足这三个条件)——这些坐标不用显示数字,可以直接放置空格

不仅可以用C语言程序进行编写,也推荐大家尝试C++和Python等语言尝试实现一些较大的程序的功能,我们一起努力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/914760.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存