C语言实现排雷游戏(多文件)

时间:2021-12-01 02:38:09

本文实例为大家分享了C语言实现排雷游戏的具体代码,供大家参考,具体内容如下

游戏功能:

①打印雷盘
②随机布雷
③第一踩雷不死(重新布雷)
④扩展式扫雷
⑤计算周围雷的个数

代码关键点:

①玩游戏的雷盘比实际定义的数组小。
②memset初始化数组(以字节为单位初始化)。
③rand函数给雷盘随机位置布雷(用sand设置随机数种子)。
④第一步就踩到雷要这个雷移开,给玩家一次机会。
⑤踩到雷后根据情况决定是否进行扩展式排雷。
⑥返回输入排雷位置周围雷的个数,根据雷的数量决定是否进行扩展式排雷。
⑦如果输入的坐标周围有雷,那就不进行扩展式排雷,直接在该位置输出它周围雷的个数。
⑧输入的坐标周围无雷,进行扩展式排雷。
⑨注意扩展式排雷函数的形参,以及函数递归对形参的影响。
⑩注意进行函数递归的判断条件。

1.game.h

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef __GAME_H__
#define __GAME_H__
 
#define COLS 11
#define ROWS 11
#define MAX 10
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
 
void Display(char arr[COLS][ROWS], int col, int row);
void set_mine(char mine[COLS][ROWS], int col, int row);
int get_mine_count(char mine[COLS][ROWS],int x,int y);
void reset_mine(char mine[COLS][ROWS], int col, int row, int x, int y);
void extend(char mine[COLS][ROWS], int x, int y, int* win, char show[COLS][ROWS]);
 
#endif //__GAME_H__

2.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
#include "game.h"
 
void Display(char arr[COLS][ROWS], int col, int row) //打印雷盘
{
  int i = 0;
  int j = 0;
  printf(" ");
  for (i = 1; i < col-1; ++i) //打印显示行坐标提示
  {
    printf("%2d ", i);
  }
 
  printf("\n");
 
  for (i = 1; i < col - 1; ++i)
  {
    printf("%d", i); //打印显示列坐标提示
    for (j = 1; j < row - 1; ++j)
    {
      printf("%2c ", arr[i][j]);
    }
    printf("\n");
  }
}
 
void set_mine(char mine[COLS][ROWS], int col, int row) //设置雷
{
 
  int count = MAX;
  while (count)
  {
    int i = rand() % (col - 2) + 1;
    int j = rand() % (row - 2) + 1;
    if (mine[i][j] != '1')
    {
      mine[i][j] = '1';
      count--;
    }
  }
}
 
void reset_mine(char mine[COLS][ROWS], int col, int row, int x, int y) //重新设置雷
{
  mine[x][y] = '0';
  int count = 1;
  while (count)
  {
    int i = rand() % (col - 2) + 1;
    int j = rand() % (row - 2) + 1;
    if ((mine[i][j] != '1') && (i != x) && (j != y))
    {
      mine[i][j] = '1';
      count--;
    }
  }
}
 
int get_mine_count(char mine[COLS][ROWS], int x, int y) //计算坐标(x,y)周围八个位置雷的个数并以int型返回
{
  return mine[x+1][y ] +
      mine[x+1][y-1] +
      mine[x ][y-1] +
      mine[x-1][y-1] +
      mine[x-1][y ] +
      mine[x-1][y+1] +
      mine[x ][y+1] +
      mine[x+1][y+1] -8 * '0';
}
 
void extend(char mine[COLS][ROWS], int x, int y, int* win, char show[COLS][ROWS]) //排雷扩展
{
  int i = -1;
  int j = -1;
  for (i = -1; i < 2; ++i)
  {
    for (j = -1; j < 2; ++j)
    {
      if ((i != 0) || (j != 0)) 
      {
        if (x + i >= 1 && x + i <= COLS-2 && y + j >= 1 && y + j <= ROWS-2)
        {
          if (show[x + i][y + j] == '*')
          {
            int count = get_mine_count(mine, x + i, y + j);
            if (count != 0)
            {
              show[x + i][y + j] = count + '0';
              (*win)++;
            }
            else if (0 == count)
            {
              show[x + i][y + j] = '0';
              (*win)++;
              extend(mine, x + i, y + j, win, show);
            }
          }
        }
      }
    }
  }
}

3.test.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
#include "game.h"
 
 
void game()
{
  int x = 0;
  int y = 0;
  int win = 0;  //记录找到非雷位置的次数
  srand((unsigned int)time(NULL));       //随机数种子
  char mine[COLS][ROWS] = { '0' };
  memset(mine, '0', COLS*ROWS*sizeof(mine[0][0])); //利用memset函数把雷盘每个位置初始化为字符‘0'
 
  char show[COLS][ROWS] = { '0' };
  memset(show, '*', COLS*ROWS*sizeof(show[0][0]));  //把显示盘的每个位置初始化为字符‘*'
  Display(show,COLS,ROWS);
 
  printf("\n");
 
  set_mine(mine, COLS, ROWS);     //布雷,把MIX颗雷随机分布在雷盘中
  Display(mine, COLS, ROWS);
 
  while ( win<( (COLS-2)*(ROWS-2)-MAX ) )       //开始玩游戏的循环
  {
    printf("请输入排雷坐标:");
    scanf_s("%d%d", &x, &y);
    if ((x >= 1) && (x <= COLS-2) && (y >= 1) && (y <= ROWS-2))
    {
      if (show[x][y] == '*')
      {
        if (mine[x][y] == '1')
        {
          if (0 == win) //如果第一次就踩到雷,为了玩家的游戏体验,把这个雷移走
          {
            reset_mine(mine,COLS,ROWS,x,y); 
            int count = get_mine_count(mine, x, y);
            if (count != 0)      //该位置有雷,那就不进行扩展
            {
              show[x][y] = count + '0';
              win++;
              system("cls");
              Display(show, COLS, ROWS);
            }
            else
            {
              show[x][y] = '0';
              win++;
              extend(mine, x, y, &win, show);
              system("cls");
              Display(show, COLS, ROWS);
            }
          }
          else
          {
            printf("你炸了,游戏结束!\n"); //非第一步踩到雷,游戏结束
            Display(mine, COLS, ROWS);
            break;
          
        }
        else
        {
          int count = get_mine_count(mine, x, y);
          if (count != 0)      //该位置有雷,那就不进行扩展
          {
            show[x][y] = count + '0';
            win++;
            system("cls");
            Display(show, COLS, ROWS);
          }
          else
          {
            show[x][y] = '0';
            win++;
            extend(mine, x, y, &win, show);
            system("cls");
            Display(show, COLS, ROWS);
          }     
        }
      }
      else
      {
        printf("这个位置已排查,请重新选择坐标\n");
      }
    }
    else
    {
      printf("坐标不合法,请重新输入\n");
    }
  }
  if (win == ((COLS - 2)*(ROWS - 2)) - MAX)
  {
    printf("排雷成功,游戏结束\n");
    Display(mine, COLS, ROWS);
  }
}
 
void menu()
{
  printf("*******************************\n");
  printf("***** 1. play   2. exit*****\n");
  printf("*******************************\n");
}
 
void test()
{
  do
  {
    menu();
    int input = 0;
    printf("请选择:");
    scanf_s("%d", &input);
 
    switch (input)
    {
    case 1:
      game();
      break;
    case 2:
      exit(0);
      break;
    default:
      printf("输入错误\n");
      break;
    }
  } while (1);
}
 
int main()
{
  test();
}

扫雷成功

C语言实现排雷游戏(多文件)

扫雷失败

C语言实现排雷游戏(多文件)

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

原文链接:https://blog.csdn.net/Tianzez/article/details/78321050