扫雷游戏
一、分三份文件
(1)test.c
test 用来游戏测试
(2)(game.c) (game.h)
game.c 和 game.c 用来 实现 游戏逻辑
二、实现游戏
(1)初始化菜单
在 test.c 中设置
#include<stdio.h>
void menu() // 这里是菜单
{
printf("**********************\n");
printf("**********************\n");
printf("******* 1 play ******\n");
printf("******* 0 exit ******\n");
printf("**********************\n");
printf("**********************\n");
}
void test()
{
int input = 0;
do
{
menu(); // 带入上面的目录函数
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game(); //开始游戏代码入口
break;
case 0:
printf("游戏结束,退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
(2)设置棋盘
扫雷游戏需要两个棋盘
( 1 ) 数字棋盘 :目的是在数字里面埋雷。
( 2 )符号*棋盘:目的是把数字盖住,不让大家看到雷在哪里。
首先是在test.c文件里面输入
DisplayBoard(show,ROW,COL); //符号棋盘
DisplayBoard(mine, ROW, COL); //数字棋盘
然后在geme.h 文件 里面声明
void DisplayBoard(char arr[ROWS][COLS], int row, int col); //打印棋盘函数
设置棋盘大小在game.h中实现:首先设置两个数字,分别为ROW 和 COL
#define ROW 9
#define COL 9
并且假设我们排查(2,5)这个坐标时,我们访问周围的⼀圈8个⻩⾊位置,统计周围雷的个数是1
假设我们排查(8,6)这个坐标时,我们访问周围的⼀圈8个⻩⾊位置,统计周围雷的个数时,最下⾯的三
个坐标就会越界,为了防⽌越界,我们在设计的时候,给数组扩⼤⼀圈,雷还是布置在中间的99的坐
标上,周围⼀圈不去布置雷就⾏,这样就解决了越界的问题。所以我们将存放数据的数组创建成1111
是⽐较合适。
所以我们需要在game.c中加入
#define ROWS ROW+2
#define COLS COL+2
然后在game.c中实现棋盘函数
}void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
printf("-------扫雷游戏-------\n");
for (int c = 0; c <= row; c++)
{
printf("%d ", c);
}printf("\n");
for (int a = 1; a <= row; a++)
{
int b = 0;
printf("%d ", a);
for(int b=1;b<=col;b++)
{
printf("%c ",arr[a][b]);
}
printf("\n");
}
}
(2)布置雷和排查雷
首先是布置雷
在test.c中加入伪随机值,需要加入头文件
#include<stdlib.h>
#include<time.h>
srand((unsigned int)time(NULL));
在game.h中加入
void SetMine(char arr[ROWS][COLS],int row,int col); //布置雷函数
在game.c中实现函数
void SetMine(char arr[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (arr[x][y] == '0') //这里是字符 0 不是数字0
{
arr[x][y] = '1';
count--;
}
}
}
然后就是排查雷
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int wan = 0;
//输出坐标后 ,判断坐标的有效性
while (wan<row*col- EASY_COUNT) //判断剩下的格子还剩下多少个
{
printf("请输入要排查的坐标");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) //判断你输出的数字是否正确 正确就进入游戏中
{
if (show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("恭喜你选中炸弹,被炸飞。\n");
DisplayBoard(mine, ROW, COL);//显示出来
break;
}
else //坐标不是雷,就要统计周围的雷
{
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
wan++; //排对一个格子就加1
}
}
else
{
printf("该坐标已经被排查过,请重新输入\n");
}
}
else
{
printf("坐标输入过大或者过小 ,请重新输入\n"); //输出错误
}
}
if (wan == row * col - EASY_COUNT)
{
printf("恭喜你赢了\n"); //找到所有的雷,游戏结束
}
}
计算周围有几个雷
先在game.h中声明 需要多少个值
FindMine(char arr[ROWS][COLS], char show[ROWS][COLS], int row, int col);
在game,c实现函数
用转义字符算出周围有几个雷 用 ‘0’减去周围8个字符的数字,最终等到周围雷的总是
int GetMineCount(char mine[ROWS][COLS],int x,int y)
{
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');
三、总代码参考
1(test.c)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"
void menu() //这里是菜单
{
printf("**********************\n");
printf("**********************\n");
printf("******* 1 play ******\n");
printf("******* 0 exit ******\n");
printf("**********************\n");
printf("**********************\n");
}
void game()
{ //设置两个棋盘
//mine数组放布置好雷的信息
char mine[ROWS][COLS] = { 0 };//这个是数字棋盘放置雷的棋盘
//show放排查出雷的信息
char show[ROWS][COLS] = { 0 };//这个是全放“**”符号棋盘
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//打印棋盘
DisplayBoard(show,ROW,COL); //符号棋盘
SetMine(mine,ROW,COL);//设置随机10个雷
DisplayBoard(mine, ROW, COL); //数字棋盘
FindMine(mine, show, ROW, COL); //排查雷
}
void test()
{
int input = 0;
srand((unsigned int)time(NULL));//设置伪随机值用来设置雷
do
{
menu(); //目录
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game(); //开始游戏代码入口
break;
case 0:
printf("游戏结束,退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
2 (game.c)
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
#include<stdio.h>
void InitBoard(char arr[ROWS][COLS], int rows, int cols,int set)
{
for (int a = 0; a < rows; a++)
{
int b = 0;
for (b = 0; b < cols; b++)
{
arr[a][b] = set;
}
}
}void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
printf("-------扫雷游戏-------\n");
for (int c = 0; c <= row; c++)
{
printf("%d ", c);
}printf("\n");
for (int a = 1; a <= row; a++)
{
int b = 0;
printf("%d ", a);
for(int b=1;b<=col;b++)
{
printf("%c ",arr[a][b]);
}
printf("\n");
}
}
void SetMine(char arr[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
int GetMineCount(char mine[ROWS][COLS],int x,int y)
{
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');
}
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int wan = 0;
//输出坐标后 ,判断坐标的有效性
while (wan<row*col- EASY_COUNT)
{
printf("请输入要排查的坐标");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("恭喜你选中炸弹,被炸飞。\n");
DisplayBoard(mine, ROW, COL);//显示出来
break;
}
else //坐标不是雷,就要统计周围的雷
{
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
wan++;
}
}
else
{
printf("该坐标已经被排查过,请重新输入\n");
}
}
else
{
printf("坐标输入过大或者过小 ,请重新输入\n");
}
}
if (wan == row * col - EASY_COUNT)
{
printf("恭喜你赢了\n");
}
}
3 (game.h)
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define EASY_COUNT 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
void InitBoard(char arr[ROWS][COLS],int rows,int cols,int set); //棋盘初始化函数
void DisplayBoard(char arr[ROWS][COLS], int row, int col); //打印棋盘函数
void SetMine(char arr[ROWS][COLS],int row,int col); //布置雷函数
FindMine(char arr[ROWS][COLS], char show[ROWS][COLS], int row, int col);