目录
头文件和源文件:
首先由于扫雷代码量要多余100行,为了提高代码的可读性需要将代码分入3个文件!
头文件:game.h 原文件:game.c play.c
好了现在开始吧:
扫雷的逻辑认识:
- 分文件(需要自己了解)
- 设置框架运行
- 设置棋盘
- 数组初始化showboard,board.
- 一个用来打印 *
- 一个用来统计0和1
- 设置随机数rand
- 设置统计函数find
- 将函数整合,运行
开始:
设置基本运行框架,这里肯定有兄弟会想到之前写过的猜数字游戏运行方式。两者的运行框架差不多。首先需要一个进入游戏的while循环以及选择的switch。但是在进入循环选择之前需要打印选择的菜单。这里我们通过函数实现:
void menu()
{
printf("****欢迎进入扫雷****\n");
printf("*******1.play*******\n");
printf("*******2.exit*******\n");
printf("********************\n");
}
现在有了目录我们开始在运行源文件中构造游戏框架
int main()
{
int intput;
do
{
menu();
scanf("%d", &intput);
switch (intput)
{
case 1:
printf("欢迎进入扫雷游戏\n");
game();
break;
case 2:
printf("再见\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (intput != 2);
return 0;
}
代码解释:在游戏运行前我们要打印出菜单供玩家选择,再选择之后,我们用switch选择语句和目录中的选项相对应。同时为了让玩家可以反复玩该游戏我们选择do...while 语句。
创建2维数组:
接下来我们要完善game()函数的内容
首先我们要创建棋盘:扫雷棋盘有列和行,而我们学过2维数组就有列和行,因此我们可以通过对2维数组的编译和打印来实现游戏。
我们创建9*9的棋盘在头文件中进行定义:
#define CLOW 9
#define LINE 9
#define CLOW2 CLOW+2
#define LINE2 LINE+2
//定义数组
char playarr[CLOW2][LINE2];
char showarr[CLOW2][LINE2];
同时为了在统计棋盘边界的雷时不越界访问我们要在原有的棋盘边界再围一圈,因此我们要定义一个11*11的数组。通过宏定义CLOW和LINE,为了方便更改我们定义CLOW2时与CLOW相联系。
这里我们要定义两个数组,playarr数组用来统计,showarr用来展现。
数组的初始化:
通过函数进行初始化
void board(char arr[CLOW2][LINE2], int clow, int line, char i)
{
int x, y;
for (x = 0; x <= clow; x++)
{
for (y = 1; y <= clow; y++)
{
arr[x][y] = i;
}
}
}
2维数组传参时需要对列数进行定义,但是在传参时传入的是首元素的地址,所以这并不影响我们对数组的定义。同事为了让棋盘被包围我们要定义下标1到9的元素。写好函数后要在头文件中进行声明。
将playarr数组中元素初始化为0;将showarr数组中元素初始化为*
棋盘打印:
通过for循环函数进行打印这是很常见的操作,但是我们也要在打印时要在第一行和每一行的开始打印坐标数。
void print(char arr[CLOW2][LINE2], int clow, int line)
{
int x, y;
for (x = 0; x <= line; x++)
{
printf("%d ", x);
}
printf("\n");
for (x = 1; x <= line; x++)
{
printf("%d ", x);
for (y = 1; y <= line; y++)
{
printf("%c ", arr[x][y]);
}
printf("\n");
}
}
设置雷的坐标(生成随机数):
void RAND(char arr[CLOW2][LINE2], int clow, int line)
{
int cout = 10;
while (cout)
{
int x = 1 + rand() % clow;
int y = 1 + rand() % line;
if (arr[x][y]== '0')
{
arr[x][y] = '1';
cout--;
}
}
}
在playarr数组中生成雷,将雷设置为1
注意:这里的x和y的生成一定要在while循环内,如果在外面将因为x和y的固定导致死循环。
统计雷:
通过对相应坐标的周围元素进行统计从而统计出雷的个数:
int ADD(char arr[CLOW2][LINE2], int clow, int line )
{
int x, y,cout=0;
for (x = clow - 1; x <= clow + 1; x++)
{
for (y = line - 1; y <= line + 1; y++)
{
if(arr[x][y]=='1')
cout++;
}
}
return cout+48;
}
这里我们用for循环进行统计,同时我们要在showarr数组中显示统计的雷的个数,
注意:我们的返回值要最终要以char类型进行展现,因此我们的返回值要加48(0的ascall码值)表示相应char类型时的数字。
游戏运行:
void PLAY(char arr[CLOW2][LINE2],char arr2[CLOW2][LINE2])
{
int x, y;
while (1)
{
printf("请输入你选择的坐标>");
scanf("%d%d", &x, &y);
if (arr[x][y] == '0')
{
int cout = ADD(playarr, x, y);
showarr[x][y] = (char)cout;
print(arr2, CLOW, LINE);
}
else
{
printf("你输啦\n");
print(arr, CLOW, LINE);
break;
}
}
}
在每一次我们都要输入一次坐标,同时判断该元素在playarr中是不是雷。不是,就要对雷进行统计
并传到showarr数组;是,就结束游戏。
注意:这里我并没有设置胜利条件。
整合运行:
void game()
{
srand((unsigned)time(NULL));
board(playarr, CLOW, LINE, '0');
board(showarr, CLOW, LINE, '*');
RAND(playarr, CLOW, LINE);
print(showarr, CLOW, LINE);
PLAY(playarr, showarr);
}
继续坚持!!!!
全部代码:
头文件:
#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
//定义数
#define CLOW 9
#define LINE 9
#define CLOW2 CLOW+2
#define LINE2 LINE+2
//定义数组
char playarr[CLOW2][LINE2];
char showarr[CLOW2][LINE2];
//函数声明
void menu();
void game();
void board(char arr[CLOW2][LINE2], int clow, int line, char i);
void print(char arr[CLOW2][LINE2], int clow, int line);
void RAND(char arr[CLOW2][LINE2], int clow, int line);
int ADD(char arr[CLOW2][LINE2], int clow, int line);
void PLAY(char arr[CLOW2][LINE2], char arr2[CLOW2][LINE2]);
源文件:
函数实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//菜单
void menu()
{
printf("****欢迎进入扫雷****\n");
printf("*******1.play*******\n");
printf("*******2.exit*******\n");
printf("********************\n");
}
//初始化
void board(char arr[CLOW2][LINE2], int clow, int line, char i)
{
int x, y;
for (x = 0; x <= clow; x++)
{
for (y = 1; y <= clow; y++)
{
arr[x][y] = i;
}
}
}
//打印
void print(char arr[CLOW2][LINE2], int clow, int line)
{
int x, y;
for (x = 0; x <= line; x++)
{
printf("%d ", x);
}
printf("\n");
for (x = 1; x <= line; x++)
{
printf("%d ", x);
for (y = 1; y <= line; y++)
{
printf("%c ", arr[x][y]);
}
printf("\n");
}
}
//设置雷
void RAND(char arr[CLOW2][LINE2], int clow, int line)
{
int cout = 10;
while (cout)
{
int x = 1 + rand() % clow;
int y = 1 + rand() % line;
if (arr[x][y]== '0')
{
arr[x][y] = '1';
cout--;
}
}
}
//计算雷
int ADD(char arr[CLOW2][LINE2], int clow, int line )
{
int x, y,cout=0;
for (x = clow - 1; x <= clow + 1; x++)
{
for (y = line - 1; y <= line + 1; y++)
{
if(arr[x][y]=='1')
cout++;
}
}
return cout+48;
}
//进行部分
void PLAY(char arr[CLOW2][LINE2],char arr2[CLOW2][LINE2])
{
int x, y;
while (1)
{
printf("请输入你选择的坐标>");
scanf("%d%d", &x, &y);
if (arr[x][y] == '0')
{
int cout = ADD(playarr, x, y);
showarr[x][y] = (char)cout;
print(arr2, CLOW, LINE);
}
else
{
printf("你输啦\n");
print(arr, CLOW, LINE);
break;
}
}
}
void game()
{
srand((unsigned)time(NULL));
board(playarr, CLOW, LINE, '0');
board(showarr, CLOW, LINE, '*');
RAND(playarr, CLOW, LINE);
print(showarr, CLOW, LINE);
PLAY(playarr, showarr);
}
框架运行:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
int main()
{
int intput;
do
{
menu();
scanf("%d", &intput);
switch (intput)
{
case 1:
printf("欢迎进入扫雷游戏\n");
game();
break;
case 2:
printf("再见\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (intput != 2);
return 0;
}