我和我的父亲都是扫雷的*粉,小时候我常常因为技术不好而被父亲嘲笑,那么今天我要来做一个简易版扫雷,回头也给他玩一玩。
首先我们要构建好雷盘的样子,我们理所当然想到利用二维数组。那么请注意:因为我们每一次随机生成的雷盘不能展示给用户,所以显示盘与雷盘要分开,那么我们在这里要用到两个二维数组。一个是雷盘,用来记录随机生成雷的布局,另一个是显示盘,初始化全为*,让用户来扫雷。
具体功能:
- 先由电脑随机生成雷的分布。
- 玩家通过输入坐标来选择点。
- 玩家选择对应点后,对应点将显示周围雷的个数(以该点为中心的一个九宫格)。
- 玩家需要根据这个个数,自己推断出有雷的地方,不能输入有雷的对应坐标,只能输入没雷的对应坐标。
- 当输入坐标对应点有雷时,炸“死”,游戏结束。当剩下未选中的点的个数等于总共布下的雷的个数时,游戏胜利。
实现功能的函数:
1.菜单函数,必不可少,是展示给用户的第一界面,这个比较简陋,后期可以考虑做一些fashion一点的。
1
2
3
4
5
6
7
|
void Menu()
{
printf ( "##########################\n" );
printf ( "#####choose 1 to play#####\n" );
printf ( "#####choose 0 to exit#####\n" );
printf ( "Please input your select here:>\n" );
}
|
2.随机生成雷函数,那么对应雷的横竖坐标就是需要随机生成的数。如果大家看过我之前的三子棋就知道,在这里关于随机生成用到了函数GetIndex,算是一个小优化。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
void SetMine( char mine_board[][COL], int row, int col)
{
srand ((unsigned long ) time (NULL));
int mine_num = MINES;
while (mine_num)
{
int i_index = GetIndex(1,col-2); //生成1~10的随机数
int j_index = GetIndex(1,col-2);
if (mine_board[i_index][j_index] == '0' )
{
mine_board[i_index][j_index] = '1' ;
mine_num--;
}
}
}
|
3.GetIndex函数,这里要注意start和end表示的是生成的随机数的范围。之前我们 如果用rand生成0~10的随机数,就直接rand%10,但是如果是5 ~10呢?所以我们用(end-start+1)得到的是0 ~end的范围,再加一个start,就能到到start ~end的范围。
1
2
3
4
|
static int GetIndex( int start, int end) //static修饰 代表该函数只能在本文件内部使用
{
return rand () % (end - start + 1) + start;
}
|
4.得到一个点周围雷的数量函数,这里要注意,我写的这个函数的返回值是整型,但得到的mine_board的和是字符型,那么要通过8-'0'来转换一下。
1
2
3
4
5
6
|
int GetMineNum( char mine_board[][COL], int i, int j)
{
return mine_board[i-1][j-1]+mine_board[i-1][j]+ mine_board[i-1][j+1]+ \
mine_board[i][j-1]+ mine_board[i][j+1]+ \
mine_board[i+1][j-1]+mine_board[i+1][j]+ mine_board[i+1][j+1]-8* '0' ; //整型
}
|
5.显示雷盘函数
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 ShowBoard( char show_board[][COL], int row, int col)
{
int i = 0;
int j = 0;
printf ( " " );
for (i = 1; i <= col-2; i++)
{
printf ( "%d " , i);
}
printf ( "\n" );
for (i = 1; i <= col - 1; i++)
{
printf ( "----" );
}
printf ( "\n" );
for (i = 1; i <=row - 2; i++)
{
printf ( "%-2d|" , i);
for (j = 1; j <=col - 2; j++)
{
printf ( " %c |" , show_board[i][j]);
}
printf ( "\n" );
int k = 1;
for (k = 1; k <= col - 1; k++)
{
printf ( "----" );
}
printf ( "\n" );
}
}
|
6.进行游戏函数,以total作为一个衡量标准。输入坐标,判断是否为雷的位置,是则游戏结束,不是则总的方块数减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
25
26
27
28
29
30
31
32
33
34
35
36
37
|
void PlayGame( char show_board[][COL], char mine_board[][COL], int row, int col)
{
int i = 0;
int j = 0;
int total = (ROW - 2)*(COL - 2);
while (1)
{
ShowBoard(show_board, row, col);
printf ( "Please enter your pos<x,y>" );
scanf ( "%d%d" , &i, &j);
if (i >= 1 && i < row - 2 && j >= 1 && j < col - 2)
{
if (mine_board[i][j] == '0' )
{
int num = GetMineNum(mine_board, i, j);
show_board[i][j] = num + '0' ;
total--;
}
else
{
ShowBoard(mine_board, row, col);
printf ( "Game over!you lose!:(\n" );
break ;
}
}
else
{
printf ( "Error!Try again!\n" );
continue ;
}
if (total == MINES)
{
printf ( "You win:)!\n" );
break ;
}
}
}
|
7.Game函数,初始化两个盘,主要调用了前面的函数,对函数的一个整合,来贯穿一下整个流程。
1
2
3
4
5
6
7
8
9
10
|
void Game()
{
char show_board[ROW][COL];
char mine_board[ROW][COL];
memset (show_board, '*' , sizeof (show_board));
memset (mine_board, '0' , sizeof (mine_board));
SetMine(mine_board, ROW, COL);
PlayGame(show_board, mine_board, ROW, COL);
}
|
这里还是采用了文件的形式,分为函数声明,函数定义,主函数。
函数声明 Mine.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#ifndef _MINE_H_
#define _MINE_H_
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define ROW 12
#define COL 12
#define MINES 20
void Menu();
void Game();
int GetIndex( int start, int end);
void SetMine( char mine_board[][COL], int row, int col);
int GetMineNum( char mine_board[][COL], int i, int j);
void ShowBoard( char show_board[][COL], int row, int col);
void PlayGame( char show_board[][COL], char mine_board[][COL], int row, int col);
#endif
|
函数定义 Mine.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
|
#include"Mine.h"
void Menu()
{
printf ( "##########################\n" );
printf ( "#####choose 1 to play#####\n" );
printf ( "#####choose 0 to exit#####\n" );
printf ( "Please input your select here:>\n" );
}
static int GetIndex( int start, int end) //static修饰 代表该函数只能在本文件内部使用
{
return rand () % (end - start + 1) + start;
}
//随机生成雷
void SetMine( char mine_board[][COL], int row, int col)
{
srand ((unsigned long ) time (NULL));
int mine_num = MINES;
while (mine_num)
{
int i_index = GetIndex(1,col-2);
int j_index = GetIndex(1,col-2);
if (mine_board[i_index][j_index] == '0' )
{
mine_board[i_index][j_index] = '1' ;
mine_num--;
}
}
}
//得到一个点周围雷的数量
int GetMineNum( char mine_board[][COL], int i, int j)
{
return mine_board[i-1][j-1]+mine_board[i-1][j]+ mine_board[i-1][j+1]+ \
mine_board[i][j-1]+ mine_board[i][j+1]+ \
mine_board[i+1][j-1]+mine_board[i+1][j]+ mine_board[i+1][j+1]-8* '0' ; //整型
}
//显示雷盘
void ShowBoard( char show_board[][COL], int row, int col)
{
int i = 0;
int j = 0;
printf ( " " );
for (i = 1; i <= col-2; i++)
{
printf ( "%d " , i);
}
printf ( "\n" );
for (i = 1; i <= col - 1; i++)
{
printf ( "----" );
}
printf ( "\n" );
for (i = 1; i <=row - 2; i++)
{
printf ( "%-2d|" , i);
for (j = 1; j <=col - 2; j++)
{
printf ( " %c |" , show_board[i][j]);
}
printf ( "\n" );
int k = 1;
for (k = 1; k <= col - 1; k++)
{
printf ( "----" );
}
printf ( "\n" );
}
}
void PlayGame( char show_board[][COL], char mine_board[][COL], int row, int col)
{
int i = 0;
int j = 0;
int total = (ROW - 2)*(COL - 2);
while (1)
{
ShowBoard(show_board, row, col);
printf ( "Please enter your pos<x,y>" );
scanf ( "%d%d" , &i, &j);
if (i >= 1 && i < row - 2 && j >= 1 && j < col - 2)
{
if (mine_board[i][j] == '0' )
{
int num = GetMineNum(mine_board, i, j);
show_board[i][j] = num + '0' ;
total--;
}
else
{
ShowBoard(mine_board, row, col);
printf ( "Game over!you lose!:(\n" );
break ;
}
}
else
{
printf ( "Error!Try again!\n" );
continue ;
}
if (total == MINES)
{
printf ( "You win:)!\n" );
break ;
}
}
}
void Game()
{
char show_board[ROW][COL];
char mine_board[ROW][COL];
memset (show_board, '*' , sizeof (show_board));
memset (mine_board, '0' , sizeof (mine_board));
SetMine(mine_board, ROW, COL);
PlayGame(show_board, mine_board, ROW, COL);
}
|
主函数 main.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
|
#include"Mine.h"
int main()
{
int select = 0;
int quit = 0;
while (!quit)
{
Menu();
scanf ( "%d" , &select);
switch (select)
{
case 1:
Game();
break ;
case 0:
printf ( "OK,byebye!\n" );
quit = 1;
break ;
default :
printf ( "Error!input again!\n" );
break ;
}
}
system ( "pause" );
return 0;
}
|
运行展示界面:
这是简易版的扫雷,过过干瘾还是可以,但和电脑里的扫雷还是有一定的差别,后期还要做一些优化。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_42913794/article/details/89360396