一、作者有话要说
首先,欢迎您的到来,这是我在CSDN写下的第一篇文章,很高兴我的文章能被大家阅读(当然不知道会被多少人看到😂),这个寒假我也是刚接触C语言,我也不是计算机专业,只是相对于C语言比较感兴趣,扫雷游戏是我学习为期两周C语言之后自己写下的,文章我也是一个字一个字纯手打的,这些内容也是我的原创,作为一个学习C语言的小白,很高兴能和大家交流学习,其实扫雷游戏可以进行拓展功能,当然我也想看到大家更有趣的代码。
二、构思程序,先进行游戏界面制作
在写代码前?初步构思我们的代码要实现什么?他的目的是什么?我们从哪里开始?
我创建了三个文件,具体功能如下
(1)test.c文件用于保存main() 以及游戏界面menu(),执行游戏程序的game()
(2)game.c 储存game()函数所需要的各类函数比如 打印数组等
(3)game.h我主要用于声明各类函数,以及调用库函数,宏定义我统一在这里使用
首先我想好的是先制作好界面,
这里我创建一个tect.c我初步编辑如下:
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void menu(); void game(); int main() { menu(); return 0; } void game() { } void menu() { int input; do { printf("**********************************\n"); printf("*********** 1.play ************\n"); printf("*********** 0.exit ************\n"); printf("**********************************\n"); printf("请选择:"); scanf("%d", &input); switch (input) { case 0: break; case 1: game(); break; default: system("CLS"); printf("选择错误,请重新选择\n"); break; } } while (input); }
三、游戏的运行 ——————game()函数
这样子我们的界面是不是已经好了,接下来是对我们game()函数进行补充,game()函数就是我们怎么实现这个扫雷游戏
首先我们先分析
(1)我们要制作9*9的扫雷游戏,
这种情况我们可以利用二维数组去实现它,
#define row 9//扫雷有9行
#define column 9//扫雷有9列
char mine[row][column] = { 0 };
但是要怎么去实现?我们可以将1设置为雷,0设置为安全区
此时出现了一个问题,当我们踩一个方块若不是雷,不是应该显示周围雷的数量吗?此时我们的数组不是产生变化,面对这种问题,我们可以再创造一个和数组,
这个char show[row[column] = { 0 };数组只用于显示界面,
而char mine[row][column] = { 0 };用于程序判断,
(2)怎么解决数组边界
此时我们检验一下,当我们踩雷时,我们踩在show[2][2]时,利用mine[2][2]判断是否会踩到雷,但是当我们在show[0][0]时,我们怎么判断周围几个雷,我们是不是设计一个边界,所以我们的数组要扩大一圈,mine[row][column]的边界应该全是0所以在原来基础上我们做一下修改
这个char show[rows[columns] = { 0 };数组只用于显示界面,
而char mine[rows][columns] = { 0 };用于程序判断,
到这里我们的game.h文件如下
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
#define row 9//扫雷有9行
#define column 9//扫雷有9列
#define rows row+2//实际扫雷有几行
#define columns column+2//实际扫雷有几行
这里是test.c里的game()函数
void game()
{
char mine[rows][columns] = { 0 };//mine为埋雷数组 show为扫雷界面 创造出扫雷数组
char show[rows][columns] = { 0 };
}
(3)对两个数组进行初始化
initialize_m(mine, rows, columns);//初始化各个数组
initialize_s(show, rows, columns);
void initialize_m(char mine[rows][columns], int x, int y)//用来初始化数组mine
{
for (int i =0;i<x;i++)
{
for (int j = 0; j < y; j++)
{
mine[i][j] = '0';
}
}
}
void initialize_s(char mine[rows][columns], int x, int y)//用来初始化数组show
{
{
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
if (i == 0 || j == 0 || i == (x - 1) || j == (y - 1))
{
mine[i][j] = ' ';
}
else
{
mine[i][j] = '*';
}
}
}
}
}
(4)放置随机地雷
初始化好函数 此时我们可以放置地雷了 也就是我们在char mine[rows][columns] = { 0 };即放置1
如下:
setting(mine, rows, columns, bomb);//放置地雷
void setting(char mine[rows][columns], int x, int y,int z)
{
srand((uint)time(NULL));
for (; z > 0; z--)
{
int a = rand() % 9 + 1;
int b = rand() % 9 + 1;
if (mine[a][b] == '0')
{
mine[a][b] ='1';
}
else
{
z++;
}
}
}
(5)打印游戏
初步工作做好后我们是不是可以打印这个show[][]数组显示界面,
display(show, row, column);//显示游戏
void display(char mine[rows][columns], int x, int y)
{
printf("____扫雷游戏1.0____\n");//考虑到程序的有趣我在里添加了这个
printf("0 1 2 3 4 5 6 7 8 9\n");//打印数字方便玩家输入坐标
for (int i = 1; i <= x; i++)
{
printf("%d", i);//同上,打印数字方便玩家输入坐标
for (int j = 1; j <= y; j++)
{
printf(" %c",mine[i][j]);
}
printf("\n");
}
}
(6)玩家输入坐标,判断是否踩雷
此时我们的程序即将完成,此时我们的玩家需要输入坐标,然后程序返回他有没有踩到雷,这里,我做以下处理
void judge(char mine[rows][columns], char show[rows][columns], int x, int y)
{
int a = 0;
int b = 0;
int win = x * y - bomb;
do
{
printf("请输入你的要判断的位置:");
scanf("%d%d",&b,&a);
char count = (mine[a - 1][b - 1] +
mine[a - 1][b] +
mine[a - 1][b + 1] +
mine[a][b - 1] +
mine[a][b + 1] +
mine[a + 1][b - 1] +
mine[a + 1][b] +
mine[a + 1][b + 1]) - 7 * '0';
if(a<=x&&a>0&&b>0&&b<=y)//正确输入
{
if (mine[a][b] == '1')
{
printf("踩中地雷,游戏结束\n");
win = 0;
}
else if (mine[a][b] == '0'&&show[a][b] == '*')
{
show[a][b] = count;
system("CLS");
display(show, row, column);
win--;
if (win == 0)
{
system("CLS");
printf("恭喜你,赢得了游戏\n");
}
}
else//重复位置
{
system("CLS");
display(show, row, column);
printf("您重复输入了一个位置\n");
}
}
else//错误位置
{
printf("位置输入错误,请重新输入一个位置\n");
display(show, row, column);
}
} while (win>0);
}
在编写以上函数时我们要判断多种情况,坐标超出位置,重复输入等情况,考虑到美观我加了个system("CLS");
此时我们编写的程序就已经完成了 以下是我的全部的代码
**************************************************************************************************************
四、代码分享
(1)test.h
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu();
void game();
int main()
{
menu();
return 0;
}
void game()
{
char mine[rows][columns] = { 0 };//mine为埋雷数组 show为扫雷界面 创造出扫雷数组
char show[rows][columns] = { 0 };
initialize_m(mine, rows, columns);//初始化各个数组
initialize_s(show, rows, columns);
setting(mine, rows, columns, bomb);//放置地雷
display(show, row, column);//显示游戏
judge(mine, show, row, column);
}
void menu()
{
int input;
do {
printf("**********************************\n");
printf("*********** 1.play ************\n");
printf("*********** 0.exit ************\n");
printf("**********************************\n");
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 0:
break;
case 1:
game();
break;
default:
system("CLS");
printf("选择错误,请重新选择\n");
break;
}
} while (input);
}
(2)game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
#define row 9//扫雷有9行
#define column 9//扫雷有9列
#define rows row+2//实际扫雷有几行
#define columns column+2//实际扫雷有几行
#define bomb 10
void initialize_m(char mine[rows][columns], int x, int y);//用来初始化数组
void initialize_s(char mine[rows][columns], int x, int y);//用来初始化数组show
void display(char mine[rows][columns], int x, int y);//用来打印数组
void setting(char mine[rows][columns], int x, int y,int z);//放置地雷
void judge(char mine[rows][columns], char show[rows][columns], int x, int y);//进行扫雷
(3)game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void initialize_m(char mine[rows][columns], int x, int y)//用来初始化数组mine
{
for (int i =0;i<x;i++)
{
for (int j = 0; j < y; j++)
{
mine[i][j] = '0';
}
}
}
void initialize_s(char mine[rows][columns], int x, int y)//用来初始化数组show
{
{
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
if (i == 0 || j == 0 || i == (x - 1) || j == (y - 1))
{
mine[i][j] = ' ';
}
else
{
mine[i][j] = '*';
}
}
}
}
}
void display(char mine[rows][columns], int x, int y)
{
printf("____扫雷游戏1.0____\n");
printf("0 1 2 3 4 5 6 7 8 9\n");
for (int i = 1; i <= x; i++)
{
printf("%d", i);
for (int j = 1; j <= y; j++)
{
printf(" %c",mine[i][j]);
}
printf("\n");
}
}
void setting(char mine[rows][columns], int x, int y,int z)
{
srand((uint)time(NULL));
for (; z > 0; z--)
{
int a = rand() % 9 + 1;
int b = rand() % 9 + 1;
if (mine[a][b] == '0')
{
mine[a][b] ='1';
}
else
{
z++;
}
}
}
void judge(char mine[rows][columns], char show[rows][columns], int x, int y)
{
int a = 0;
int b = 0;
int win = x * y - bomb;
do
{
printf("请输入你的要判断的位置:");
scanf("%d%d",&b,&a);
char count = (mine[a - 1][b - 1] +
mine[a - 1][b] +
mine[a - 1][b + 1] +
mine[a][b - 1] +
mine[a][b + 1] +
mine[a + 1][b - 1] +
mine[a + 1][b] +
mine[a + 1][b + 1]) - 7 * '0';
if(a<=x&&a>0&&b>0&&b<=y)//正确输入
{
if (mine[a][b] == '1')
{
printf("踩中地雷,游戏结束\n");
win = 0;
}
else if (mine[a][b] == '0'&&show[a][b] == '*')
{
show[a][b] = count;
system("CLS");
display(show, row, column);
win--;
if (win == 0)
{
system("CLS");
printf("恭喜你,赢得了游戏\n");
}
}
else//重复位置
{
system("CLS");
display(show, row, column);
printf("您重复输入了一个位置\n");
}
}
else//错误位置
{
printf("位置输入错误,请重新输入一个位置\n");
display(show, row, column);
}
} while (win>0);
}