将整个代码分装在三个文件中,分别为源文件:test.c game.c game.h 。
代码如下:
game.h
#ifndef __GAME_H__
#define __GAME_H_
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define MINE_NUM 20
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
void Menu();//游戏菜单
void Game();//游戏主体函数
void Mine(char mine_map[ROWS][COLS]);//设置雷的位置
void Print(char mine_map[ROWS][COLS]);//打印游戏中的雷盘
void Init(char mine_map[ROWS][COLS],char mine_map_show[ROWS][COLS]);//初始化雷盘
void Clear_Mine(char mine_map[ROWS][COLS], char mine_map_show[ROWS][COLS]);//玩家进行扫雷的函数
int Go_on(char mine_map_show[ROWS][COLS]);//判断游戏是否继续进行下去
int Mine_num(char mine_map[ROWS][COLS], int row, int col);//判断玩家选择的位置周围有几颗雷
int Is_win(char mine_map_show[ROWS][COLS]);//判断玩家是否获胜
#endif//game.h
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Print(char mine_map[ROWS][COLS])
{
int i = 0;
int j = 0;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
printf("%c ", mine_map[i][j]);
}
printf("\n");
}
}
void Init(char mine_map[ROWS][COLS],char mine_map_show[ROWS][COLS])
{
int num = (ROWS)*(COLS);
int i = 0;
int j = 0;
memset(mine_map, '0',num);//把mine_map这个雷盘全部初始化为字符‘0’
memset(mine_map_show, '*', num);//把mine_map_show这个雷盘全部初始化为字符‘*’
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{//把定义好的雷盘的第一行和第一列都初始化为1 2 3 4 5 6 7 8 9,这样用于让玩家方便选择要查看的位置
if (0 == i)
{
mine_map[i][j] = 47 + j;
mine_map_show[i][j] = 47 + j;
}
else if (0 == j)
{
mine_map[i][j] = 47 + i;
mine_map_show[i][j] = 47 + i;
}
}
}
}
void Mine(char mine_map[ROWS][COLS])
{
int row = 0;
int col = 0;
int i = 0;
int row_s = 0;
int col_s = 0;
row_s = ROWS;
col_s = COLS;
srand((unsigned int)time(NULL));//设置随机数种子
for (i = 0; i < MINE_NUM; i++)
{//定义一个宏用来设置雷的个数
do
{
row = 0;
col = 0;
while (row < 1 || col < 1)
{
row = rand() % row_s;
col = rand() % col_s;//让电脑随机生成一个位置
}//因为雷盘的第一行或第一列用于让玩家明确位置,所以当电脑生成的位置指向雷盘的第一行或第一列时,让电脑重新生成一个随机位置
} while (mine_map[row][col] != '0');//要保证随机生成的的位置是一个合法位置
mine_map[row][col] = 36;//把所有合法位置改为字符‘$’,用来表示雷所在的位置
}
}
void Clear_Mine(char mine_map[ROWS][COLS], char mine_map_show[ROWS][COLS])
{
int row = 0;
int col = 0;
int i = 0;
int j = 0;
int mine_num = 0;
int open = 0;
printf("请输入要查看的坐标:");
flag:
scanf("%d %d", &row, &col);
if (row >= 10 || col >= 10)
{//确保玩家所输入的位置是一个合法位置
printf("非法输入,请重新输入:");
goto flag;
}
mine_num = Mine_num(mine_map, row, col);//查找玩家所选位置周围雷的个数
if (36 == mine_map[row + 1][col + 1])
{
printf("你踩到地雷了,游戏结束\n");
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
if (mine_map[i][j] == 36)
{
mine_map_show[i][j] = 36;//当玩家选中的位置是雷时,让雷盘中所有的雷的位置都展示在显示给玩家的雷盘中
}
}
}
Print(mine_map_show);
return;
}
else if ('0' == mine_map[row + 1][col + 1])
{
for (open = 0; open < rand() % 9; open++)
{
for (i = row; i < row + 2; i++)
{
for (j = col; j < col + 2; j++)
{
if ('0' == mine_map[i][j])
{
mine_map_show[i][j] = '0';//当玩家所选的位置不是雷,让电脑随机判断所选位置的周围,让不是雷的地方随机展开
}
}
}
}
mine_map_show[row + 1][col + 1] = '0'+mine_num;//让玩家所选择的位置显示周围雷的个数
}
}
int Go_on(char mine_map_show[ROWS][COLS])
{
int i = 0;
int j = 0;
int count = Is_win(mine_map_show);//用count来接收Is_win函数的返回值
for (i = 1; i < ROWS; i++)
{
for (j = 1; j < COLS; j++)
{
if (mine_map_show[i][j] ==36)//判断如果展示给玩家的雷盘中出现字符‘$’时,就证明玩家被雷炸死
{
return 0;
}
else if (MINE_NUM==count)//当count=MINE_NUM时说明玩家已经把所有不是雷的位置排除
{
return 0;
}
}
}
return 1;//return 1 证明游戏继续
}
int Mine_num(char mine_map[ROWS][COLS],int row,int col)
{//当玩家所选位置不是雷时,让电脑查找所选位置雷的个数
int i = 0;
int j = 0;
int mine_num = 0;
for (i = row; i <= row + 2; i++)
{
for (j = col ; j <= col + 2; j++)
{
if (mine_map[i][j] == 36)
{
mine_num++;
}
}
}
return mine_num;
}
int Is_win(char mine_map_show[ROWS][COLS])
{
int i = 0;
int j = 0;
int count = 0;//设置一个计数器
for (i = 1; i < ROWS; i++)
{
for (j = 1; j < COLS; j++)
{//因为用于游戏的雷盘不包括所定义的第一行和第一列,所以设置for循环从第二行的第二列开始
if (mine_map_show[i][j] == '*')
{
count++;
}//如果遇到字符‘*’计数器就+1,当所有的不是雷的位置都让玩家排掉之后,count就等于所设置的雷的个数
}
}
return count;
}
void Game()
{
int ret = 0;
char mine_map[ROWS][COLS] = { 0 };//定义一个没有隐藏雷所在位置的雷盘
char mine_map_show[ROWS][COLS] = { 0 };//定义一个专门展示给玩家的雷盘
Init(mine_map,mine_map_show);
Mine(mine_map);//把雷存进mine_map这个雷盘中
Print(mine_map);//打印一次mine_map这个雷盘,仅用于测试
printf("\n");
while (Go_on(mine_map_show))//Go_on返回1时不跳出循环,返回0时跳出循环
{
Print(mine_map_show);
Clear_Mine(mine_map, mine_map_show);
if (Is_win(mine_map_show) == MINE_NUM)
{
printf("恭喜你排出了所有雷\n");
}
}
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Menu()
{
printf("***********************************************\n");
printf("******** 1.play 0. exit *********\n");
printf("***********************************************\n");
}
int main()
{
int i = 1;
while (i)
{
Menu();
printf("请选择:");
scanf("%d", &i);
switch (i)
{
case 0:printf("退出游戏\n");
break;
case 1: printf("开始游戏\n");
Game();
break;
default:printf("选择错误,请重新开始\n");
break;
}
}
system("pause");
return 0;
}
以上即为扫雷小游戏的所有代码。