数组–扫雷
分装了三个工程
game.h
#ifndef __GAME_H__
#define __GAME_H__
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10 //设置游戏难度
void InitBoard(char arr[ROWS][ROWS], int rows, int cols, char set);
void DisplayBoard(char arr[ROWS][ROWS], int row, int col);
void SetMine(char arr[ROWS][ROWS], int row, int col);
void FindMine(char mine[ROWS][ROWS], char show[ROWS][ROWS], int row, int col);
int GetMineCount(char mine[ROWS][ROWS], char show[ROWS][ROWS], int x, int y);
#endif //__GAME_H__
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include"game.h"
void menu()
{
printf("*****************************\n");
printf("**** 欢迎进入扫雷游戏! *****\n");
printf("**** 1 .paly *****\n");
printf("**** 0. exit *****\n");
printf("*****************************\n");
}
void game()
{
char mine[ROWS][COLS] = { 0 };//'0' //创建的两个数组都要比实际看到的要大,会考虑到边界排雷的问题,害怕会数组越界
char show[ROWS][COLS] = { 0 };//'*'
InitBoard(mine, ROWS, COLS, '0');//初始化时数字字符
InitBoard(show, ROWS, COLS, '*');
//DisplayBoard(mine, ROW, COL); //打印的时候创建的虚拟边框就不要打印了
DisplayBoard(show, ROW, COL);
//布置雷
SetMine(mine, ROW,COL);
//DisplayBoard(mine, ROW, COL);//打印雷
//排雷
FindMine(mine, show,ROW, COL);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));//头文件#include<stdlib.h>
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戏退出\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (input);
system("pause");
return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"game.h"
void InitBoard(char arr[ROWS][ROWS], int rows, int cols,char set)
{
memset(&arr[0][0], set, rows*cols*sizeof(arr[0][0]));
}
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");//打印列号 在整个循环之前打印成一行 从0开始方便对齐。
for (i = 1; i <=row; i++)//注意i从一开始的理由
{
printf("%d ", i );//打印行号
for (j = 1; j <=col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
printf("\n");
}
//布置雷
//随机生成坐标,不止是十个有可能会随机生成重复的。
void SetMine(char arr[ROWS][ROWS], int row, int col)
{
int count = EASY_COUNT;
int rand();
while (count)
{
int x = rand() % row + 1;//注意不要把代码写死
int y = rand() % col+ 1;
//判断坐标有没有布置过雷
if (arr[x][y] == '0')
{
arr[x][y] ='1';
count--;
}
}
}
void FindMine(char mine[ROWS][ROWS], char show[ROWS][ROWS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while (win<row*col - EASY_COUNT)
{
printf("请输入坐标:>\n");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row&&y >= 1 && y <= col)
{
if (mine[x][y] =='1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine , ROW, COL);
break;
}
else
{
int count = GetMineCount(mine,show, x, y);
show[x][y] = count + '0'; //转换成字符数
DisplayBoard(show, ROW, COL);
win++;
}
//break; 不用跳出,你要一直排雷
}
else
{
printf("坐标输入有误,请重新输入:>\n");
}
}
if (win = row*col - EASY_COUNT)
{
printf("恭喜你排雷成功!请联系作者领取奖励\n");
}
}
int GetMineCount(char mine[ROWS][ROWS], char show[ROWS][ROWS], 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'; //减去字符0转换成对应的数字
}
关于测试
如何测试是否排雷成功
把雷阵打印出来 看着雷阵排查
例如 把雷弄成80 看着雷阵检测跳出循环的条件
扫雷扩展
1.第一次排雷不能炸死
2.扫雷可以展开一片,直到外围有雷,不要再展开。
没有雷就空格就好了。
此处的细节问题
细节问题特别多,要是一一写出来有些太过累赘,所以重要的地方加了说明。细节不写太详细主要是想让自己以后看的时候,自己独立回忆。
博客后续还会进行补充,把上述的两个扩展给完成。
小问题
这个随机函数 启发器还不太会用,我可能需要复习一下前面的博客了。害,忘得快啊!
复盘
扫雷陆陆续续写了很久,其实也不是很难。只是复杂,这两天事情确实比不上网课的时候事情多,但还是有时间刷剧的,所以不能拿这个当借口。偷懒就是偷懒了。
有的时候,你需要机会,在机会没有来的时候储备能力。机会来了,能力不行,你就谁也怪不了了。
前两天看到一个好玩的话
一天不写代码你自己知道
两天不写代码老师知道
三天不写代码老板知道
一直往后你的工资知道
我觉得再往后就是差距了