二维数组应用(扫雷)

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

4.运行结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值