
- 游戏简介
- 1. 前言
- 2. 扫雷游戏规则:
- 一、各功能函数
- 1. 简易菜单
- 2. 初始化扫雷界面
- 3. 打印扫雷界面
- 4. 布雷
- 5. 标记
- 6. 展开(爆炸式效果)
- 7. 找雷
- 8. 排雷
- 二、完整代码
- 1.game.h------游戏用到的函数
- 2.test.c---------主逻辑
- 3. game.c---------游戏的实现
- 总结
游戏简介 1. 前言
游戏中需要两个数组,一个用于存放雷(不向玩家展示),另一个用于向用户展示游戏进程,即排雷情况.
2. 扫雷游戏规则:从键盘输入你推测的非雷的坐标,如果该坐标为雷,恭喜您被炸,游戏失败
游戏失败后屏幕上打印出的棋盘中1表示该位置为雷,0表示该位置非雷
如果该坐标不是雷,屏幕上会显示出该坐标周围(上下左右)八个坐标中雷的个数,
玩家可根据屏幕上显示的雷的个数进行下一步排雷
当玩家将坐标中全部非雷坐标都找到,玩家获得胜利.
提示:共有十个雷(该数可在源代码的预处理字符EASYCOUNT自定义)
添加了标记和展开功能:
标记:可以标记已经确认的雷的位置
展开:输入一个坐标,若该坐标周围无雷, 可将该坐标周围无雷区域全部显示出来
game.h 头文件中是函数声明
game.c 源文件里面是函数定义和调用
test.c 源文件里面是函数调用
void menu() {
printf("*****************\n");
printf("**** 1. play ****\n");
printf("**** 0. exit ****\n");
printf("*****************\n");
}
2. 初始化扫雷界面
//初始化
void Initboard(char board[ROWS][COLS], int rows, int cols, char ret) {
int i = 0, j = 0;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
board[i][j] = ret;
}
}
}
3. 打印扫雷界面
void DisplayBoard(char board[ROWS][COLS], int row, int col) {
int i = 0, j = 0;
for (j = 0; j <= col; j++) {
printf("%d ", j);
}
printf("\n");
for (i = 1; i <= row; i++) {
printf("%d ", i);
for (j = 1; j <= col; j++) {
printf("%c ", board[i][j]);
}
printf("\n");
}
}
4. 布雷
布雷用到了随机数的生成,需要包含头文件stdlib.h和time.h
//布雷
void Getthunder(char board[ROWS][COLS], int row, int col) {
int count = EASYCOUNT;
while (count) {
int i = rand() % 9 + 1;
int j = rand() % 9 + 1;
if (board[i][j] == '0') {
board[i][j] = '1';
count--;
}
}
}
有雷处为1, 非雷处为0,此界面不向玩家展示
5. 标记如果有玩家已确认的雷, 可以将其标记
展开以函数递归实现
输入一个坐标,若该坐标周围无雷, 可将该坐标周围无雷区域全部显示出来
这里我们将地雷数设置为1,方便查看爆炸效果
可以看到非雷区将全部以空格形式展示
void Spr_board(char thunder[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
if (x >= 1 && x <= 9 && y >= 1 && y <= 9) {
int i = -1, j = -1;
for (i = -1; i < 2; i++) {
for (j = -1; j < 2; j++) {
if (thunder[x + i][y + j] == '0') {
if (show[x + i][y + j] == '*') {
show[x + i][y + j] = get_thunder_count(thunder, x + i, y + j) + '0';
if ('0' == show[x + i][y + j]) {
show[x][y] = ' ';
show[x +i][y + j] = ' ';
//show[x][y] = ' ';
//DisplayBoard(thunder, ROW, COL);
//DisplayBoard(show, ROW, COL);
Spr_board(thunder, show, x + i, y + j);
}
}
}
}
}
}
}
7. 找雷
int get_thunder_count(char thunder[ROWS][COLS], int x, int y) {
return (thunder[x - 1][y - 1] + thunder[x - 1][y] + thunder[x - 1][y + 1] +
thunder[x][y - 1] + thunder[x][y + 1] +
thunder[x + 1][y - 1] + thunder[x + 1][y] + thunder[x + 1][y + 1] - 8 * '0');
}
这里用加减的方法实现了由字符到数字的转变
将该值加’0’就又能将数字转换为字符,这种方法还是第一次见.
//排雷
void FindBoard(char thunder[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
int x = 0, y = 0;
int win = 0;
char b = '0';
while (win < ROW * COL - EASYCOUNT) {
int x1 = 0, y1 = 0;
do {
printf("是否要标记雷的位置,标记后无法取消(Y/N):\n");
scanf("%c", &b);
getchar();
if ('Y' == b) {
printf("请输入您确定的雷的坐标(一旦确认无法更改,输入0 0退出此 *** 作)\n");
scanf("%d %d", &x1, &y1);
if (0 != x1 && 0 != y1) {
show[x1][y1] = 'z';
DisplayBoard(show, ROW, COL);
}
}
} while (x1 != 0 && y1 != 0 );
printf("请输入要排雷的坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (show[x][y] != '*') {
printf("该位置已经排查过了,请重新选择\n");
}
else {
if (thunder[x][y] == '1') {
printf("\a恭喜你!\n");
printf("\a被炸死了!\n");
DisplayBoard(thunder, ROW, COL);
break;
}
else {
win++;
show[x][y] = get_thunder_count(thunder, x, y) + '0';
//这里get_thunder_count函数里面将字符型转换为数字型
//此处又将数字型转换为字符型,注意方法
//展开功能
if ('0' == show[x][y]) {
Spr_board(thunder, show, x, y);
}
DisplayBoard(show, ROW, COL);
}
}
}
else {
printf("坐标输入不合法,请重新输入\n");
}
}
if (win == EASYCOUNT) {
printf("\a很遗憾!\n");
printf("\a排雷成功!\n");
DisplayBoard(show, ROW, COL);
}
}
二、完整代码
1.game.h------游戏用到的函数
# include
# include
# include
# define ROW 9 //棋盘行数,可自定义
# define COL 9 //棋盘列数,可自定义
# define ROWS (ROW + 2)
# define COLS (COL + 2)
//设置雷的个数
# define EASYCOUNT 1
//初始化
void Initboard(char board[ROWS][COLS], int rows, int cols, char ret);
//打印:
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布雷
void Getthunder(char board[ROWS][COLS], int row, int col);
//排雷
void FindBoard(char thunder[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//找雷
int get_thunder_count(char thunder[ROWS][COLS], int rows, int cols);
//展开
void Spr_board(char thunder[ROWS][COLS], char show[ROWS][COLS], int x, int y);
2.test.c---------主逻辑
这里主要是代码的调用,也是一个主逻辑,代码的神经中枢
# define _CRT_SECURE_NO_WARNINGS
# include "game.h"
void menu() {
printf("*****************\n");
printf("**** 1. play ****\n");
printf("**** 0. exit ****\n");
printf("*****************\n");
}
void game() {
srand((unsigned int)time(NULL));
char thunder[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
//初始化雷区和显示区
Initboard(thunder, ROWS, COLS, '0');
Initboard(show, ROWS, COLS, '*');
//打印雷区和显示区:
//DisplayBoard(thunder, ROW, COL);
DisplayBoard(show, ROW, COL);
//布雷
Getthunder(thunder, ROW, COL);
//DisplayBoard(thunder, ROW, COL);
//排雷
FindBoard(thunder, show, ROW, COL);
}
int main()
{
int n = 0;
do {
menu();
printf("请输入要完成的功能编号:");
scanf("%d", &n);
getchar();
switch (n) {
case 1:
printf("玩游戏\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (n);
}
3. game.c---------游戏的实现
如果说test.c是一个领导,那么game.c就是里面的员工了,包含大部分的函数定义
# define _CRT_SECURE_NO_WARNINGS
# include "game.h"
//初始化
void Initboard(char board[ROWS][COLS], int rows, int cols, char ret) {
int i = 0, j = 0;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
board[i][j] = ret;
}
}
}
//打印
void DisplayBoard(char board[ROWS][COLS], int row, int col) {
int i = 0, j = 0;
for (j = 0; j <= col; j++) {
printf("%d ", j);
}
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 Getthunder(char board[ROWS][COLS], int row, int col) {
int count = EASYCOUNT;
while (count) {
int i = rand() % 9 + 1;
int j = rand() % 9 + 1;
if (board[i][j] == '0') {
board[i][j] = '1';
count--;
}
}
}
//展开
void Spr_board(char thunder[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
if (x >= 1 && x <= 9 && y >= 1 && y <= 9) {
int i = -1, j = -1;
for (i = -1; i < 2; i++) {
for (j = -1; j < 2; j++) {
if (thunder[x + i][y + j] == '0') {
if (show[x + i][y + j] == '*') {
show[x + i][y + j] = get_thunder_count(thunder, x + i, y + j) + '0';
if ('0' == show[x + i][y + j]) {
show[x][y] = ' ';
show[x +i][y + j] = ' ';
//show[x][y] = ' ';
//DisplayBoard(thunder, ROW, COL);
//DisplayBoard(show, ROW, COL);
Spr_board(thunder, show, x + i, y + j);
}
}
}
}
}
}
}
//找雷
int get_thunder_count(char thunder[ROWS][COLS], int x, int y) {
return (thunder[x - 1][y - 1] + thunder[x - 1][y] + thunder[x - 1][y + 1] +
thunder[x][y - 1] + thunder[x][y + 1] +
thunder[x + 1][y - 1] + thunder[x + 1][y] + thunder[x + 1][y + 1] - 8 * '0');
}
//'1' - '0' = 1;
//'0' - '0' = 0;
//排雷
void FindBoard(char thunder[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
int x = 0, y = 0;
int win = 0;
char b = '0';
while (win < ROW * COL - EASYCOUNT) {
int x1 = 0, y1 = 0;
do {
printf("是否要标记雷的位置,标记后无法取消(Y/N):\n");
scanf("%c", &b);
getchar();
if ('Y' == b) {
printf("请输入您确定的雷的坐标(一旦确认无法更改,输入0 0退出此 *** 作)\n");
scanf("%d %d", &x1, &y1);
if (0 != x1 && 0 != y1) {
show[x1][y1] = 'z';
DisplayBoard(show, ROW, COL);
}
}
} while (x1 != 0 && y1 != 0 );
printf("请输入要排雷的坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (show[x][y] != '*') {
printf("该位置已经排查过了,请重新选择\n");
}
else {
if (thunder[x][y] == '1') {
printf("\a恭喜你!\n");
printf("\a被炸死了!\n");
DisplayBoard(thunder, ROW, COL);
break;
}
else {
win++;
show[x][y] = get_thunder_count(thunder, x, y) + '0';
//这里get_thunder_count函数里面将字符型转换为数字型
//此处又将数字型转换为字符型,注意方法
//展开功能
if ('0' == show[x][y]) {
Spr_board(thunder, show, x, y);
}
DisplayBoard(show, ROW, COL);
}
}
}
else {
printf("坐标输入不合法,请重新输入\n");
}
}
if (win == EASYCOUNT) {
printf("\a很遗憾!\n");
printf("\a排雷成功!\n");
DisplayBoard(show, ROW, COL);
}
}
总结
ok,大致就是这样了,如果发现哪里有bug还请大佬指出,小王在此谢过,有不清楚的地方也可以来问小王,很高兴和大家一起学习!!!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)