如何写出一个简易版扫雷代码?

目录

一,说明

二,逐层构思

1,游戏菜单界面

2,游戏地图的创建     

 3,地图的打印(显示)

4,雷的分布 

 5,显示周围雷数

6,雷的排查

三,代码展示 

1,代码的声明(头文件)

2,代码的调用(源文件)

3,代码的描述(实现)(源文件


一,说明

    简易版扫雷中,我们用坐标来代替鼠标点击的位置,并且仅仅展示该点周围雷数(大家可以通过学习自行拓展)。算是低配版。

      为了代码分工明确、清晰、有条理,代码位置分为了三部分:game.h(预处理及代码的声明)、test.c(代码的调用)、game.c(代码的描述)。

    大部分操作都实现为一个函数,方便随时调用,且定义都放在头文件里。

说明结束,开始发车····

二,逐层构思

         

          下面是游戏结构分析

1,游戏菜单界面

        菜单的显示仅涉及打印,代码如下:

void menu()
{
	printf(">>>1.开始游戏<<<\n>>>0.退出游戏<<<\n请输入:");
}

2,游戏地图的创建     

扫雷游戏有三种难度:

  • 简单(9*9地图,10处雷)
  • 中等(16*16地图,40处雷)
  • 困难(30*16地图,99处雷)

这里我们学习简单难度的写法:

        在这里,地图要分为两种:1,显示出的地图、2,分布着雷的地图。对于两种地图,我们要用两种二维数组来对应,我们将它们命名为:map1(分布雷的地图)、map2(显示的地图)。对于此类二维数组的创建,我们会想着创建一个【9】【9】的数组,但是到排雷时,我们会发现当我们要排查边缘时边缘以外的坐标就无法显示了,因此,我们选择【11】【11】数组。(注:ROWS与COLS在定义时已经赋值)

//创建地图
char map1[ROWS][COLS];
char map2[ROWS][COLS];

此时要对数组进行初始化,map1初始化为0,而map2初始化为  *  ,即显示在屏幕上的图案。这里我们要利用for循环:

代码如下:

//棋盘初始化
for (int i = 0; i < ROWS; i++)
{
	for (int j = 0; j < COLS; j++)
	{
		map1[i][j] = '0';
		map2[i][j] = '*';
	}
}

 3,地图的打印(显示)

      地图的打印大部分涉及map2的打印,在每一次排查雷时,打印一次排查雷后的map2,如果踩到雷了,我们则打印出map1,以显示雷的分布情况。

代码如下:

//地图的打印
void DisplayBoard (char map[ROWS][COLS],int row,int col)
{
	int i = 0;
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", map[i][j]);
		}		
		printf("\n");
	}	
}

4,雷的分布 

     众所周知,扫雷中雷的分布时随机的,因此这里涉及srand与time函数,我们要用其随机生成10个雷处,然后赋值给map1这样雷的生成及分布就完成了。

代码如下:

 void SetMine(char map[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;//生成横纵坐标均为1到10
		int y = rand() % col + 1;
		if (map[x][y] == '0')
		{
			map[x][y] = '1';
				count--; 
		}
	}
}

 5,显示周围雷数

代码如下:

//显示周围雷数
int GetMineCount(char map1[ROWS][COLS], int x, int y)
{
	return(map1[x - 1][y] + map1[x - 1][y - 1] + map1[x - 1][y + 1] +map1[x][y - 1] + map1[x][y + 1] + map1[x + 1][y] + map1[x + 1][y-1] + map1[x + 1][y + 1] - 8*'0');
}

6,雷的排查

       在以上操作都完成后,便来到排查环节。排查时,当输入要排查的坐标后,我们用if函数判断该点是否为雷:

  1. 为雷时,游戏结束并且显示出答案
  2. 不为雷时,显示周围雷数并且显示出来

当我们排查到图上仅有雷时(即仅剩10个点时)游戏通关并打印答案。

代码如下:

//雷的排查
 void FindMine(char map1[ROWS][COLS],char map2[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while(win<ROW*COL-EASY_COUNT)
	{
		printf("请选择要扫描的坐标:\n");
		scanf_s("%d %d", &x, &y);
		if (map1[x][y] == '1')//踩雷了
		{
			printf("很遗憾,游戏结束\n");
			DisplayBoard(map1, ROW, COL);
			break;
		}
		else
		{
			int count = GetMineCount(map1, x, y);
			map2[x][y] = count+'0';
			system("cls");
			DisplayBoard(map2, ROW, COL);
			win++;
		}
	}
	if (win == ROW * COL - EASY_COUNT)
	{
		printf("恭喜通关!");
		DisplayBoard(map1, ROW, COL);
	}

三,代码展示 

1,代码的声明(头文件)

//代码的声明
#pragma once
#include<stdlib.h>
#include<time.h>
# include <stdio.h>

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10//雷的数目

void game();
void menu();
//打印棋盘
void DisplayBoard(char map[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char map[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char map[ROWS][COLS],char map2[ROWS][COLS], int row, int col);
//显示周围雷数
int GetMineCount(char map[ROWS][COLS], int x, int y);

2,代码的调用(源文件)

//代码的调用
#include"game.h"
void menu()
{
	printf(">>>1.开始游戏<<<\n>>>0.退出游戏<<<\n请输入:");
}
void game()
{
	//创建地图
	char map1[ROWS][COLS];
	char map2[ROWS][COLS];
	//棋盘初始化
	for (int i = 0; i < ROWS; i++)
	{
		for (int j = 0; j < COLS; j++)
		{
			map1[i][j] = '0';
			map2[i][j] = '*';
		}
	}
	//打印棋盘
	DisplayBoard(map2, ROW, COL);
	//布置雷
	SetMine(map1, ROW, COL);
	//扫雷
	FindMine(map1, map2, ROW, COL);
}

int main()
{
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		int input = 0;
		scanf_s("%d", &input);
		if (input == 1)
		{
			printf("游戏开始\n");
			game();
			break;
		}
		else if (input == 0)
		{
			printf("游戏结束");
			break;
		}
		else
		{
			printf("输入错误,请重新输入:");
		}
	} while (1);
	return 0;
}

3,代码的描述(实现)(源文件)

//代码的描述
# include"game.h"

//地图的打印
void DisplayBoard (char map[ROWS][COLS],int row,int col)
{
	int i = 0;
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", map[i][j]);
		}		
		printf("\n");
	}	
}
//雷点的布置
 void SetMine(char map[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;//生成横纵坐标均为1到10
		int y = rand() % col + 1;
		if (map[x][y] == '0')
		{
			map[x][y] = '1';
				count--; 
		}
	}
}
//雷的排查
 void FindMine(char map1[ROWS][COLS],char map2[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while(win<ROW*COL-EASY_COUNT)
	{
		printf("请选择要扫描的坐标:\n");
		scanf_s("%d %d", &x, &y);
		if (map1[x][y] == '1')
		{
			printf("很遗憾,游戏结束\n");
			DisplayBoard(map1, ROW, COL);
			break;
		}
		else
		{
			int count = GetMineCount(map1, x, y);
			map2[x][y] = count+'0';
			system("cls");
			DisplayBoard(map2, ROW, COL);
			win++;
		}
	}
	if (win == ROW * COL - EASY_COUNT)
	{
		printf("恭喜通关!");
		DisplayBoard(map1, ROW, COL);
	}
}//显示周围雷数
int GetMineCount(char map1[ROWS][COLS], int x, int y)
{
	return(map1[x - 1][y] + map1[x - 1][y - 1] + map1[x - 1][y + 1] +map1[x][y - 1] + map1[x][y + 1] + map1[x + 1][y] + map1[x + 1][y-1] + map1[x + 1][y + 1] - 8*'0');
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值