基于C语言实现简单扫雷游戏

时间:2022-06-01 21:16:02

在每一个电脑里总有一个固定的小游戏-扫雷,那今天就让我们一起来实现下扫雷。

1.主函数的构建

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main()
{
 int input = 0;
 
 do
 {
  menu();
  printf("请选择是否开始游戏(1/0):>");
  scanf("%d", &input);
  switch (input)
  {
  case 1:
   game();
   break;
  case 0:
   printf("游戏退出!");
   break;
  default:
   printf("输入错误!请重新输入:");
   break;
  }
 } while (input);
 return 0;
}

创建主函数和菜单,并对此进行游戏选择判断。

2.雷盘的设计

?
1
2
3
4
char mine[ROWS][COLS];        //扫雷数组
char show[ROWS][COLS];         //展示数组
InitMine(mine, ROWS, COLS,'0');        //初始化的雷盘
InitShow(show, ROW, COL,'*');          //初始化展示的雷盘

这里我们创建两个二维数组,mine数组用来布置雷,show数组用来展示雷盘情况。

InitMine函数实现如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
void InitMine(char mine[ROWS][COLS], int row, int col) // 初始化雷盘
{
    int i = 0;
    int j = 0;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            mine[i][j] = '0';
        }
    }
}

接下来我们需要展示雷盘,可我们不会把将布置雷的雷盘展示出去,这时我们用到了show函数来帮助我们实现这一需求。

InitShow函数实现如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
void InitShow(char show[ROWS][COLS], int row, int col,char set) //初始化展示的雷盘
{
    int i = 0;
    int j = 0;
    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= col; j++)
        {
            show[i][j] = set;
        }
    }
}

这样我们就完成了第一步的设计。

3.布置雷

在完成雷盘之后,我们需要在我们的雷盘上布置雷,那这里我们引入了新的函数-SetMine,将雷布置在Mine数组中。

函数实现如下:

?
1
2
3
4
5
6
7
8
9
10
void SetMine(char mine[ROWS][COLS], int row, int col, int count) // 随机布雷
{
    while (count)//雷的个数
    {
        int x = rand() % row + 1;//(1-9)
        int y = rand() % col + 1;//(1-9)
        mine[x][y] = '1';
        count--;
    }
}

这里我们又又又遇见了rand函数,那我们则需要设置一个随机器-srand() ,别忘了它的头文件是<stdlib.h>,我们应该把srand()放在do whie中,不然雷会一直变动。

如图:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main()
{
 int input = 0;
 do
 {
  menu();
     srand((unsigned int)time(NULL)); //产生随机数
  printf("请选择是否开始游戏(1/0):>");
  scanf("%d", &input);
  switch (input)
  {
  case 1:
   game();
   break;
  case 0:
   printf("游戏退出!");
   break;
  default:
   printf("输入错误!请重新输入:");
   break;
  }
 } while (input);
 return 0;
}

4.打印雷盘

这里我们使用DisplayBoard函数来打印雷盘

函数实现如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void DisplayBoard(char arr[ROWS][COLS], int row, int col) // 打印展示雷盘
{
    int i = 0;
    int j = 0;
    printf(" ");
    for (i = 0; i <= row; i++)//打印列号
    {
        printf("%d ", i);
    }
    printf("\n");
    for (i = 1; i <= row; i++)
    {
        printf("%2d", i);//打印行号
        for (j = 1; j <= col; j++)
        {
            printf(" %c", arr[i][j]);
        }
        printf("\n");
    }
}

5.开始排雷

这里我们创建PlayGame函数来进行我们一系列的操作

函数实现如下:

?
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
void PlayGame(char mine[ROWS][COLS], char show[ROWS][COLS])
{
    int x = 0;
    int y = 0;
    int win = 0;//统计排雷的个数
    int count = 0;//统计周围雷的个数
    while (win < ROW * COL - COUNT)//判断条件
    {
        printf("请输入坐标:>");
        scanf("%d %d", &x, &y);
        if (show[x][y] == count + '0'|| show[x][y] == ' ')//避免重复排雷
        {
            printf("此处已经排过雷\n");
        }
        if (x >= 1 && x <= ROW && y >= 1 && y <= COL)//输入坐标是否合法
        {
            if (mine[x][y] == '1')
            {
                printf("很遗憾,你被炸死了\n");
                DisplayBoard(mine, ROW, COL);
                break;//退出循环
 
            }
            else
            {
                count = FindMineCount(mine, x, y);
                if (count == 0)//满足展开的条件
                {
                    show[x][y] = ' ';
                    expand(mine, x, y, show, &win);
                }
                else
                {
                    show[x][y] = count + '0';
                }
                win++;
                DisplayBoard(show, ROW, COL);
            }
        }
 
        else
        {
            printf("输入坐标不合法\n");
        }
 
    }
    if (win == ROW * COL - COUNT)//判断排雷结束
    {
        printf("排雷成功\n");
        DisplayBoard(mine, ROW, COL);//打印雷盘中雷的分布
    }
}

这里我们引入了FindMineCount函数expand函数

FindMineCount:

?
1
2
3
4
5
6
7
8
9
10
11
static int  FindMineCount(char mine[ROWS][COLS], int i, int j)   //统计雷的个数
{
    return mine[i - 1][j] +
        mine[i - 1][j - 1] +
        mine[i][j - 1] +
        mine[i + 1][j - 1] +
        mine[i + 1][j] +
        mine[i + 1][j + 1] +
        mine[i][j + 1] +
        mine[i - 1][j + 1] - 8 * '0';
}

使用这个FindMineCount函数用来查找左边周围雷的个数。

expand函数:

?
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
void expand(char mine[ROWS][COLS], int x, int y, char show[ROWS][COLS], int* p)//展开函数
{
    int i,j;
    for (i = -1; i <=1; i++) 
    {
      for (j = -1; j <=1; j++)
       {
         if (i != 0 || j != 0)//避免排到自己
         {
           if (x + i >= 1 && x + i <= ROW && y + j >= 1 && y + j <= COL) //判断x y坐标是否合法
            {
              if (show[x + i][y + j] == '*' && mine[x + i][y + j] != '1')//防止死递归
              {
                   int count = GetMineCount(mine, x + i, y + j);
                 if (count != 0)
                 {
                        show[x + i][y + j] = count + '0';
                        (*p)++;//排雷数加一
                 }
                 else
                 {
                        show[x + i][y + j] = ' ';
                        (*p)++;//排雷数加一
                        expand(mine, x + i, y + j, show, p);
                 }
              }
           }
         }
      }
    }
}

用此函数来判断是否符合条件进行展开。

对此所有步骤都已写完。

附上头文件、源文件。

game.h 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#define ROW  9  //雷盘操作范围
#define COL  9
#define ROWS ROW+2//雷盘实际大小
#define COLS COL+2
#define COUNT  10   //布置雷的个数
//设置游戏菜单
void menu();
 //初始化雷盘
void InitMine(char mine[ROWS][COLS], int row, int col);
//初始化展示的雷盘
void InitShow(char show[ROWS][COLS], int row, int col); 
// 随机布雷
void SetMine(char mine[ROWS][COLS], int x, int y, int count);
// 打印展示雷盘
void DisplayBoard(char arr[ROWS][COLS], int row, int col);
//玩游戏
void PlayGame(char mine[ROWS][COLS], char show[ROWS][COLS]);

game.c

?
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "game.h"
void menu()  //游戏菜单
{
    printf("****************************\n");
    printf("****     1.开始游戏     ****\n");
    printf("****     0.退出游戏     ****\n");
    printf("****************************\n");
}
void InitMine(char mine[ROWS][COLS], int row, int col,char set) // 初始化雷盘
{
    int i = 0;
    int j = 0;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            mine[i][j] = set;
        }
    }
}
 
void InitShow(char show[ROWS][COLS], int row, int col,char set) //初始化展示的雷盘
{
    int i = 0;
    int j = 0;
    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= col; j++)
        {
            show[i][j] = set;
        }
    }
}
 
void SetMine(char mine[ROWS][COLS], int row, int col, int count) // 随机布雷
{
    while (count)//雷的个数
    {
        int x = rand() % row + 1;//(1-9)
        int y = rand() % col + 1;//(1-9)
        mine[x][y] = '1';
        count--;
    }
}
 
void DisplayBoard(char arr[ROWS][COLS], int row, int col) // 打印展示雷盘
{
    int i = 0;
    int j = 0;
    printf(" ");
    for (i = 0; i <= row; i++)
    {
        printf("%d ", i);
    }
    printf("\n");
    for (i = 1; i <= row; i++)
    {
        printf("%2d", i);
        for (j = 1; j <= col; j++)
        {
            printf(" %c", arr[i][j]);
        }
        printf("\n");
    }
}
 
static int  GetMineCount(char mine[ROWS][COLS], int i, int j)   //统计雷的个数
{
    return mine[i - 1][j] +
        mine[i - 1][j - 1] +
        mine[i][j - 1] +
        mine[i + 1][j - 1] +
        mine[i + 1][j] +
        mine[i + 1][j + 1] +
        mine[i][j + 1] +
        mine[i - 1][j + 1] - 8 * '0';
}
 
void expand(char mine[ROWS][COLS], int x, int y, char show[ROWS][COLS], int* p)//展开函数
{
    int i,j;
    for (i = -1; i <=1; i++) 
    {
      for (j = -1; j <=1; j++)
       {
         if (i != 0 || j != 0)//避免排到自己
         {
           if (x + i >= 1 && x + i <= ROW && y + j >= 1 && y + j <= COL) //判断x y坐标是否合法
            {
              if (show[x + i][y + j] == '*' && mine[x + i][y + j] != '1')//防止死递归
              {
                   int count = GetMineCount(mine, x + i, y + j);
                 if (count != 0)
                 {
                        show[x + i][y + j] = count + '0';
                        (*p)++;//排雷数加一
                 }
                 else
                 {
                        show[x + i][y + j] = ' ';
                        (*p)++;//排雷数加一
                        expand(mine, x + i, y + j, show, p);
                 }
              }
           }
         }
      }
    }
}
 
// 主逻辑
void PlayGame(char mine[ROWS][COLS], char show[ROWS][COLS])
{
    int x = 0;
    int y = 0;
    int win = 0;//统计排雷的个数
    int count = 0;// 统计雷的个数
    while (win < ROW * COL - COUNT)//判断条件
    {
        printf("请输入坐标:>");
        scanf("%d %d", &x, &y);
        if (show[x][y] == count + '0'|| show[x][y] == ' ')//避免重复排雷
        {
            printf("已经排过雷\n");
        }
        if (x >= 1 && x <= ROW && y >= 1 && y <= COL)//输入坐标是否合法
        {
            if (mine[x][y] == '1')
            {
                printf("很遗憾,你被炸死了\n");
                DisplayBoard(mine, ROW, COL);
                break;
 
            }
            else
            {
                count = GetMineCount(mine, x, y);
                if (count == 0)
                {
                    show[x][y] = ' ';
                    expand(mine, x, y, show, &win);
                }
                else
                {
                    show[x][y] = count + '0';
                }
                win++;
                DisplayBoard(show, ROW, COL);
            }
        }
 
        else
        {
            printf("输入坐标不合法\n");
        }
    }
    if (win == ROW * COL - COUNT)//判断排雷结束
    {
        printf("排雷成功\n");
        DisplayBoard(mine, ROW, COL);
    }
}

text.c

?
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
#include "game.h"
void game()
{
 char mine[ROWS][COLS];             //扫雷数组
 char show[ROWS][COLS];             //展示数组
 InitMine(mine, ROWS, COLS,'0');    //初始化的雷盘
 InitShow(show, ROW, COL,'*');      //初始化展示的雷盘
 SetMine(mine, ROW, COL, COUNT);    //随机布雷
 DisplayBoard(show, ROW, COL);      //打印雷盘
 PlayGame(mine, show);              //玩游戏
}
int main()
{
 int input = 0;
 srand((unsigned int)time(NULL)); //产生随机数
 do
 {
  menu();
  printf("请选择是否开始游戏(1/0):>");
  scanf("%d", &input);
  switch (input)
  {
  case 1:
   game();
   break;
  case 0:
   printf("游戏退出!");
   break;
  default:
   printf("输入错误!请重新输入:");
   break;
  }
 } while (input);
 return 0;
}

谢谢观看!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/Rinki123456/article/details/121308834