1、核心思想:
1.1:数组创建
需要两个数组,一个用来布置雷mine[RAWS][COLS],一个用来显示扫雷信息show[RAWS][COLS].
1.2:扫雷信息显示
如何扫雷呢,只要将你要扫的地方的附近的八个位置有几个雷放置在显示扫雷信息的数组中就可以了,如图1-1。
图1-1
1.3:常量的具体使用
在写扫雷这个程序的时候,我的的确确感受到了常量的重要性。在改变数组的大小时,只需要改常量就可以了,而不需要将每个参数都进行更改,如果没有常量,这个过程将十分痛苦。
2、实现过程
2.1:大概流程
建立新的工程文件,建立新的主函数,在主函数中调用test()方法来逐步完善这个程序,在tes()方法中调用game()方法,game()是整个游戏的逻辑实现,在其中创建两个数组,一个用来放置雷,一个用来显示扫雷信息,然后创建一个给数组初始化的方法InitArray,分别给这两个两个数组进行初始化,然后创建一个打印数组的方法,来显示扫雷的结果,然后创建最重要的扫雷方法,现在就需要用到上面这个我自己画的很丑的图了,将这八个格子中的所有字符加起来然后减去8 * '0',然后将这个数字返回去,将扫雷信息的数组更新,当猜玩71个格子的时候,游戏结束。如图2-1所示。
2.2:自顶向下,逐步求精
主函数是程序的入口,然后调用test,在test函数中定义并初始化两个数组,调用game函数,在用户没有要选择退出的时候,一直执行menu函数和FindMine函数,menu负责控制用户是否继续游玩游戏,而FindMine是这个游戏的核心所在,在猜到炸弹时,游戏结束,并通过Display函数来打印真正的地雷在哪里,如果没有猜到炸弹时,调用CountMine来统计炸弹的个数,并且将炸弹的个数返回来,将这个返回的数字放到玩家猜的那个地方上,并且打印show中的每个元素,然后继续玩,当猜对元素数减去炸弹数的时候,游戏结束,打印游戏胜利了
3、代码实现
3.1:main函数
int main(void)
{
test();
return 0;
}
3.2:test函数
void test(void)
{
int choice;
do
{
menu();
printf("请输入你的选择:");
scanf("%d", &choice);
switch (choice)
{
case 1:
game();
break;
case 0:
break;
default:
printf("请输入合理的数字!!!\n");
break;
}
} while (choice);
}
3.3:InitBoard函数
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char flag)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
arr[i][j] = flag;
}
}
}
3.4:DisplayBoard函数
void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
printf("------扫雷游戏-----\n");
for (i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
3.5:SetMine函数
void SetMine(char arr[ROWS][COLS], int num)
{
srand((unsigned int)time(NULL));
int x = 0;
int y = 0;
while (num)
{
x = rand() % 9 + 1;
y = rand() % 9 + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
num--;
}
}
}
3.6:FindMine函数
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x, y;
int ch;
int num = (COL * ROW - MINENUM);
while (num)
{
printf("请输入坐标(用空格隔开):");
scanf("%d %d", &x, &y);
if ('*' == show[x][y])
{
if ('1' == mine[x][y])
{
printf("你被炸死了,游戏结束\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
ch = SurroundMine(show,mine, x, y);
show[x][y] = ch + '0';
DisplayBoard(show, ROW, COL);
num--;
}
}
else
{
printf("请输入合法的坐标!!!!\n");
}
}
if (0 == num)
{
printf("游戏胜利了\n");
}
}
4、完整代码:
4.1:game.h
#define _CRT_SECURE_NO_WARNINGS 1;
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define COL 9
#define ROW 9
#define COLS COL + 2
#define ROWS ROW + 2
#define MINENUM 10
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char flag);
void DisplayBoard(char arr[ROWS][COLS], int row, int col);
void SetMine(char arr[ROWS][COLS], int num);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int SurroundMine(char show[ROWS][COLS], char arr[ROWS][COLS], int x, int y);
4.2:game.c
#define _CRT_SECURE_NO_WARNINGS 1;
#include "game.h"
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char flag)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
arr[i][j] = flag;
}
}
}
void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
printf("------扫雷游戏-----\n");
for (i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
void SetMine(char arr[ROWS][COLS], int num)
{
srand((unsigned int)time(NULL));
int x = 0;
int y = 0;
while (num)
{
x = rand() % 9 + 1;
y = rand() % 9 + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
num--;
}
}
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x, y;
int ch;
int num = (COL * ROW - MINENUM);
while (num)
{
printf("请输入坐标(用空格隔开):");
scanf("%d %d", &x, &y);
if ('*' == show[x][y])
{
if ('1' == mine[x][y])
{
printf("你被炸死了,游戏结束\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
ch = SurroundMine(show,mine, x, y);
show[x][y] = ch + '0';
DisplayBoard(show, ROW, COL);
num--;
}
}
else
{
printf("请输入合法的坐标!!!!\n");
}
}
if (0 == num)
{
printf("游戏胜利了\n");
}
}
int SurroundMine(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y)
{
//检测周围八个区域的地雷数
return mine[x - 1][y] +
mine[x - 1][y - 1] +
mine[x][y - 1] +
mine[x + 1][y - 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] +
mine[x][y + 1] +
mine[x - 1][y + 1] - (8 * '0');
}
4.3:test.c
#define _CRT_SECURE_NO_ARNINGS 1;
#include "game.h"
void test(void);//测试程序
void game(void);
void menu(void);//打印菜单
int main(void)
{
test();
return 0;
}
void test(void)
{
int choice;
do
{
menu();
printf("请输入你的选择:");
scanf("%d", &choice);
switch (choice)
{
case 1:
game();
break;
case 0:
break;
default:
printf("请输入合理的数字!!!\n");
break;
}
} while (choice);
}
void menu(void)
{
printf("****************************\n");
printf("* 1.play *\n");
printf("* 0.exit *\n");
printf("****************************\n");
}
void game(void)
{
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
//初始化数组
InitBoard(mine, ROW, COL, '0');
InitBoard(show, ROW, COL, '*');
//放置雷
SetMine(mine, MINENUM);
//打印数组
DisplayBoard(show, ROW, COL);
//DisplayBoard(mine, ROW, COL);
//扫雷
FindMine(mine, show, ROW, COL);
}
5、总结
这是我自己写的,看了好几遍,感觉还是太巧妙了,一个小小的扫雷游戏却让我受益了好多,独立思考,自顶向下,逐步求精的方法确实可以在解决问题的时候帮助到我!