迷宫生成及自动寻路--DFS算法

该文介绍了一个基于DFS算法的计算机软件课设项目,包括迷宫生成和自动寻路两个部分。使用DFS进行路径搜索,但未实现BFS或A*等其他算法。项目代码使用C++编写,生成和显示迷宫地图,并找到从起点到终点的路径。
摘要由CSDN通过智能技术生成

一、项目思路

该项目应用于计算机软件课设。该项目主要分成两部分迷宫生成与自动寻路,两部分都采用DFS算法。迷宫生成参考文章:

经验分享:三套简单的迷宫地图生成方案(思路一:主路扭曲型)

实验结果:

20230123_194707

二、代码

Maze_generation.h

#pragma once
#include <graphics.h>
#include <Windows.h>
#include <math.h>
#include <iostream>
#include<utility>
#include<stack>

#define WIDTH 350//分辨率
#define HEIGHT 350
#define BLOCK_XY 10//小方格边长
const int BLOCK_WIDTH = WIDTH / (BLOCK_XY);//小方格x轴数量
const int BLOCK_HEIGHT = HEIGHT / (BLOCK_XY);//小方格y轴数量

#define Road COLORREF RGB(0,0,0)//路 黑色
#define Wall COLORREF RGB(255,255,255)//墙壁 白色
#define ReadBlock COLORREF RGB(235,51,36) //选中的格子
#define Point COLORREF RGB(0,35,245)//起点,重点
#define Path COLORREF RGB(240,134,80) //寻路路径

#define BeginPoint 6
#define EndPoint 7
#define	RoadDisplay 9


class Maze_generation
{
private:
	int X_index;
	int Y_index;
public:
	void Initialize();
	int IsHaveNeighbour(int X_index, int Y_index);
	void Generation(int X_index, int Y_index);
	void Drawing(int x, int y, COLORREF RGB);
	void Display();
	void DispalyPath();
	void clearscreen(COLORREF RGB);//清空地图为RGB颜色(带有网格)
	void setBeginPoint(int x, int y);
	void setEndPoint(int x, int y);
	void findPathDFS();
};


Maze_generation.cpp

#include "Maze_generation.h"
using namespace std;
int map[BLOCK_HEIGHT][BLOCK_WIDTH];
const int dirx[4] = { 0,1,0,-1 };
const int diry[4] = { 1,0,-1,0 };
int startx = 1;
int	starty = 1;
int endx = BLOCK_HEIGHT - 2;
int	endy = BLOCK_WIDTH - 2;

//为DFS服务
struct pathNode {
	int dir; //方向
	bool isFind; //0为没走过 1为走过
};
pathNode path[BLOCK_HEIGHT][BLOCK_WIDTH] = { 0 };
stack<Maze_generation>DFSpoint;
enum dir { p_up = 0, p_down = 1, p_left = 2, p_right = 3 };

void Maze_generation::Initialize()
{
	int i, j;
	for (i = 0; i < BLOCK_HEIGHT; i++)	//通过后将地图初始化成全0的
		for (j = 0; j < BLOCK_WIDTH; j++)//i为行,j为列
			map[i][j] = 0;
	//将所需地图以外的初始化为空白,其余空地和墙壁间隔
	for (i = 0; i < BLOCK_HEIGHT; i++)
	{
		for (j = 0; j < BLOCK_WIDTH; j++)
		{
			if (i != 0 && j != 0 && i != BLOCK_HEIGHT - 1 && j != BLOCK_WIDTH -1) //迷宫围墙内
			{
				if (i % 2 != 0) //i为奇数
					if (j % 2 != 0)//j为奇数
						map[i][j] = 1;
			}
		}
	}
}

int Maze_generation::IsHaveNeighbour(int X_index, int Y_index)
{
	//上	下		左		右
	if ((X_index >= 3 && map[X_index - 2][Y_index] == 1) || (X_index < BLOCK_HEIGHT - 3 && map[X_index + 2][Y_index] == 1) || (Y_index >= 3 && map[X_index][Y_index - 2] == 1) || (Y_index < BLOCK_WIDTH - 3 && map[X_index][Y_index + 2] == 1))
		return 1;
	return 0;
}

void Maze_generation::Generation(int X_index, int Y_index)
{
	int rand_position, x, y, flag = 0;
	x = X_index;
	y = Y_index;
	while (1)
	{
		flag = 0;
		flag = IsHaveNeighbour(X_index, Y_index); //是否有邻居
		if (flag == 0) //无邻居
		{
			return;
		}
		else //有邻居
		{
			map[X_index][Y_index] = 5;
			Drawing(X_index, Y_index, ReadBlock);
			FlushBatchDraw();
			Display();
			x = X_index;
			y = Y_index;
			while (1)
			{
				rand_position = rand() % 4; //随机一个方向
				if (rand_position == 0 && X_index >= 3 && map[X_index - 2][Y_index] == 1)//上
				{
					X_index = X_index - 2;
				}
				else if (rand_position == 1 && X_index < BLOCK_HEIGHT - 3 && map[X_index + 2][Y_index] == 1)//下
				{
					X_index = X_index + 2;
				}
				else if (rand_position == 2 && Y_index >= 3 && map[X_index][Y_index - 2] == 1)//左
				{
					Y_index -= 2;
				}
				else if (rand_position == 3 && Y_index < BLOCK_WIDTH - 3 && map[X_index][Y_index + 2] == 1)//右
				{
					Y_index += 2;
				}
				map[(x + X_index) / 2][(y + Y_index) / 2] = 5;
				Drawing(X_index, Y_index,Road);
				FlushBatchDraw();
				Display();
				map[X_index][Y_index] = 5;
				Generation(X_index, Y_index); //递归 flag==0 返回到此处
				break;
			}
		}
	}
}

void Maze_generation::Drawing(int x, int y, COLORREF RGB)
{
	setfillcolor(RGB); setlinecolor(COLORREF RGB(55, 126, 71));
	fillrectangle(x * BLOCK_XY, y * BLOCK_XY, BLOCK_XY + x * BLOCK_XY, BLOCK_XY + y * BLOCK_XY);
}

void Maze_generation::Display()
{
	for (int y = 0; y < BLOCK_HEIGHT; y++) {
		for (int x = 0; x < BLOCK_WIDTH; x++) {
			if (map[x][y] == 0) {
				Drawing(x, y, Wall);
			}
			else if (map[x][y] == 5) {
				Drawing(x, y, Road);
			}
			else if (map[x][y] == BeginPoint || map[x][y] == EndPoint) {
				Drawing(x, y,Point);
			}
		}
	}
	FlushBatchDraw();
}


void Maze_generation::clearscreen(COLORREF RGB)
{
	for (int y = 0; y < BLOCK_HEIGHT; y++) {
		for (int x = 0; x < BLOCK_WIDTH; x++) {
			Drawing(x, y, RGB);
		}
	}
}

void Maze_generation::setBeginPoint(int x, int y)
{
	X_index = x;
	Y_index = y;
	map[x][y] = BeginPoint;
	Drawing(X_index, Y_index, Point);
	FlushBatchDraw();
	Display();
}

void Maze_generation::setEndPoint(int x, int y)
{
	X_index = x;
	Y_index = y;
	map[x][y] == EndPoint;
	Drawing(X_index, Y_index, Point);
	FlushBatchDraw();
	Display();
}

void Maze_generation::findPathDFS()
{
	bool find = false;
	Maze_generation start;
	start.X_index = startx;
	start.Y_index = starty;
	path[start.X_index][start.Y_index].dir = 0;
	path[start.X_index][start.Y_index].isFind = 1;
	path[17][17].isFind = 0;
	DFSpoint.push(start);

	Maze_generation current;
	Maze_generation search;
	current = start;

	while (1) {
		search = current;
		switch (path[current.X_index][current.Y_index].dir) {
		case p_up:
			search.Y_index--;
			path[current.X_index][current.Y_index].dir = p_down;
			if (path[search.X_index][search.Y_index].isFind == 0 && (map[search.X_index][search.Y_index] == 5 || map[search.X_index][search.Y_index] == EndPoint)) {
				current = search;
				path[search.X_index][search.Y_index].isFind = 1;
				DFSpoint.push(search);

				cout << "successs p_up" << '\t' << current.X_index << '\t' << current.Y_index << endl;
			}
			else {
				cout << "faile p_up" << '\t' << current.X_index << '\t' << current.Y_index << endl;
			}
			break;
		case p_down:
			search.Y_index++;
			path[current.X_index][current.Y_index].dir = p_left;
			if (path[search.X_index][search.Y_index].isFind == 0 && (map[search.X_index][search.Y_index] == 5 || map[search.X_index][search.Y_index] == EndPoint)){
				current = search;
				path[search.X_index][search.Y_index].isFind = 1;
				DFSpoint.push(search);

				cout << "successs p_down" << '\t' << current.X_index << '\t' << current.Y_index << endl;
			}
			else {
				cout << "faile p_down" << '\t' << current.X_index << '\t' << current.Y_index << endl;
			}
			break;
		case p_left:
			search.X_index--;
			path[current.X_index][current.Y_index].dir = p_right;
			if (path[search.X_index][search.Y_index].isFind == 0 && (map[search.X_index][search.Y_index] == 5 || map[search.X_index][search.Y_index] == EndPoint)) {
				current = search;
				path[search.X_index][search.Y_index].isFind = 1;
				DFSpoint.push(search);

				cout << "successs p_left" << '\t' << current.X_index << '\t' << current.Y_index << endl;
			}
			else {
				cout << "faile p_left" << '\t' << current.X_index << '\t' << current.Y_index << endl;
			}
			break;
		case p_right:
			search.X_index++;
			if (path[search.X_index][search.Y_index].isFind == 0 && (map[search.X_index][search.Y_index] == 5 || map[search.X_index][search.Y_index] == EndPoint)) {
				current = search;
				path[search.X_index][search.Y_index].isFind = 1;
				DFSpoint.push(search);

				cout << "successs p_right" << '\t' << current.X_index << '\t' << current.Y_index << endl;
			}
			else {
				cout << "死胡同回溯" << '\t' << current.X_index << '\t' << current.Y_index << endl;
				DFSpoint.pop();
				current = DFSpoint.top();
			}
			break;
		}
		if (current.X_index == endx && current.Y_index == endy) {
			find = true;
			break;
		}
		if (DFSpoint.empty()) {
			break;
		}
	}
	if (find) {
		while (!DFSpoint.empty()) {
			Maze_generation temp = DFSpoint.top();
			Drawing(temp.X_index, temp.Y_index, Path);
			FlushBatchDraw();
			DFSpoint.pop();
		}
		
	}
}

main.cpp

#include"Maze_generation.h"
#include"Stack.h"
#include<iostream>
using namespace std;
int main() {
	
	srand((unsigned)time(NULL));	//随机数种子
	initgraph(WIDTH, HEIGHT, EW_SHOWCONSOLE);//创建绘图窗口
	BeginBatchDraw();//开始批量绘图
	cleardevice();//清空显示
	Maze_generation m;

	
	m.Initialize();
	m.Generation(1,1);
	m.setBeginPoint(1, 1);
	m.setEndPoint(BLOCK_WIDTH - 2, BLOCK_HEIGHT - 2);
	m.Display();
	m.findPathDFS();

	system("pause");

	/*Stack<int>stack;
	for (int i = 0; i < 10; i++)
		stack.push(i);
	while (!stack.empty()) {
		cout << stack.top() << endl;
		stack.pop();

	}
	return 0;*/
}

三、总结

该项目实现难度不大,没有采用较难的算法,BFS寻路以及A*寻路都未实现,留待后续完善。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值