学习写代码是为了完成某些事情,无论是循环还是判断语句都是为了去实现某些功能,接下来,我将详细的描述如何去写出一个9×9,包含10个雷的扫雷游戏。
这个游戏的规则是这样的,当我们进入这个游戏,我们输入一个坐标,电脑会判断这个坐标是否为雷,如果是雷,那么游戏结束,如果不是雷,那么游戏继续且显示出当前坐标附近八个坐标有几个雷。当场上只剩下雷的坐标,那么游戏胜利。
首先,为了让玩家自由选择是否开始游戏,我们可以先写出一个函数,让代码刚开始先打印出一个菜单,这个菜单会告诉玩家1是开始游戏,0是结束游戏。
void menu()
{
printf("*****************************\n");
printf("****** PLAY:1 *********\n");
printf("****** EXIT:0 *********\n");
printf("*****************************\n");
}
接着,我们便写出主函数。我们先初始化一个int input = 0;我们要无限的玩这个游戏,所以我们需要使用到while语句,而且我们至少需要进行一次循环,来让判断的input作用于switch语句,所以我们使用do while循环。
我们需要写出一个判断语句来让电脑知道玩家开不开始游戏,1代表游戏开始而0代表游戏结束,我们便自然而然的想到了switch语句,当玩家选择1时候,我们游戏开始,当玩家选择0的时候,游戏结束,当玩家输入其他数字的时候,我们可以打印一句话,提醒玩家重新选择。
int main()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
printf("----扫雷游戏即将开始!-------\n");
game();
break;
case 0:
printf("Game Over!\n");
break;
default:
printf("You print the wrong digit!\n");
break;
}
} while (input);
return 0;
}
当主函数写完以后,我们便需要开始考虑这个游戏的核心,也就是game函数部分了。
首先,为了实现功能,我们先定义雷的数量为10,初始化两个二维数组,一个数组arr1用来存放雷,一个arr2数组用来显示,而这个棋盘的大小,我们可以用Hang来表示行,用Lie来表示列,Hang和Lie我们会多次使用,且日后为了扩展扫雷游戏,所以我们把他放在头文件里面。于是,理论上我们的Hang和Lie就是9。但是,我们这样这样子定义,在后面判断坐标附近有几个雷的时候,四边的雷会检测超过当前内存的地区,导致报错。为了解决这个问题,我们可以给四条边多向外扩展一排,于是便可以这样写
#define Hang 9
#define Lie 9
#define HangPlus Hang + 2
#define LiePlus Lie + 2
#define BOME 10
而初始化数组我们需要放在game函数里头写。
char arr1[HangPlus][LiePlus];
char arr2[HangPlus][LiePlus];
当数组初始化以后,我们便需要在数组里面放东西了。为了方便,我们用1代表雷,用0代表不是雷,注意,在这里面,1和0都不是数字,他们是字符。我们在arr1里面放满0,在arr2里面放满*,我们不需要在最外侧的0和10列,0和10行放0或*,所以,我们只需要这样写
在game函数里面这样
Initboard(arr1, '0', HangPlus, LiePlus);
Initboard(arr2, '*', HangPlus, LiePlus);
在game文件里面我们这么写
void Initboard(char board[HangPlus][LiePlus], char set,int hang ,int lie)//不能与关键字重名
{
int i = 0;
for (int i = 0; i < hang; i++)
{
for (int j = 0; j < lie; j++)
{
board[i][j] = set;
}
}
set让我们可以自由选择放进去什么字符,操作起来更自由。
在实现数组完全初始化以后,我们便可以开始选择先放雷或者先显示一次arr2棋盘的样子,我们这便选择先写Bome函数
Bome函数要实现的是在9×9的棋盘里面随机放10个雷,所以我们还是得使用前面学到的scrand()和时间戳知识来实现随机数,scrand()函数就放在主函数里面。
我们定义一个count文件等于BOME,定义x与y来确定雷的坐标,x与y皆需要通过随机数选出,x = rand()%Hang + 1;y也是同样意思,这样我们就可以得到随机的x,y值了。为了重复布雷,我们再写一个if判断语句来避免这种情况出现。
void Bome(char board[HangPlus][LiePlus], int hang, int lie)
{
int count = BOME;
while(count)
{
int x = rand() % hang + 1;
int y = rand() % lie + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
在布完雷以后,我们便开始打印出arr2棋盘,为了实现视觉上的美观,我们将棋盘打印成第一行与第一列都是0~9,让玩家更好的进行坐标锁定。接着就是很正常的利用for循环打印二维数组啦
void Display(char board[HangPlus][LiePlus], int hang, int lie)
{
for (int i = 0; i <= hang; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= lie; i++)
{
printf("%d ", i);
for (int j = 1; j <= hang; j++)
{
printf("%c ",board[i][j]);
}
printf("\n");
}
}
在我们的目标中,当我们选择一个坐标以后,我们便会得到这个坐标附近有几个雷,这个功能我们也可以通过一个函数实现,由于我们数组里面的0和1都是字符,所以我们需要针对的是他们的ASCII值进行计算的这个函数需要一个int的返回值,于是我们可以这样子写
int GetBome(char board[HangPlus][LiePlus], int x, int y)
{
return(board[x][y - 1] + board[x][y + 1] + board[x + 1][y] + board[x + 1][y - 1] + board[x][y + 1] + board[x - 1][y] + board[x - 1][y + 1] + board[x - 1][y - 1] - 7 * '0');
}
到最后,就是我们最重要的找雷函数了,这个函数在前面函数已经写好的情况下并不算很难,只需要注意控制坐标的范围以及胜利的条件就行
void FindBome(char arr1[HangPlus][LiePlus], char arr2[HangPlus][LiePlus],int hang, int lie)
{
int x = 0;
int y = 0;
int win = 0;
while (win < (hang * lie - BOME))
{
printf("请输入要排查的坐标:");
scanf("%d,%d", &x, &y);
if (x >= 1 && x <= hang && y >= 1 && y <= lie)
{
if (arr1[x][y] == '1')
{
printf("你死了\n");
Display(arr1, Hang, Lie);
break;
}
else
{
arr2[x][y] = GetBome(arr1, x, y);
Display(arr2, Hang, Lie);
win++;
}
}
else
{
printf("你输入了一个错误坐标!\n");
}
}
if (win == hang * lie - BOME)
{
printf("你赢了\n");
Display(arr1, Hang, Lie);
}
}
于是经过这一串的代码,我们便写好了这个游戏。
game头文件
#pragma once
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define Hang 9
#define Lie 9
#define HangPlus Hang + 2
#define LiePlus Lie + 2
#define BOME 10
void Initboard(char board[HangPlus][LiePlus], char set, int hang, int lie);
void Bome(char board[HangPlus][LiePlus], int hang, int lie);
void Display(char board[HangPlus][LiePlus], int hang, int lie);
void FindBome(char arr1[HangPlus][LiePlus], char arr2[Hang][Lie], int hang, int lie);
game游戏文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void Initboard(char board[HangPlus][LiePlus], char set,int hang ,int lie)//不能与关键字重名
{
int i = 0;
for (int i = 0; i < hang; i++)
{
for (int j = 0; j < lie; j++)
{
board[i][j] = set;
}
}
}
void Bome(char board[HangPlus][LiePlus], int hang, int lie)
{
int count = BOME;
while(count)
{
int x = rand() % hang + 1;
int y = rand() % lie + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
void Display(char board[HangPlus][LiePlus], int hang, int lie)
{
for (int i = 0; i <= hang; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= lie; i++)
{
printf("%d ", i);
for (int j = 1; j <= hang; j++)
{
printf("%c ",board[i][j]);
}
printf("\n");
}
}
int GetBome(char board[HangPlus][LiePlus], int x, int y)
{
return(board[x][y - 1] + board[x][y + 1] + board[x + 1][y] + board[x + 1][y - 1] + board[x + 1][y + 1] + board[x - 1][y] + board[x - 1][y + 1] + board[x - 1][y - 1] - 7 * '0');
}
void FindBome(char arr1[HangPlus][LiePlus], char arr2[HangPlus][LiePlus],int hang, int lie)
{
int x = 0;
int y = 0;
int win = 0;
while (win < (hang * lie - BOME))
{
printf("请输入要排查的坐标:");
scanf("%d,%d", &x, &y);
if (x >= 1 && x <= hang && y >= 1 && y <= lie)
{
if (arr1[x][y] == '1')
{
printf("你死了\n");
Display(arr1, Hang, Lie);
break;
}
else
{
arr2[x][y] = GetBome(arr1, x, y);
Display(arr2, Hang, Lie);
win++;
}
}
else
{
printf("你输入了一个错误坐标!\n");
}
}
if (win == hang * lie - BOME)
{
printf("你赢了\n");
Display(arr1, Hang, Lie);
}
}
主函数文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("*****************************\n");
printf("****** PLAY:1 *********\n");
printf("****** EXIT:0 *********\n");
printf("*****************************\n");
}
void game()
{
char arr1[HangPlus][LiePlus];
char arr2[HangPlus][LiePlus];
Initboard(arr1, '0', HangPlus, LiePlus);
Initboard(arr2, '*', HangPlus, LiePlus);
Display(arr2, Hang, Lie);
Bome(arr1,Hang,Lie);
FindBome(arr1, arr2, Hang,Lie);
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
printf("----扫雷游戏即将开始!-------\n");
game();
break;
case 0:
printf("Game Over!\n");
break;
default:
printf("You print the wrong digit!\n");
break;
}
} while (input);
return 0;
}