[C语言]c语言简易实现扫雷

文章详细介绍了扫雷游戏的创建过程,包括创建棋盘、布置雷、排雷和状态判断四个步骤,并提供了相应的代码实现。强调了逻辑图在程序设计中的重要性,以及在步骤细化中应注意的细节,如数组越界和游戏规则的处理。此外,还提供了头文件和主函数的示例代码。
摘要由CSDN通过智能技术生成

目录

一,前言 

二,逻辑图

1. (步骤)创建棋盘:​编辑

2.(步骤)布置雷:

3.(步骤)排雷:

 4.(步骤)状态判断

三,代码实现 

初始化棋盘:

打印棋盘:

 布置雷:

 扫雷:

game函数内逻辑拼装:(重点)

主函数:

头文件:

四,心得总结


一,前言 

前言:面对扫雷从何下手?面对一个完整的程序,我们第一步就是细化出过程并且画出来。

 扫雷的过程我分为了四步: 一,创建棋盘

                                              二,布置雷

                                              三,开始排雷

                                              四,状态判断

二,逻辑图

我们根据以上四步,画出逻辑图:

 

然后细化逻辑图:

进一步细化可以写出要完成这个步骤需要什么,或者这个步骤包含什么,或者这个步骤里面有什么易错点,又或是这个步骤需要完成有何技巧

1. (步骤)创建棋盘:

创造容器定义数组即可,初始化就是遍历数组赋初始值即可

打印是打印棋盘,但是 :棋盘每格子的信息包括:1.是否是雷,2.周边雷的信息;

我们打印的时候,死了需要打印出所有雷,但是不包含雷的信息;没有死需要打印雷的信息,不能打印出雷;显然,这个是一个数组难以完成的,所以,我们创造容器的时候,可以创造两个容器,一个放是否是雷,一个放周边雷的信息;

(由此可以看出,细分的时候,每个步骤之间的联系可以引出更多的思考和细节)

2.(步骤)布置雷:

一个数组内,用什么表示雷呢?由于后面会用到雷的数量,如果一个雷用数字1表示,之后排雷点的范围内的雷的数量直接就是该范围内数字的和;所以,雷用数字1表示更好;

(这就是步骤有何技巧)

3.(步骤)排雷:

 涉及数组,并且涉及对数组位置的变化的时候,一定考虑越界问题!!!(易错点)

 这时,可以再多加一圈数组的大小,数组中间设置为游戏区域(技巧)

 4.(步骤)状态判断

状态分为:1.结束   2.继续

结束有两种情况:1.被雷炸死   2.非雷区域全部探索完

三,代码实现 

根据逻辑图,我们先用代码先写出整体步骤来

 

 写完之后再一个一个实现代码逻辑

具体代码逻辑:

初始化棋盘:

//初始化棋盘
void IntiBoard(char board[ROW][COL], int row, int col, char tag)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			board[i][j] = tag;
		}
	}

	return 0;
}

打印棋盘:

//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	printf("\n棋盘如下:\n");
	//打印棋盘有两个部分  1.提示行列数 2.棋盘内容

	int i = 0;
	int j = 0;
	//第一行内容:0 1 2 3 4 5 6 7 8 9.....
	for (i = 0; i <= GAMECOL; i++)
	{
		printf("%d  ",i);
	}
	printf("\n");
	
	//为了方便后续计算,增加了一圈大小,但是打印只需打印圈内的
	for (i = 1; i <= row; i++)
	{
		//每行第一列需要打印行数
		printf("%d  ", i);

		for (j = 1; j <= col; j++)
		{
			printf("%c  ", board[i][j]);
		}

		printf("\n");
	}

	return;
}

 布置雷:

//布置雷
void GetMine(char board[ROW][COL])
{
	int minecounts = MINECOUNT;
	while(minecounts != 0)
	{
		//未布置雷的地方才可以放
		
		int x = rand() % GAMEROW + 1;
		int y = rand() % GAMECOL + 1;

		if(board[x][y] == '0')
		{
			board[x][y] = '1';
			minecounts--;
		}
	}

	return;
}

 扫雷:

//得到雷的数量
int GetMineCounts(char board[ROW][COL], int row, int col)
{
	//逻辑就是该点周围的内容之和-‘0’*8
	return
		(
			board[row - 1][col + 1] +
			board[row - 1][col] +
			board[row - 1][col - 1] +
			board[row][col + 1] +
			board[row][col - 1] +
			board[row + 1][col - 1] +
			board[row + 1][col] +
			board[row + 1][col - 1]

			-(8*'0')

		);

}

game函数内逻辑拼装:(重点)

void game()
{
	//1.创建棋盘
	// 
	//a.定义棋盘
	char mine[ROW][COL] = { '0' };
	char infor[ROW][COL] = { '0' };
	//b.初始化棋盘
	IntiBoard(mine, ROW, COL, '0');//雷为1非雷为0,初始化全0

	IntiBoard(infor,ROW,COL,'*');//为探索为*,探索为周围雷的数量,初始化全*
	//c.打印棋盘
	DisplayBoard(infor,GAMEROW,GAMECOL);

	//2.布置雷
	GetMine(mine);

	int x = 0;
	int y = 0;
	//3.扫雷
				//4.结束条件是排除所有不是雷的地方(gamerow*gamecol-MINECOUNT),flag等于这个数字的时候获胜
				int flag = 0;	
	while (flag < (GAMEROW*GAMECOL-MINECOUNT))
	{
		//a.输入目标行列
		printf("请输入你扫的行列数:>");
		scanf("%d %d", &x, &y);
				//x,y必须是合法的
		//一:在范围内
		if (x >= 1 && x < GAMEROW && y >= 1 && y < GAMECOL && infor[x][y] == '*')
		{
			//b.检查雷
			if (mine[x][y] == '1')
			{
				//是雷,炸死
				printf("被炸死,游戏结束\n");
				//被炸死的时候显示所有雷
				DisplayBoard(mine, GAMEROW, GAMECOL);

				return;
			}
			else
			{
				//不是雷的话,infor该位置显示周围地雷的数量
				int minecounts = GetMineCounts(mine, x, y);
				infor[x][y] = (minecounts + '0');
				//然后显示
				DisplayBoard(infor, GAMEROW, GAMECOL);
				flag++;
			}
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}


	}


	//flag等于这个数字的时候获胜
	if (flag == (GAMEROW * GAMECOL - MINECOUNT))
	{
		printf("恭喜你,获得游戏胜利\n");
	}

	return;
}

主函数:

#include"all.h"

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

	int choice = 0;
	do
	{
		menu();
		printf("请输入你的选择:>");
		scanf("%d", &choice);

		//根据选择进行游戏还是退出游戏
		switch (choice)
		{

		case 1:
			game();
			break;

		case 0:
			printf("退出游戏成功\n");
			break;

		default:
			printf("输入错误,请重新输入\n");
			break;

		}


		//choice为0代表退出游戏
	} while (choice != 0);



	return 0;
}


void menu()
{
	printf("************************\n");
	printf("****  1.开始游戏  ******\n");
	printf("****  0.退出游戏  ******\n");
	printf("************************\n");

	return;
}

头文件:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

//*** 宏定义 ***
#define ROW 11
#define COL 11
#define	GAMEROW (ROW-2)
#define GAMECOL (COL-2)
#define MINECOUNT 80

//*** 函数定义 ***
void menu();
void game();
void IntiBoard(int board[ROW][COL], int row, int col, char tag);//初始化棋盘
void DisplayBoard(int board[ROW][COL], int row, int col);//打印棋盘
void GetMine(char board[ROW][COL]);//布置雷
int GetMineCounts(char board[ROW][COL], int row, int col);//得到周围雷的数量

四,心得总结

对于长代码程序,先画逻辑图是非常非常重要的,然后再细分逻辑图,根据逻辑图逐步逐步完善代码逻辑;

觉得不错的兄弟点个赞呗b( ̄▽ ̄)d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彭s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值