总共分为三个文件,头文件(存放变量和函数声明),游戏文件(实现游戏内部函数),测试文件
以下是头文件:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<Windows.h>
#include<time.h>
#include<stdlib.h>
#define ROW 8//定义棋盘的行和列,为了后面计算方便,所以定义两种行列
#define COL 8//因为计算周围有多少个雷的时候,是计算周围八个,如果是边上的格子计算周围的雷,那就越界访问了
#define ROWS ROW+2//所以虽然我们显示的是8*8的棋盘,但实际上是10*10
#define COLS COL+2//只不过最外层的格子始终不放雷,所以计算起来也不会越界访问
#define EASY 63//设置简单的模式为10个雷
void initboard(char board[ROWS][COLS], int rows, int cols,char ch);//传进来的还是10*10数组
void display(char board[ROWS][COLS], int row, int col);//只不过使用的时候只用到8*8,所以后面参数传的是8
void putmine(char board[ROWS][COLS], int row, int col);
void checkmine(char board1[ROWS][COLS], char board2[ROWS][COLS], int row, int col);
以下是游戏函数文件:
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void initboard(char board[ROWS][COLS], int rows, int cols, char ch)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = ch;
}
}
}
void display(char board[ROWS][COLS], int row, int col)
{
int i, j = 0;
for (i = 0; i <= row; i++)//为了看上去方便,给最外面打印每行每列的编号
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);//打印编号
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
void putmine(char board[ROWS][COLS], int row, int col)
{
int count = EASY;//每当成功放置一个雷,count就减1,直到0
while (count)//随机生产的坐标可能重复,所以用循环
{
int x = rand() % row + 1;//因为我们要用到1-8行、列,所以取模于8在加上1
int y = rand() % col + 1;//如果只是单纯地取模8或9,那就是0到8或0到9,就没有1了
if (board[x][y] == '0')//若该坐标没被放置,则进入以下语句
{
board[x][y] = '1';//放置成功,将坐标内容改为字符'1'
count--;
}
}
}
int numofmind(char board[ROWS][COLS], int x,int y)
{
//将周围八个位置的ASCII码相加,再减去8个‘0’,最后返回的就是炸弹的个数
//‘1’的ASCII码是49,0是48,相减正好是1
return (board[x - 1][y] +
board[x - 1][y - 1] +
board[x][y - 1] +
board[x + 1][y - 1] +
board[x + 1][y] +
board[x + 1][y + 1] +
board[x][y + 1] +
board[x - 1][y + 1] - 8 * '0');
}
void checkmine(char board1[ROWS][COLS], char board2[ROWS][COLS], int row, int col)
{
int x, y = 0;//创建两个变量存放玩家输入的坐标
int count = row * col - EASY;//行*列-雷的个数等于我们要排除雷的个数
while (count)//坐标可能重复,所以用循环//当count不为0,则循环
{
printf("请输入要排查的坐标\n");
scanf("%d%d", &x, &y);
if (board1[x][y] == '1')//如果坐标是地雷,则提示玩家失败,跳出循环
{
printf("你输了\n");
break;
}
else
{
int num = numofmind(board1, x, y);//写一个函数,显示周围八个坐标总共的地雷数量
board2[x][y] = num + '0';//加上'0'转换成字符,因为这个数组是char类型的
count--;
display(board2, ROW, COL);//打印显示的数组
//判断输赢,每成功排除一个雷,就count减1,当count为0,说明全排完了,就显示胜利
}
}
if (count == 0)
{
printf("胜利!\n");
}
}
以下是测试文件:
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu()
{
printf("******************\n");
printf("******1.game******\n");
printf("******2.exit******\n");
printf("******************\n");
}
void game()
{
char mine[ROWS][COLS] = { 0 };//创建棋盘,一个是放地雷,不显示出来,一个用来显示
char show[ROWS][COLS] = { 0 };
initboard(mine,ROWS,COLS,'0');//初始化棋盘,将放地雷的棋盘中所有内容初始化成字符‘0’
initboard(show, ROWS, COLS, '*');//将显示的棋盘内容初始化成‘*’
putmine(mine, ROW, COL);//布置雷
display(show, ROW, COL);//打印棋盘
display(mine, ROW, COL);
checkmine(mine, show, ROW, COL);//排查雷
}
int main()
{
srand((unsigned int)time(NULL));//随机数种子
int input = 0;//存放玩家选择的一个变量
do//玩家可能输入错误,或者为了玩好一把方便继续玩,所以用循环
{
menu();//上来先打印菜单
printf("请输入你的选择\n");//提示玩家选择
scanf("%d", &input);
switch (input)
{
case 1://选择1,则开始游戏
game();//调用游戏的函数
break;
case 0://选择0,则退出
printf("退出成功\n");
exit(0);
break;
default://输入其他为错误
printf("请重新输入\n");
break;
}
} while (1);
return 0;
}
总共160行代码,轻轻松松