一、扫雷游戏的讲解
首先扫雷游戏是一款益智类型大的游戏,玩家需要把所有的雷排查出来即可获得游戏的胜利,游戏即可胜利,反之,点开是雷则玩家输了游戏结束。
二、代码的设计思路
首先我们怎么存放这些数呢,因为我们是需要通过一个矩阵来存放这些数,我们可以用一些二维数组来进行存放这些数,但是一个二维数组肯定是不够的呢。因为刚开始棋盘是看不到雷的,是需要玩家一个一个排查的。所以,我们需要开两个二维数组。
开好两个二维数组我们就可以1把这两个数组初始化,但是一个函数只能初始化成一种数值那这怎么办呢,诶!这里我们可以多加一个参数这样不就可以用一个函数初始化两个不同的数组了吗!
我们定义mine和show这两个二维数组mine这个二维数组初始化为字符'0'这里是要为了和数字0做出区分,以为我们的点开了一个需要显示周围有几个雷。show这个二维数组可以初始化为'*'这个字符
接下来我们就要想一下怎么开始布置雷了,所以我们把雷定义为'1'这里要注意为了和数字1卓出区分我们需要把雷定义为字符'1',
紧接着,我们思考一下,我们翻格子的时候,如果这个格子不是雷,那么就会排查这个格子周围八个格子存在雷的个数,假设我们翻开左上角的格子的时候,但是该格子上面和左边没有格子了怎么办?那就会出现越界访问的情况,为了避免这个情况出现,我们只需要把9*9的格子扩张成11*11的格子就可以了,如图所示,这样遍历的时候就不会出现越界访问的情况了。
三、代码的实现
首先我们需要一个test.c的文件由于编写主程序,在需要一个test.h的头文件用于存放声明和定义的,还需要一个game.c的文件由于实现函数的实现。
首先我们需要一个菜单
void menu()
{
printf("***************************\n");
printf("******** 1.play **********\n");
printf("******** 0.exit **********\n");
printf("***************************\n");
}
void test()
{
int input = 0;
do
{
menu();
printf("请输入您要选择的选项>\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
再来我们需要函数,初始化棋盘
void IntyBorad(char arr[COLS][ROWS], int cols, int rows, char set)//由于初始化棋盘的函数
{
for (int i = 0; cols > i; i++)
{
int j = 0;
for (j = 0; rows > j; j++)
{
arr[i][j] = set;
}
}
}
我们需要一个函数看看里面是否都初始化来看看是初始化完成了
void ShowBorad(char arr[COLS][ROWS], int col, int row)
{
printf("__________扫雷游戏__________扫雷游戏_________\n");
for (int i = 1; i <= col; i++)
{
if (i <= 1)
{
printf(" ");
}
printf(" ");
printf("%d", i);
}
printf("\n");
for (int i = 1; i <= col; i++)
{
printf("%d", i);
int j = 0;
for (j = 1; j <= row; j++)
{
printf("%3c", arr[i][j]);
}
printf("\n");
}
printf("__________扫雷游戏__________扫雷游戏_________\n");
}
布置雷的函数
void DictBorad(char arr[COLS][ROWS], int col, int row)
{
int count = EASYCOUNT;
while (count)
{
int x = rand() % COL + 1;
int y = rand() % ROW + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
排查雷,加上判断输赢
void FindBorad(char mine[COLS][ROWS], char show[COLS][ROWS], int col, int row)
{
int x = 0;
int y = 0;
int win = 0;
int count = 0;
while (win<COL*ROW-EASYCOUNT)
{
printf("请输入坐标>\n");
scanf("%d,%d", &x, &y);
if (x<1&&x > col &&y<1&& y > row)
{
printf("输入坐标非法,请重新输入>\n");
}
else
{
if (show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("很遗憾,您输了>\n");
ShowBorad(mine, COL, ROW);//打印棋盘内容
break;
}
else
{
int count = GetMineCount(mine, x, y);
show[x][y] = count + 0;
ShowBorad(show, COL, ROW);
win++;
}
}
else
{
printf("该坐标已被排查,请重新输入!!!>\n");
}
}
}
if (win == COL * ROW - EASYCOUNT)
{
printf("恭喜您赢啦!!!>\n");
}
}
统计周围有几个雷
int GetMineCount(char mine[COLS][ROWS], int x, int y)
{
return mine[x][y] + mine[x][y - 1] + mine[x][y + 1]
+ 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 - 1][y] - '0' * 8;
}
四、完整代码
源文件test.c(主程序)
#include"test.h"
void game()
{
srand((unsigned int)time(NULL));
char mine[COLS][ROWS] = { 0 };
char show[COLS][ROWS] = { 0 };
IntyBorad(mine, COLS, ROWS, '0');//初始化棋盘内容
IntyBorad(show, COLS, ROWS, '*');//初始化棋盘表面内容
ShowBorad(mine,COL,ROW);//打印棋盘内容
ShowBorad(show, COL, ROW);//初始化棋盘表面内容
DictBorad(mine, COL, ROW);//布置雷
ShowBorad(mine, COL, ROW);//打印棋盘内容
FindBorad(mine,show, COL, ROW);//排查雷
}
void menu()
{
printf("***************************\n");
printf("******** 1.play **********\n");
printf("******** 0.exit **********\n");
printf("***************************\n");
}
void test()
{
int input = 0;
do
{
menu();
printf("请输入您要选择的选项>\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
test.h的头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define COL 9
#define ROW 9
#define EASYCOUNT 10
#define COLS COL+2
#define ROWS ROW+2
void IntyBorad(char arr[COLS][ROWS],int cols, int rows, char set);//初始化棋盘
void ShowBorad(char arr[COLS][ROWS], int col, int row);//打印棋盘
void DictBorad(char arr[COLS][ROWS], int col, int row);//布置雷
void FindBorad(char mine[COLS][ROWS],char show[COLS][ROWS],int col,int row);//排查雷
game.c的源文件(用于实现函数)
#include"test.h"
void IntyBorad(char arr[COLS][ROWS], int cols, int rows, char set)
{
for (int i = 0; cols > i; i++)
{
int j = 0;
for (j = 0; rows > j; j++)
{
arr[i][j] = set;
}
}
}
void ShowBorad(char arr[COLS][ROWS], int col, int row)
{
printf("__________扫雷游戏__________扫雷游戏_________\n");
for (int i = 1; i <= col; i++)
{
if (i <= 1)
{
printf(" ");
}
printf(" ");
printf("%d", i);
}
printf("\n");
for (int i = 1; i <= col; i++)
{
printf("%d", i);
int j = 0;
for (j = 1; j <= row; j++)
{
printf("%3c", arr[i][j]);
}
printf("\n");
}
printf("__________扫雷游戏__________扫雷游戏_________\n");
}
void DictBorad(char arr[COLS][ROWS], int col, int row)
{
int count = EASYCOUNT;
while (count)
{
int x = rand() % COL + 1;
int y = rand() % ROW + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
int GetMineCount(char mine[COLS][ROWS], int x, int y)
{
return mine[x][y] + mine[x][y - 1] + mine[x][y + 1]
+ 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 - 1][y] - '0' * 8;
}
void FindBorad(char mine[COLS][ROWS], char show[COLS][ROWS], int col, int row)
{
int x = 0;
int y = 0;
int win = 0;
int count = 0;
while (win<COL*ROW-EASYCOUNT)
{
printf("请输入坐标>\n");
scanf("%d,%d", &x, &y);
if (x<1&&x > col &&y<1&& y > row)
{
printf("输入坐标非法,请重新输入>\n");
}
else
{
if (show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("很遗憾,您输了>\n");
ShowBorad(mine, COL, ROW);//打印棋盘内容
break;
}
else
{
int count = GetMineCount(mine, x, y);
show[x][y] = count + 0;
ShowBorad(show, COL, ROW);
win++;
}
}
else
{
printf("该坐标已被排查,请重新输入!!!>\n");
}
}
}
if (win == COL * ROW - EASYCOUNT)
{
printf("恭喜您赢啦!!!>\n");
}
}