C语言编程之扫雷小游戏空白展开算法优化

时间:2022-06-25 02:36:49

写代码前,扫雷需要什么

1,游戏需要初始选择菜单
2,需要布置两个棋盘,一个布置雷,一个展示给玩家看
3,打印棋盘
4,玩家要输入选择的坐标,并且可以多次输入游戏坐标
5,每次输入后打印棋盘,同时判断是否继续还是输赢。
6,玩家每次输入坐标,都进行一次递归展开。

进行主函数文件的代码

?
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
32
33
34
35
36
37
void option(int input)
{
    switch (input)//分支语句
    {
    case 1:
        game();//扫雷开始
        break;
    case 0:
        printf("Logon out the game\n");
        break;
    default:
        printf("Input error,please input again\n");
        break;
    }
}
void menu(void)
{
    printf("Welcome to game\n");
    printf("\n");
    printf("****************\n");
    printf("*----1.play----*\n");
    printf("*----0.exit----*\n");
    printf("****************\n");
}
int main(void)
{
    int input;
    srand((unsigned int)time(NULL));
    do
    {
        menu();//打印游戏菜单
        printf("please input option(1/0):>");
        scanf("%d", &input);
        option(input);//选项判断
    } while (input);
    
}

game文件以及函数步骤

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <time.h>
#define ROW 9
#define COL 9
#define _CRT_SECURE_NO_WARNINGS
#define ROWS ROW+2
#define COLS COL+2
#define LEVEL 10
#include <stdio.h>
#include <stdio.h>
void game(void);//扫雷游戏
void setboard(char board[ROWS][COLS], int rows, int cols,char ret);//初始布置棋盘内容
void showboard(char board[ROWS][COLS], int rows, int cols);//负责打印棋盘
//void player(char board[ROWS][COLS]);//玩家输入
void setmine(char mine[ROWS][COLS], int row, int col);//布置地雷
int cleanmine(char board[ROWS][COLS], char mine[ROWS][COLS], int row, int col);
void space(char board[ROWS][COLS], char mine[ROWS][COLS], int x,int y);//空白递归算法
int test(char mine[ROWS][COLS], int x, int y);//计算周围雷数

在主函数文件中使用game函数

?
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
32
33
34
void game()
{
    char board[ROWS][COLS];
    char mine[ROWS][COLS];
    setboard(mine, ROWS, COLS,'0');//创建初始棋盘
    setmine(mine, ROW, COL);//布雷要在一次游戏开始时就布好雷,只布一次雷
    setboard(board, ROWS, COLS, '*');//给玩家看的棋盘
    while (1)
    {
        int ret;
        showboard(mine, ROW, COL);//打印布雷图      
        showboard(board, ROW, COL);//打印玩家棋盘
        //player(board);
        ret=cleanmine(board,mine,ROW,COL);//扫雷
        //showboard(board, ROW, COL);
        int count = 0;//可以用一个函数进行封装
        for (int i = 1; i <= ROW; i++)
        {
            for (int j = 1; j <= COL; j++)
            {
                if (board[i][j] == '*')
                    count++;
            }
        }
        if (count ==  LEVEL)
        {
            printf("you win\n");
            break;
        }
        if (ret == 0)
            break;
        system("cls");     
    }  
}

布值棋盘(雷盘和玩家棋盘)

?
1
2
3
4
5
6
7
8
9
10
11
12
void setboard(char board[ROWS][COLS], int rows, int cols,char ret)
{
    int i;//主要靠ret决定是布雷还是布置玩家棋盘
    for (i = 0; i < rows; i++)
    {
        int j;
        for (j = 0; j < cols; j++)
        {
            board[i][j] = ret;
        }
    }
}

打印棋盘函数

每次将棋盘重新定义后就可以打印,但是我们设置的棋盘要比打印的大两行,为了保证之后计算雷数的循环成立。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void showboard(char board[ROWS][COLS], int rows, int cols)
{
    for (int a = 0; a <= cols; a++)
        printf("%d ",a);
    printf("\n");
    int i;
    int a = 1;
    for (i = 1; i <= rows; i++)
    {
        printf("%d ", a++);
        int j;
        for (j = 1; j <= cols; j++)
        {
            printf("%c|", board[i][j]);
        }
        printf("\n");
    }
}

玩家排雷

?
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
int cleanmine(char board[ROWS][COLS],char mine[ROWS][COLS],int row,int col)
{
    int x, y;
    while (1)
    {
        printf("please input the coordinate:>");
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            if (mine[x][y] == '0')
            {
                board[x][y] = test(mine, x, y) + '0';
                //空白递归算法
                space(board, mine, x, y);
                //showboard(board, ROW, COL);
                break;
            }
            else if (mine[x][y] == '1')
            {
                printf("You died\n");
                return 0;
                break;
            }
        }
        else
            printf("Coordinate is illegal,please input again\n");
    }
    printf("player\n");
    //showboard(board, ROW, COL);
    return 1;
}

计算雷数的函数

?
1
2
3
4
5
6
7
8
9
10
11
12
13
int test(char mine[ROWS][COLS], int x, int y)
{
    int count = 0;
    for (int i = x - 1; i <= x + 1; i++)
    {
        for (int j = y - 1; j <= y + 1; j++)
        {
            if (mine[i][j] == '1')
                count++;
        }
    }
    return count;//count就代表返回的雷数
}

空白递归算法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void space(char board[ROWS][COLS], char mine[ROWS][COLS], int x, int y)
{
    int i;
    if(test(mine, x, y)==0)
    {
        board[x][y] = ' ';
        for (i = x-1; i <=x+1; i++)
        {
            int j;
            for (j = y-1; j <=y+1; j++)
            {
                if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != '1'&&board[i][j]=='*')
                {
                    space(board, mine, i, j);
                }
            }
        }
    }
    else
        board[x][y] = '0' + test(mine, x, y);  
}

要使用test函数去测试某个元素周围8个元素是不是雷,如果不是,就进入函数进行递归,里面用来循环来表示各个方向的元素

C语言编程之扫雷小游戏空白展开算法优化

如果检测出来test不为0,就代表周围有雷,就else玩家棋盘定义为周围雷数,同时返回上一级函数。每一次递归都有两个for循环来递归检查各个方向上的元素。
就这些,如有问题,烦请大佬指点一二

以上就是C语言编程之扫雷小游戏空白展开算法优化的详细内容,更多关于C语言空白展开算法的资料请关注服务器之家其它相关文章!

原文链接:https://blog.csdn.net/weixin_52199109/article/details/113233421