一、扫雷游戏的分析
在这里我们采用基础版的扫雷界面,它是由一个9*9的棋盘构成的,这81个格子中包含着10个雷,当你选中雷后游戏结束。
首先,我们根据棋盘的样子想到了二位数组,由于雷是看不见的,雷埋在下面,我们可以得出这个游戏是由两个二维数组组成的。假设我们用1表示雷,0表示非雷,但如果某个位置显示1的话,这个1是表示雷呢还是表示周围有一个雷呢?这里面起了冲突。
其次,我们应该设计多大的棋盘呢?有人说设计一个9*9的数组,但如果这样设计的话,当你去查看棋盘边界位置时,这个位置周围的部分坐标会位于数组界定的大小之外,这样的话就会导致越界现象,我们就必须去判断是否越界,这样的话会增加我们的工作量。如图:
因此,我们可以在9*9数组的基础之上多加两行和两列,创建一个11*11的数组,这样就能解决越界问题的发生。如图:
二、创建扫雷的流程
三、程序设计
首先,设计主函数:
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("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
根据代码可知,使用menu函数(此代码根据个人需求设计,可加可不加)
void menu()
{
printf("***********************\n");
printf("***** 1.play *****\n");
printf("***** 0.exit *****\n");
printf("***********************\n");
}
然后当输入1时,运行game函数,在运行game函数时,我们需要对棋盘进行构建,构建一个11*11的二位数组
//构建二位数组
char mine[Hangs][Lies];
char show[Hangs][Lies];
然后再对棋盘进行初始化
//初始化棋盘
InitBoard(mine, Hangs, Lies, '0');//雷
InitBoard(show, Hangs, Lies, '*');//表面展示
打印棋盘
//打印棋盘
void PrintBoard(char arr[Hangs][Lies],int hang,int lie)
{
int i = 0;
printf("\n");
printf("------扫雷游戏------");
printf("\n");
for (i = 0; i <= hang; i++) //打印出坐标,使坐标的选择更简便
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= hang; i++)
{
printf("%d ", i); //打印出坐标,使坐标的选择更简便
int j = 0;
for (j = 1; j <= lie; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
然后进行埋雷,埋雷需要用到随机数,其头文件为#include<stdlib.h>
//埋雷
void LatMine(char arr[Hangs][Lies],int hang,int lie)
{
int lei = EASY_COUNT;
while (lei)
{
int x = rand() % hang + 1;
int y = rand() % lie + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
lei--;
}
}
}
埋雷后,就可以进行排雷
int Count(char mine[Hangs][Lies], int x, int y)
{
return (mine[x - 1][y] + mine[x + 1][y] + mine[x - 1][y - 1]
+ mine[x - 1][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x][y - 1] - 8 * '0');
} //计算选择坐标附近包含雷的数量
//排雷
void clearmine(char mine[Hangs][Lies], char show[Hangs][Lies], int hang, int lie)
{
int x = 0;
int y = 0;
int win = 0;
while (win < hang * lie - EASY_COUNT)
{
printf("请输入要排查的坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= hang && y >= 1 && y <= lie)
{
if (mine[x][y] == '1')
{
printf("你被雷炸死了\n");
PrintBoard(mine, Hang, Lie);
break;
}
else
{
int count = Count(mine, x, y);
show[x][y] = count + '0';//将某个数字转化为该数字的字符形式
PrintBoard(show, Hang, Lie);
win++;
}
}
else
{
printf("坐标输入错误,请重新输入");
}
}
if (win == hang * lie - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
PrintBoard(mine, Hang, Lie);
}
}
四、全代码书写
头函数game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define EASY_COUNT 10
#define Hang 9
#define Lie 9
#define Hangs Hang+2
#define Lies Lie+2
//初始化二位数组
void InitBoard(char arr[Hangs][Lies], int hangs, int lies, char set);
//打印棋盘
void PrintBoard(char arr[Hangs][Lies], int hang, int lie);
//埋雷
void LatMine(char arr[Hangs][Lies],int hang,int lie);
//排雷
void clearmine(char mine[Hangs][Lies],char show[Hangs][Lies], int hang, int lie);
game.c
#include"game.h"
//初始化棋盘
void InitBoard(char arr[Hangs][Lies],int hangs,int lies,char set)
{
int i = 0;
for (i = 0; i < hangs; i++)
{
int j = 0;
for (j = 0; j < lies; j++)
{
arr[i][j] = set;
}
}
}
//打印棋盘
void PrintBoard(char arr[Hangs][Lies],int hang,int lie)
{
int i = 0;
printf("\n");
printf("------扫雷游戏------");
printf("\n");
for (i = 0; i <= hang; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= hang; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= lie; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
//埋雷
void LatMine(char arr[Hangs][Lies],int hang,int lie)
{
int lei = EASY_COUNT;
while (lei)
{
int x = rand() % hang + 1;
int y = rand() % lie + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
lei--;
}
}
}
//计算选择坐标周围埋雷数目
int Count(char mine[Hangs][Lies], int x, int y)
{
return (mine[x - 1][y] + mine[x + 1][y] + mine[x - 1][y - 1]
+ mine[x - 1][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x][y - 1] - 8 * '0');
}
//排雷
void clearmine(char mine[Hangs][Lies], char show[Hangs][Lies], int hang, int lie)
{
int x = 0;
int y = 0;
int win = 0;
while (win < hang * lie - EASY_COUNT)
{
printf("请输入要排查的坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= hang && y >= 1 && y <= lie)
{
if (mine[x][y] == '1')
{
printf("你被雷炸死了\n");
PrintBoard(mine, Hang, Lie);
break;
}
else
{
int count = Count(mine, x, y);
show[x][y] = count + '0';
PrintBoard(show, Hang, Lie);
win++;
}
}
else
{
printf("坐标输入错误,请重新输入");
}
}
if (win == hang * lie - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
PrintBoard(mine, Hang, Lie);
}
}
test.c
#include"game.h"
void menu() //根据自己需求,可写可不写
{
printf("***********************\n");
printf("***** 1.play *****\n");
printf("***** 0.exit *****\n");
printf("***********************\n");
}
void game()
{
//构建棋盘
char mine[Hangs][Lies];
char show[Hangs][Lies];
//初始化棋盘
InitBoard(mine, Hangs, Lies, '0');
InitBoard(show, Hangs, Lies, '*');
//打印棋盘
//PrintBoard(mine, Hang, Lie);
//PrintBoard(show, Hang, Lie);
//埋雷
LatMine(mine, Hang, Lie);
//PrintBoard(mine, Hang, Lie);
//排雷
clearmine(mine, show, Hang, Lie);
}
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("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}