1.多文件创建
1.main.c:函数的调用
2.mine.c:扫雷函数的实现
3.mine.h:头文件,函数的声明,宏定义,头文件包含。
2.扫雷思路
1.创建多文件夹。(main.c、mine.c、mine.h)。
2.Menu()函数:提示玩家是玩游戏还是退出游戏。
3.main()函数,主函数,程序的入口。调用相关函数。
4.Game()玩游戏函数。
5.定义两个(N+2)(N+2)的二维数组。
6.初始化面板为
7.初始化雷盘为0
8.设置雷(系统随机设置)
9.排雷
10.判断结果
3.扫雷实现
3.1 main.c主函数源文件
3.1.1 Menu()函数
思路:Menu()函数:提示玩家是玩游戏还是退出游戏。
static void Menu()
{
printf("***************************\n");
printf("**1.玩游戏 2.退出游戏**\n");
printf("***************************\n");
}
3.1.2 main()函数,主函数,程序的入口。
思路:main()函数,主函数,程序的入口。
1.循环实现多次玩游戏。(这里应该是死循环,使用quit变量巧妙的控制退出和循环条件。)
2.调用菜单界面
3.玩家选择游戏方式
4.根据玩家选择方式,调用相关函数
int main()
{
int quit = 0;
//1.循环实现多次玩游戏
do{
//2.调用菜单界面
Menu();
//3.玩家选择游戏方式
int select = 0;
printf("请输入 1 or 2:\n");
scanf("%d",&select);
//4.根据玩家选择方式,调用相关函数
switch(select)
{
case 1:
printf("游戏开始!\n");
Game();
break;
case 2:
quit = 1;
printf("退出游戏!\n");
break;
default:
printf("输入有误,请重新输入:\n");
break;
}
}while(!quit);
system("pause");
return 0;
}
3.2 mine.c源文件
3.2.1 Game()玩游戏函数
思路:Game()玩游戏函数
1.定义两个(N+2)*(N+2)的二维数组。
2.初始化面板和初始化有雷的面板
3.设置雷
4.排雷
(1)排雷肯定不是一次就牌成功的,循环实现多次操作。注意循环条件:面板没雷的位置如果都排完了,那就排雷成功了。
(2)输入位置之前,需要给用户展示面板。让用户根据面板信息来输入坐标。
(3)输入x,y的坐标
(4)根据输入的坐标判断
--------------》
1.输入是否有误;2.输入是否被占用; 3.位置输入正确的情况下,判断该位置有雷还是没雷。有雷,那就被炸死了,退出循环;
没雷时,统计该位置周围8个位置中雷的个数。
(5)退出循环后判断游戏结果;
1.count>0;循环中break退出的,被雷炸死了
2.count<0;那就是正常循环退出,说明排雷成功了。
void Game()
{
//1.定义两个(N+2)*(N+2)的二维数组。
//(1)一个负责显示面板,全部用'*'表示;一个负责设置雷,用'1'代表有雷的位置,'0'代表没雷的位置
//(2)(N+2)*(N+2)是为了更方便统计周围雷的个数,这样可以保持周围和中间都统计8个位置。
char board[ROW][COL];
char mine[ROW][COL];
//2.初始化面板为*
InitBoard(board,ROW,COL,'*');
//3.初始化雷盘为0
InitBoard(mine,ROW,COL,'0');
//4.设置雷(系统随机设置)
srand((unsigned int)time(NULL));
SetMine(mine,ROW,COL);
//5.排雷
//count是面板可以填写数据的位置数量。MINENUM雷的个数
int count = (ROW-2)*(COL -2)-MINENUM;
//排雷--循环实现
do{
system("cls");
//6.输入位置之前,需要给用户展示面板。
ShowBoard(board,ROW,COL);
//7.输入x,y的位置
int x = 0;
int y = 0;
printf("请输入你所输入的位置:\n");
scanf("%d%d",&x,&y);
//8.判断你输入的位置是否有误或者被占用
//越界[1,10]--输入有误;'0'--统计周围雷的个数;'1'--被炸死了;!'*'--该地方已被占用
if(x<1||x>10||y<1||y>10){
printf("你输入的坐标有误,请重新输入:\n");
Sleep(1000);
continue;
}
//board[x][y]这块写x,y,是因为雷盘有效位置数组的下标是1-10.多了两行两列。
if(board[x][y]!='*'){
printf("你输入的位置已经被占用,请重新输入:\n");
Sleep(1000);
continue;
}
//到这一步,必然输入坐标是正确的,只有两种结果,该位置有雷,或者没雷
//有雷:被炸死;没雷,统计周围雷的个数
if(mine[x][y]=='0'){
char ret = GetNum(mine,x,y);//雷的个数类型定义为char,是为了和数组元素、雷的设置('0'没雷;'1'有雷)保持一直。
board[x][y]=ret;//将雷的个数显示在面板上,然后count--;
count--;
}else{
printf("你输入的位置有雷!x=%d, y=%d\n",x,y);
break;
}
}while(count>0);
//9.判断结果
if(count > 0){//循环break退出的。
printf("你被雷炸死了,\n");
}else//循环退出的
{
printf("扫雷成功!\n");
}
//结束后显示一下雷的面板
ShowBoard(mine,ROW,COL);
}
3.2.2 InitBoard()初始化面板函数
思路:InitBoard()初始化面板函数
1.遍历数组,将elem赋值给数组元素。
2.这里使用一个初始化函数,将面板和雷盘都给设置了。面板elem是’*‘;雷盘elem是’0’.('0’是没雷的)
void InitBoard(char board_mine[][COL],int row,int col,char elem)
{
//行0-----------------11
//列0-----------------11
int i = 0;
for(;i<row;i++){
int j = 0;
for(;j<col;j++){
board_mine[i][j] = elem;
}
}
}
3.2.3 SetMine()设置雷的个数
思路:SetMine()设置雷的个数
1.首先我应该传入的是雷的面板;
2.系统生成20个随机坐标,放置雷,注意坐标的范围是[1,10];
3.有雷的位置,设置成字符’1’;
void SetMine(char mine[][COL],int row,int col)
{
int n = MINENUM;
while(n){
//实际设置雷的二维数组是10*10的数组。
int x = rand()%(row-2)+1;
int y = rand()%(col-2)+1;
if(mine[x][y] == '1'){
continue;
}
mine[x][y] = '1';
n--;
}
}
3.2.4 GetNum()获取雷的个数
思路:GetNum()获取雷的个数
1.当你输入的位置正确,且该位置没雷时,统计该位置周围8个位置雷的个数,然后显示在该位置处。
2.要统计周围雷的个数,那一定传入的是雷的面板。
3.注意这块返回的类型是char类型。
4.由于’0’—>48;‘1’—>49
(1)mine[x-1][y-1] + mine[x-1][y] + mine[x-1][y+1] + mine[x][y-1] + mine[x][y+1] + mine[x+1][y-1] + mine[x+1][y] + mine[x+1][y+1]加起来都是十进制数;需要减去8*‘0’才得到实际的雷的个数,但这里是整形;应该再加上’0’,才得到的是字符。
(2)比如有四个’1’,四个’0’,那你计算就是:484+494-488 —》整数4;要想变成字符4,就再加48;
因此:- 7’0’而不是-8*‘0’(返回类型为char类型。)
char GetNum(char mine[][COL],int x,int y)
{
return mine[x-1][y-1] + mine[x-1][y] + mine[x-1][y+1] + \
mine[x][y-1] + mine[x][y+1] + \
mine[x+1][y-1] + mine[x+1][y] + mine[x+1][y+1] - 7*'0';
}
3.2.5 ShowBoard()显示面板函数
思路:ShowBoard()显示面板函数
1.这里使用一个显示面板函数,将面板或者雷盘显示出来。通过传入的二维数组不一致来区分是面板还是雷盘。
2.显示就是根据你设计的样式来遍历数组显示
3.注意要少两行两列,只显示中间的。
void ShowBoard(char board_mine[][COL],int row,int col)
{
printf("+---+---+---+---+---+---+---+---+---+---+---+\n");
int i = 0;
for(;i<=col-2;i++){
printf(" %-2d|",i);
}
printf("\n");
printf("+---+---+---+---+---+---+---+---+---+---+---+\n");
for(i=1;i<=row-2;i++){
printf(" %-2d| ",i);
int j = 1;
for(;j<col-2;j++){
printf(" %-2c|",board_mine[i][j]);
}
printf("\n");
for(j=1;j<=col-1;j++){
printf("%3s","+---");
}
printf("+\n");
}
}
3.3 mine.h头文件
#ifndef _MINE_H_
#define _MINE_H_
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <time.h>
#pragma warning(disable:4996)
#define ROW 12
#define COL 12
#define MINENUM 20;
void Game();
void InitBoard(char board_mine[][COL],int row,int col,char elem);
void SetMine(char mine[][COL],int row,int col);
char GetNum(char mine[][COL],int x,int y);
void ShowBoard(char mine[][COL],int row,int col);
#endif