二维数组应用——扫雷

C语言实现简单扫雷小游戏

游戏简介:

电脑随机设置10个雷,用户输入坐标,若坐标下是雷则结束游戏,不是则该位置显示周围的雷数。

game.h
#ifndef __GAME_H__ 
#define __GAME_H__ 
#include<stdio.h> 
//设置屏幕显示的雷盘的大小
#define ROW 9 
#define COL 9 

//设置实际雷盘的大小(判断雷数是看用户所选的坐标周围八个坐标内是否设雷,但若是用户选择的坐标是位于雷盘四周,则会数组访问越界,所以行和列都要多设两行)
#define ROWS ROW+2 
#define COLS COL+2 

//设置雷的数量
#define MINE_NUM 10 

#include<stdlib.h> 
#include<time.h> 
//初始化雷盘 
void IntiBoard(char board[][ROWS], int row, int col, char set);
//打印雷盘
void Show(char board[][ROWS], int row, int col);
//设置雷的位置
void SetMine(char board[][ROWS], int row, int col);
//找雷
void FindMine(char Mine[][ROWS], char MineInfo[][ROWS], int row, int col);
#endif
test.c
#define _CRT_SECURE_NO_WARNINGS 1 
#include"game.h" 
//游戏菜单打印
void menu()
{ 
	printf("********0.exit********\n");
	printf("********1.play********\n");
	printf("**********************\n");
}
//进入游戏
void game()
{
	char Mine[ROWS][COLS] = { 0 };//后台设置雷的情况
	IntiBoard(Mine, ROWS, ROWS,'0');//0为未设雷,1为设雷,先置为全0

	char MineInfo[ROWS][COLS] = { 0 };//用来展示给用户看的雷盘
	IntiBoard(MineInfo, ROWS, ROWS, '*');//将该雷盘全置为*
	Show(MineInfo, ROWS, ROWS);//打印雷盘

	SetMine(Mine, ROW, ROW);//设置雷

	FindMine(Mine,MineInfo, ROW, ROW);//用户找雷
}

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入您的选择-->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("游戏开始,玩的开心呦~~~\n");
			game();//进入游戏
			break;
		case 0:
			printf("游戏退出\n");
			break;
		default:
			printf("请输入正确的操作");
			break;
		}
	} while (input);//循环至少执行一次
	return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//将雷盘元素重置为char set
void IntiBoard(char board[][ROWS], int row, int col, char set)
{
	int i = 0;
	int j = 0;
	//遍历数组
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = set;
		}
	}
}

void Show(char board[][ROWS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("-------------------------------\n");
	for (i = 0; i < row - 1; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	//遍历数组,打印
	for (i = 1; i < row - 1; i++)
	{
		printf("%d ", i);
		for (j = 1; j < col - 1; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("-------------------------------\n");
}

void SetMine(char board[][ROWS], int row, int col)
{
	int x;
	int y;
	int count = 0;
	//系统随机设置10个范围在1~9的x,y值,即随机找十个雷的坐标
	srand((unsigned)time(NULL));
	for (int i = 0; i < MINE_NUM; i++)
	{
		x = rand() % row +1;
		y = rand() % row +1;
		board[x][y] = '1';
		count++;
	}
}
//字符'1' - 字符'0' = 数字1,坐标值都为字符,所以要转化为数字要加字符‘0’
int MineCount(char Mine[][ROWS], 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])-(8*'0');
}
//找雷
void FindMine(char Mine[][ROWS], char MineInfo[][ROWS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = MINE_NUM;//用来控制循环
	int countmine = 0;
	//循环当中踩到雷退出循环,游戏结束,未踩到雷count--,直至雷全找完,此时游戏胜利
	while (count != 0)
	{
		printf("请输入坐标:");
		scanf("%d%d", &x, &y);
		//判断用户输入是否合法,不合法重新输入坐标,合法则判断当前坐标下是否有雷,有雷游戏结束,没雷count--,游戏继续
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (Mine[x][y] == '1')
			{
				printf("Boom!你被炸了!\n");
				Show(Mine, ROWS, ROWS);
				break;
			}
			else
			{
				countmine = MineCount(Mine, x, y);
				MineInfo[x][y] = countmine + '0';
				Show(MineInfo, ROWS, ROWS);
				count--;
			}
		}
		else
		{
			printf("坐标不合法,请重新输入");
		}

易错点

  • 该雷盘打印时是%c打印,后期检查雷的个数时应返回整型,所以中间转换需要知道:‘某数字’-字符’0’=该数字的整型
  • 数组越界怎么办 由于要统计当前所选坐标周围的雷数,要考虑当用户将坐标选在数组边缘或四个角的位置该如何统计,此时需要给数组上下左右各扩充一行,设置初值时设为0,打印时只打印中间部分,(如11*11的数组只打印1~9列/行,第0行/列和第10列/行充当安全区域),这样在统计雷时数组便不会越界。

猜你喜欢

转载自blog.csdn.net/qq_43360037/article/details/97697689
今日推荐