扫雷游戏是一款经典的单机游戏,玩家需要在一个网格中找出所有的地雷而不触发任何一个。下面我将详细介绍扫雷游戏的设计思路和实现步骤。
一、游戏设计
1. 游戏界面:游戏界面采用*阵来显示,*可能是雷,也可能不是雷,并可以显示周围8格的雷数。
2. 操作方式:玩家通过输入相关坐标来获取雷的个数,进而进行排雷。
3. 游戏胜利:当玩家输入所有除雷外的坐标,游戏胜利。
4. 游戏失败:当玩家触发地雷时,游戏失败。
二、实现代码
接下来就跟着代码的一步步实现,对扫雷游戏有个初步理解:
1.先打印菜单,根据玩家需求选择进行游戏或者退出游戏;
#include "game.h"
void menu(void)
{
printf("*****************************\n");
printf("*********** 1.play **********\n");
printf("*********** 0.exit **********\n");
printf("*****************************\n");
}
int main()
{
int input = 0;
do
{
menu();//menu函数打印菜单
printf("请选择:");
scanf("%d", &input);//玩家选择
switch (input)
{
case 1:
game();
break;
case 0:
printf("正在退出游戏......");
break;
default:printf("非法输入,请重新选择。\n");
}
} while (input);
return 0;
}
先做出游戏的框架,运用do while语句来实现进入游戏或者退出游戏。
当输入1时进入游戏,当输入0时退出游戏,输入其他值使用default语句来提醒玩家重新选择。
2.总体框架已经有了轮廓,接下来实现游戏主体部分。
但是只在主函数上进行编译会使代码看起来繁琐,所以游戏主体部分可以放在game函数里面进行操作。
void game(void)
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
intboard(mine, ROWS, COLS, '0');
intboard(show, ROWS, COLS, '*');
displayboard(show, ROW, COL);
buried_mines(mine, ROW, COL);
fine_mine(mine, show, ROW, COL);
}
将游戏的各个部分存放在game函数中,各个部分又有单独的函数进行实现,这样就提高了代码的可读性。
3.定义两个二维数组,一个用来埋雷,一个用来显示未知格子和已知格子周围的雷的数量。
char mine[ROWS][COLS];//埋雷
char show[ROWS][COLS];//显示
4.接下来就分别对这两个数组进行赋值。
对于mine数组,可以用0表示非雷,1表示雷,先对所有数组元素赋值为字符0,对于埋雷,我们在后面讲解。
对于show函数,我们需要它让玩家不知道对应坐标是否为雷,所以我们将它用字符*来隐藏,同时也需要让它显示其周围的雷的个数,统计雷的个数我们后面讲解。
对于数组赋值,我们可以用一个函数来实现对两个数组的赋值。
void intboard(char arr[ROWS][COLS], int rows, int cols, char set)//set为需要的字符
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
arr[i][j] = set;
}
}//给数组赋值
//函数调用
intboard(mine, ROWS, COLS, '0');
intboard(show, ROWS, COLS, '*');
5.接下来就是埋雷阶段,我们需要一个函数进行埋雷,也就是对埋雷的数组将字符0赋值为字符1。
void buried_mines(char arr[ROWS][COLS],int row, int col)
{
int count_mine = Autonomous_input;
while (count_mine)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if(arr[x][y] == '0')
{
arr[x][y] = '1';
count_mine--;
}
}
}
6.接下来就需要给玩家显示一个9*9的*阵进行排雷了,那么就需要一个打印数组的函数来对显示数组进行打印。
void displayboard(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
int 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 ", arr[i][j]);
}
printf("\n");
}
7。最后就是排雷阶段(由于是简易版,需要一个一个进行排查。)
int get_mine_count(char mine[ROWS][COLS],int x,int y)
{
return (mine[x-1][y-1] + mine[x-1][y] + mine[x-1][y+1] + mine[x][y-1] + mine[x][y+1] + mine[x+1][y-1] + mine[x+1][y] + mine[x+1][y+1] - 8 * '0');
}//对某一坐标周围的雷进行统计
void fine_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x;
int y;
int win = 0;
while (win < row * col - Autonomous_input)
{
printf("请输入你要查找的坐标【形式:(X Y)】:");
scanf("%d %d", &y, &x);
if (x >= 1 && x <= col && y >= 1 && y <= row)
{
if (mine[x][y] == '1')
{
printf("哈哈哈,你炸屎了。\n");
displayboard(mine, ROW, COL);
break;
}
else
{
int count = get_mine_count(mine, x, y);
show[x][y] = count + '0';
displayboard(show, ROW, COL);
win += 1;
}
}
else
{
printf("坐标非法,请重新输入。\n\a\a\a");
}
}
if (win == row * col - Autonomous_input)
{
printf("诶哟,不错哦。\n");
displayboard(mine, ROW, COL);
}
}
三.具体代码如下
1.游戏主体(源文件)
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu(void)
{
printf("*****************************\n");
printf("*********** 1.play **********\n");
printf("*********** 0.exit **********\n");
printf("*****************************\n");
}
//游戏实现
//1.游戏界面,选择进入游戏或退出游戏
//2.定义两个二维数组,一个埋雷,一个显示,均为11*11,实际为9*9进行操作
//3.随机埋雷,设定为十个雷
//4.排查雷,踩雷即为失败;多次排查,每次排查都会显示9*9之内的雷的个数,直到排查所有雷即为成功
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("非法输入,请重新选择。\n");
}
} while (input);
return 0;
}
2.相关函数(源文件)
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void intboard(char arr[ROWS][COLS], int rows, int cols, char set);
void game(void)
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
intboard(mine, ROWS, COLS, '0');
intboard(show, ROWS, COLS, '*');
displayboard(show, ROW, COL);
buried_mines(mine, ROW, COL);
fine_mine(mine, show, ROW, COL);
}
void intboard(char arr[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
arr[i][j] = set;
}
}
void displayboard(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
int 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 ", arr[i][j]);
}
printf("\n");
}
}
void buried_mines(char arr[ROWS][COLS],int row, int col)
{
int count_mine = Autonomous_input;
while (count_mine)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if(arr[x][y] == '0')
{
arr[x][y] = '1';
count_mine--;
}
}
}
int get_mine_count(char mine[ROWS][COLS],int x,int y)
{
return (mine[x-1][y-1] + mine[x-1][y] + mine[x-1][y+1] + mine[x][y-1] + mine[x][y+1] + mine[x+1][y-1] + mine[x+1][y] + mine[x+1][y+1] - 8 * '0');
}
void fine_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x;
int y;
int win = 0;
while (win < row * col - Autonomous_input)
{
printf("请输入你要查找的坐标【形式:(X Y)】:");
scanf("%d %d", &y, &x);
if (x >= 1 && x <= col && y >= 1 && y <= row)
{
if (mine[x][y] == '1')
{
printf("哈哈哈,你炸屎了。\n");
displayboard(mine, ROW, COL);
break;
}
else
{
int count = get_mine_count(mine, x, y);
show[x][y] = count + '0';
displayboard(show, ROW, COL);
win += 1;
}
}
else
{
printf("坐标非法,请重新输入。\n\a\a\a");
}
}
if (win == row * col - Autonomous_input)
{
printf("诶哟,不错哦。\n");
displayboard(mine, ROW, COL);
}
}
3.相关声明(头文件)
#pragma once
#include <stdio.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define Autonomous_input 10
void game(void);
void displayboard(char arr[ROWS][COLS], int rows, int cols);
#include <time.h>
#include <stdlib.h>
void buried_mines(char arr[ROWS][COLS], int row, int col);
int get_mine_count(char mine[ROWS][COLS], int x, int y);
void fine_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
以上就是我对简易版扫雷的见解,如果有错误或者补充欢迎评论区留言,感谢观看!!!