Ⅰ前提
扫雷小游戏大家都不陌生,我们这里先设计一个初级版本的。扫雷游戏的规则就是,在一块9*9的网格中(网格可以数量设置),点开所有没有雷的网格(雷数默认10颗)。 所有操作依靠对应坐标即可完成。 输入打开网格,若该网格为雷则失败;若该网格周边八个网格中有雷,则显示雷数。
Ⅱ游戏整体框架
我们既然知道游戏规则,那我们开始构思如何实现扫雷游戏,通过构思我么大致可以把代码分成四个模块,如果所有的函数均放在都放在一个main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路。
test.c:游戏逻辑的测试,包含游戏菜单的打印,游戏设计的基本逻辑的展示。
game.c:游戏功能的具体实现,这部分是整个游戏的核心代码。
game.h:相关头文件的包含、符号的声明以及函数的声明。
Ⅲ扫雷代码的实现
①初始化棋盘
为了更加方便的经行游戏我们可以先加入一个菜单,方便我们开始游戏是经行选择
void menu()
{
printf("********************");
printf("****** 1.play ******");
printf("****** 2.exit ******");
printf("********************");
}
这里我们完成的是初级棋盘99的,但为了我们后期可以自由灵活的调整棋盘大小和难度,我们只需要改动这里一次即可,增加了代码的可维护性。我们可以在game.h的头文件里定义几个雷盘的大小以及雷的个数。
定义连个数组一个用于放置雷,一个用于显示显示雷
我们开始初始化棋盘,在mine棋盘里先全部初始化为字符‘0’***
在show棋盘里全部初始化为字符‘’***
这里我们需要注意,这里的set,是两个数组都需要初始化的值,我们直接直接以参数的形式传进去,就不用初始化两次,可以出初始化我们任意给定的值。
②打印棋盘
打印棋盘我们可以自己封装一个函数,调用起来比较方便。
我们随时调用打印自己的初始化的棋盘,或者布置雷的棋盘,及时查看,防止代码出现错误。
void PrintfBoard(char Board[ROWS][COLS], int row, int col)
{
int i = 0;
printf("***********扫雷游戏************\n");
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row;i++ )
{
printf("%d ", i);
int j = 1;
for (j = 1; j <= col; j++)
{
printf("%c ", Board[i][j]);
}
printf("\n");
}
}
这里我们可以打印出mine棋盘里全部初始化为‘0’;
show棋盘里全部初始化为‘*’;
③ 布置雷
对于布置雷我们有两个需要注意两点:
一.是用于随机生成坐标的rand函数的种子srand函数只需要在main函数中声明一次即可。
二.是我们在布置雷的时候需要检查该位置是否已经有雷,避免重复布置
④排查雷
排查雷的时候我们首先需要让用户输入需要排查的坐标,然后判断坐标的合法性及该坐标是否已被排查,其次再判断该坐标周围八个位置是否有雷排查到几个雷就在输入点的坐标,记录周围八个位置雷的个数。
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入要排查点的坐标:》");
scanf("%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("不好意思,你被在炸死了。");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
//该位置不是雷,统计有几个雷。
int count = GetMineCount(mine,x,y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
}
}
else
{
printf("输入错误,请重新输入:");
}
}
}
这里我们把炸弹的位置都布置成字符**‘1’,为的是方便我们统计我们输入点的周围的八个点的雷,我们直接把周围的字符1加起来减去8个字符0**,就可以得到周围八个位置雷的数量。这样的设计方便我们统计周围的八个位置,减小了我们的工作量。
int GetMineCount(char mine[ROW][COL], 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');
}
Ⅳ游戏完整代码
🌈game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
//
void InitBoard(char Board[ROWS][COLS], int rows, int cols,char set)
{
int i = 0;
for (i = 0; i < ROWS; i++)
{
int j = 0;
for (j = 0; j < COLS; j++)
{
Board[i][j] = set;
}
}
}
//
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
printf("***************扫雷游戏****************\n");
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
//
void SetMine(char board[ROWS][COLS], int row, int col)
{
//布置十个雷;
//1.生成随机坐标,布置雷
int count = 10;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
//
int GetMineCount(char mine[ROW][COL], 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');
}
//
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入要排查点的坐标:》");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("不好意思,你被在炸死了。");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
//该位置不是雷,统计有几个雷。
int count = GetMineCount(mine,x,y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
}
}
else
{
printf("输入错误,请重新输入:");
}
}
}
🌈text.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu()
{
printf("********************\n");
printf("****** 1.play ******\n");
printf("****** 2.exit ******\n");
printf("********************\n");
}
void game()
{
//定义连个数组一个用于放置雷,一个用于显示雷
char mine[ROWS][COLS];
char show[ROWS][COLS];
InitBoard(mine, ROWS, COLS,'0');
InitBoard(show, ROWS, COLS,'*');
/*PrintfBoard(mine, ROW, COL);*/
//PrintfBoard(show, ROW, COL);
SetMine(mine, ROW, COL);
DisplayBoard(mine, ROW, COL);
FindMine(mine,show, ROW, COL);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:》");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏");
break;
default:
printf("输入错误,请重新输入:》");
break;
}
} while (input);
return 0;
}
🌈game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//#define COUNT 10
//初始化棋
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char board[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);