扫雷(简易版)

  • Post author:
  • Post category:其他


提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


目录


前言


一、扫雷代码量比较大,如何写?


二、扫雷详解


1.扫雷详解


a、设置一个打印菜单,作为游戏提示


b、输入一个数字,使程序能够进入游戏


c、进入游戏代码,难度逐渐提升


三、思完整代码实现


总结





前言





示:这里可以添加本文要记录的大概内容:

例如:我们初学C语言时,遇到代码量较大的项目——扫雷,那么如何思路清晰地写出扫雷的代码呢?这里推荐一个靠谱的方法。


本文有:扫雷详解+代码实现。



提示:以下是本篇文章正文内容,下面案例可供参考



一、扫雷代码量比较大,如何写?

答:思维导图帮助我们快速理清编程思路,是一个很好用的工具。



二、扫雷详解



1.扫雷详解


a、设置一个打印菜单,作为游戏提示

样式如下图:

直接让程序打印即可,代码如下:

void menu()
{
	printf("*********************\n");
	printf("****** 1. PLAY ******\n");
	printf("****** 2. EXIT ******\n");
	printf("*********************\n");
}

b、输入一个数字,使程序能够进入游戏

创建变量input;

利用scanf输入函数,使得用户能够输入input

switch选择语句:选择是否进入游戏。

case 1:进入游戏。

case 2 :退出游戏。

default:选择错误,请重新输入。(假如用户输入的数据不是1,也不是2,则执行default语句。)

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);//输入一个数字1或者2,表示是否进入游戏
		switch (input)
		{
		case 1://进入
			game();
			break;
		case 2://退出
			printf("退出游戏\n");
			break;
		default://选择错误
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

c、进入游戏代码,难度逐渐提升


(1)、首先,创建一个打印棋盘。

给用户看的棋盘,代码如下:

建立两个循环,打印出一个矩形的*阵。

用于初始化我们的*号棋盘。

void init_printboard(char print_board[ROW][COL])
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= ROW - 2; i++)
	{
		for (j = 1; j <= COL - 2; j++)
		{
			print_board[i][j] = '*';
		}
	}
}


(2)、用户输入扫雷的坐标,就把*改为数字。

假设雷为1,非雷为0;

我们想要的效果如下,输入扫雷的坐标,改变对应的位置符号。

改变符号时,我们需要确定该位置以及四周有没有雷。

假设我们选择的坐标为2,3;那么需要排查的坐标如黄线的位置,分别是:(1,2);(1,3);(1,4);(2,2);(2,4);(3,2);(3,3);(3,4).

如果坐标在最边缘的位置,那么我们需要排查的只有五个坐标,如图:

四个角落,需要排查的坐标也各不相同。

我们排查雷的代码又各不一样。

如果建立两个棋盘,可以帮助我们很好的避免边缘排查困难的情况。


左边的代码我们已经写完了,那么右边的代码如何实现?


(3)、初始化数字棋盘,设置时间戳

我们需要创建一个全0的棋盘,然后再把雷布置上去。

我们在初始化时,顺便把0放上去,完成一个棋盘的初始化。

void init_numboard(char num_board[ROW][COL])
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= ROW; i++)
	{
		for (j = 1; j <= COL; j++)
		{
			num_board[i][j] = '0';
		}
	}
}

再者就是布置雷了。

随机出现的雷才更加有趣。说到随机,我们就不得不使用时间戳来使得雷的位置随机出现。

因为时间永远都是变化的,所以利用时间戳来布置雷再好不过了。

srand((unsigned int)time(NULL));

上面这个就是时间戳的创建。

然后,我们再调用它。代码如下:

void Num(char num_board[ROW][COL])
{
	int n = 0;
	while (n < 10)
	{
		int row = rand() % (ROW-2) + 1;
		int col = rand() % (COL-2) + 1;
		if (num_board[row][col] == '0')
		{
			num_board[row][col] = '1';
			n++;
		}
	}
}


(4)、数字棋盘代码:

void init_numboard(char num_board[ROW][COL])
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= ROW; i++)
	{
		for (j = 1; j <= COL; j++)
		{
			num_board[i][j] = '0';
		}
	}
}

将两个棋盘合并,那么最边缘的棋盘四周也能确定是否有雷,就不需要写好几种不一样的



(5)、 如何排查雷?

根据我们所选择的坐标,判断该坐标是否为1。

如果是,那么直接结束游戏;如果不是,将其置为0。

int Findland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col)
{
	if (num_board[row][col] != '1')
	{
		print_board[row][col] = '0';
	}
	else
	{
		print_board[row][col] = '1';
		return 1;//1表示游戏失败
	}
}

排查一圈,查看坐标周围是否有雷。

将四周的坐标遍历,有雷的count++。

排查出的count赋值给打印棋盘。

这样我们就能够看到四周有多少个雷啦。

如下图:

表示该坐标周围有两个雷。

代码实现如下:

char Findaroundland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col)//排查该坐标周围有几个雷
{
	char count = '0';
	int i = 0;
	int j = 0;
	for (i = row - 1; i <= row + 1; i++)
	{
		for (j = col - 1; j <= col + 1; j++)
		{
			if (num_board[i][j] == '1')
			{
				count++;
			}
		}
	}
	if (num_board[row - 1][col - 1] == '1' ||
		num_board[row - 1][col] == '1'|| 
		num_board[row - 1][col + 1] == '1'||
		num_board[row][col + 1] == '1'||
		num_board[row + 1][col + 1] == '1'||
		num_board[row + 1][col] == '1' ||
		num_board[row + 1][col - 1] == '1' ||
		num_board[row][col - 1] == '1' )
	{

		print_board[row][col] = count;//该坐标周围有几个雷
	}
	else
	{
		return '0';//0表示周围没有雷
	}
}

三、思完整代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"


//打印菜单
void menu()
{
	printf("*********************\n");
	printf("****** 1. PLAY ******\n");
	printf("****** 2. EXIT ******\n");
	printf("*********************\n");
}

//初始化数字棋盘
void init_numboard(char num_board[ROW][COL])
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= ROW; i++)
	{
		for (j = 1; j <= COL; j++)
		{
			num_board[i][j] = '0';
		}
	}
}

//初始化打印棋盘
void init_printboard(char print_board[ROW][COL])
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= ROW - 2; i++)
	{
		for (j = 1; j <= COL - 2; j++)
		{
			print_board[i][j] = '*';
		}
	}
}


//实现数字棋盘:布置雷
void Num(char num_board[ROW][COL])
{
	int n = 0;
	while (n < 10)
	{
		int row = rand() % (ROW - 2) + 1;
		int col = rand() % (COL - 2) + 1;
		if (num_board[row][col] != '1')
		{
			num_board[row][col] = '1';
			n++;
		}
	}
}


//打印数字棋盘
void PrintNum(char num_board[ROW][COL])
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= ROW; i++)
	{
		for (j = 1; j <= COL; j++)
		{
			printf("%c ", num_board[i][j]);
		}
		printf("\n");
	}
}

//实现打印棋盘
void Print(char print_board[ROW][COL])
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= ROW - 2; i++)
	{
		for (j = 1; j <= COL - 2; j++)
		{
			printf("%c ", print_board[i][j]);
		}
		printf("\n");
	}
}


//排查该坐标是否是雷
int Findland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col)
{
	if (num_board[row][col] != '1')
	{
		print_board[row][col] = '0';
	}
	else
	{
		print_board[row][col] = '1';
		return 1;//1表示游戏失败
	}
}

//排查该坐标周围有几个雷
char Findaroundland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col)//排查该坐标周围有几个雷
{
	char count = '0';
	int i = 0;
	int j = 0;
	for (i = row - 1; i <= row + 1; i++)
	{
		for (j = col - 1; j <= col + 1; j++)
		{
			if (num_board[i][j] == '1')
			{
				count++;
			}
		}
	}
	if (num_board[row - 1][col - 1] == '1' ||
		num_board[row - 1][col] == '1'|| 
		num_board[row - 1][col + 1] == '1'||
		num_board[row][col + 1] == '1'||
		num_board[row + 1][col + 1] == '1'||
		num_board[row + 1][col] == '1' ||
		num_board[row + 1][col - 1] == '1' ||
		num_board[row][col - 1] == '1' )
	{

		print_board[row][col] = count;//该坐标周围有几个雷
	}
	else
	{
		return '0';//0表示周围没有雷
	}
}

//游戏实现
void game()
{
	char print_board[ROW+10][COL+10];
	char num_board[ROW+10][COL+10];
	int i = 0;
	int j = 0;

	init_numboard(num_board);//初始化数字棋盘
	//PrintNum(num_board);//打印数字棋盘
	init_printboard(print_board);//初始化打印棋盘
	Print(print_board);//实现打印棋盘

	Num(num_board);//实现数字棋盘:布置雷
	PrintNum(num_board);//打印数字棋盘


	while (1)
	{
		int row = 0;
		int col = 0;
		printf("请输入坐标:>");
		scanf("%d %d", &row, &col);//选择扫雷坐标

		int ret = Findland(num_board, print_board, row, col);//排查该坐标是否是雷
		//Print(print_board);//实现打印棋盘
		char ret2 = Findaroundland(num_board, print_board, row, col);//排查该坐标周围有几个雷
		Print(print_board);//实现打印棋盘


		if (ret == '1')
		{
			printf("游戏结束\n");
			break;
		}
	}
}

#pragma once

#include<stdio.h>

#define ROW 11
#define COL 11

//打印菜单
void menu();

//初始化数字棋盘
void init_numboard(char num_board[ROW][COL]);
//初始化打印棋盘
void init_printboard(char print_board[ROW][COL]);

//实现数字棋盘:布置雷
void Num(char num_board[ROW][COL]);

//打印数字棋盘
void PrintNum(char num_board[ROW][COL]);
//实现打印棋盘
void Print(char print_board[ROW][COL]);

//排查该坐标是否是雷
int Findland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col);
//排查该坐标周围有几个雷
char Findaroundland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col);



总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文仅仅简单介绍了扫雷代码的思路,和简单的代码实现。如果有学有余力,也可以自己尝试把四周的*表示为数字,写一个更加复杂的扫雷。



版权声明:本文为star_xyz原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。