C语言_迷宫的实现

#1、单条通路迷宫

实现思路:

这里写图片描述

代码如下:

头文件maze.h

#ifndef __MAZE_H__
#define __MAZE_H__

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#define H 5
#define L 5
#define MAX_SIZE 100

typedef struct position 
{
	int x;
	int y;
}position;

typedef struct Maze
{
	int _Map[H][L];
}Maze;

typedef position DataType;

typedef struct stack
{
	DataType  data[MAX_SIZE];
	int top;
}Stack;

/////////////////////////////////////////////////////////
////栈操作
void InitStack (Stack *p);	//初始化栈
void PushStack (Stack *p, DataType d);	//入栈
void PopStack (Stack *p);	// 出栈
DataType TopNumAndTop (Stack *p);	 //返回栈顶元素然后出栈
int IsEmpty (Stack *p);	// 判空
int StackSize (Stack* p); //返回栈的大小

//////////////////////////////////////////////////////////
//////迷宫操作
void InitMaze (Maze* maze, int arr[H][L]);//初始化迷宫地图
void PrintMap (Maze maze);//打印迷宫
int IsEntry (Maze *maze, position *entry);//判断迷宫是否合法,合法返回1,否则返回0
void RunInMaze (Maze *maze, position *entry);//走迷宫
int IsPositionOk (Maze* maze, position *pos);//判断当前位置是否为通路
int IsExit(Maze* maze, position *entry, position *cur);//判断是否为出口
#endif

主演函数main.c

#include "maze.h"

///////////////////////////////////////////////////////////////
//栈操作
void InitStack (Stack *p)	//初始化
{
	assert (p != NULL);
	p->top = 0;
}

void PushStack (Stack *p, DataType d)	//入栈
{
	assert (p);
	if (p->top == MAX_SIZE)
	{
		printf ("栈满,无法入栈!!!\n");
		return;
	}
	p->data[p->top] = d;
	p->top++;
}

int IsEmpty (Stack *p)	// 判空
{
	return (p->top == 0);//如果为空,返回1;如果不为空,返回0
}

void PopStack (Stack *p)//出栈
{
	assert (p);
	if (p->top == 0)
	{
		printf ("栈空,操作失败!!!\n");
		return;
	}
	p->top --;
}

DataType TopNumAndTop (Stack *p)	 //返回栈顶元素(出栈)
{
	if (p->top == 0)
	{
		printf ("栈为空!!\n");
		return ;
	}
	return p->data[--(p->top)];
}

int StackSize (Stack* p)//返回栈的大小
{
	return p->top;
}


////////////////////////////////////////////////////////////////
//单条通路迷宫操作
void InitMaze (Maze* maze,int arr[H][L])	//初始化迷宫
{
	int i = 0;
	int j = 0;
	for (i=0; i<H; i++)
	{
		for (j=0; j<L; j++)
		{
			maze->_Map[i][j] = arr[i][j];
		}
	}
}

void PrintMap (Maze maze)	//打印迷宫
{
	int i = 0;
	int j = 0;
	for (i=0; i<H; i++)
	{
		for (j=0; j<L; j++)
		{
			printf ("%d\t", maze._Map[i][j]);
		}
		printf ("\n\n\n");
	}
}

int IsEntry (Maze *maze, position *entry)	//判断是否是迷宫入口
{
	if (entry->x == 0 || entry ->x == H-1 || entry->y == 0 || entry->y == L-1)
	{
		if (maze->_Map[entry->x][entry->y] == 1)
		{
			return 1;
		}
	}
	return 0;
}

int IsPositionOk (Maze* maze, position *pos)	//判断迷宫当前位置是否是通路
{
	assert (pos != NULL);
	if (pos->x >= 0 && pos->x < H && pos ->y >= 0 && pos ->y < L)
	{
		if (maze->_Map[pos->x][pos->y] == 1)
		{
			return 1;
		}
	}
	return 0;
}

int IsExit(Maze* maze, position *entry, position *cur)//判断是否为出口
{
	assert (maze != NULL && entry != NULL && cur != NULL);



	if (cur->x == 0 || cur ->x == H-1 || cur->y == 0 || cur->y == L-1)
	{
		if (maze->_Map[cur->x][cur->y] == 2 && cur->x != entry->x && cur->y != entry->y)
		{
			return 1;
		}
	}

	return 0;
}

void RunInMaze (Maze *maze, position *entry)//走迷宫
{
	position *cur = NULL;
	position next ;
	Stack s;
	InitStack (&s);
	assert (maze != NULL && entry != NULL);

	if (IsEntry (maze, entry) == 0)
	{
		printf ("入口非法!!!\n");
		return;
	}

	//入口合法
	cur = entry;
	maze->_Map[cur->x][cur->y] = 2;
	next.x = cur->x;
	next.y = cur->y;
	PushStack (&s, next);

	while (!IsEmpty(&s) && !IsExit(maze, entry, &next))
	{
		//上
		next.x --;
		if(IsPositionOk (maze, &next) == 1)//位置合法
		{
			maze->_Map[next.x][next.y] = 2;
			PushStack (&s, next);
			continue;
		}

		//左
		next .x ++;
		next.y --;
		if(IsPositionOk (maze, &next) == 1)//位置合法
		{
			maze->_Map[next.x][next.y] = 2;
			PushStack (&s, next);
			continue;
		}
		//右
		next.y++;
		next.y ++;
		if(IsPositionOk (maze, &next) == 1)//位置合法
		{
			maze->_Map[next.x][next.y] = 2;
			PushStack (&s, next);
			continue;
		}
		//下
		next.y--;
		next.x ++;
		if(IsPositionOk (maze, &next) == 1)//位置合法
		{
			maze->_Map[next.x][next.y] = 2;
			PushStack (&s, next);
			continue;
		}

		//四个方向都不合法,坐标出栈,回退
		next = TopNumAndTop (&s);
	}
	if (IsEmpty(&s) == 1)
	{
		printf ("迷宫无出口!!\n");
	}
	else
	{
		printf ("迷宫已走完!!!\n");
	}
}

测试代码:
test.c

#include "maze.h"

void test_1()
{
	Maze maze;
	position entry ;

	int arr[H][L] = {
					 {0, 0, 0, 0, 0},
					 {0, 0, 0, 0, 0}, 
					 {0, 1, 1, 1, 1}, 
					 {0, 1, 0, 0, 0},
					 {0, 1, 0, 0, 0},
					 
					};
	InitMaze (&maze, arr);
	PrintMap (maze);
	entry.x = H-1;
	entry.y = 1;
	RunInMaze (&maze, &entry);
	PrintMap (maze);
}

int main()
{
	test_1();
	system ("pause");
	return 0;
}

测试结果:

这里写图片描述
#2、多条通路的迷宫

这里写图片描述

对于多条通路的迷宫,和上面的一种相比,只是多了几个出口,所以在遇到出口时,只需要将出口值赋为0,将出口堵死,知道栈为空时,迷宫走完所有通路
所以走迷宫的函数为(其余函数和上一个的一样):

void RunInMaze (Maze *maze, position *entry)//走迷宫
{
	position* cur = NULL;
	position next ;
	Stack s;
	InitStack (&s);
	assert (maze != NULL && entry != NULL);
	cur = entry;
	if (0 == IsEntry (maze, entry))
	{
		printf ("非法入口!!!\n");
		return ;
	}


	maze->_Map[cur->x][cur->y] = 2;
	next.x = cur->x;
	next.y = cur->y;
	PushStack (&s, next);

	while (!IsEmpty (&s))
	{

		//如果走到出口,将出口值赋为0,回退
		if (1 == IsExit(maze, entry, &next))
		{
			maze->_Map[next.x][next.y] = 0;
			next = TopNumAndTop (&s);
		}

	//上
		next.x --;
		if(IsPositionOk (maze, &next) == 1)//位置合法
		{
			/*cur = &next;*/
			maze->_Map[next.x][next.y] = 2;
			PushStack (&s, next);
			continue;
		}
		next .x ++;

		
		//左
		next.y --;
		if(IsPositionOk (maze, &next) == 1)//位置合法
		{
			/*cur = &next;*/
			maze->_Map[next.x][next.y] = 2;
			PushStack (&s, next);
			continue;
		}
		next.y++;
		
		//右
		next.y ++;
		if(IsPositionOk (maze, &next) == 1)//位置合法
		{
			/*cur = &next;*/
			maze->_Map[next.x][next.y] = 2;
			PushStack (&s, next);
			continue;
		}
		next.y--;
		
		//下
		next.x ++;
		if(IsPositionOk (maze, &next) == 1)//位置合法
		{
			/*cur = &next;*/
			maze->_Map[next.x][next.y] = 2;
			PushStack (&s, next);
			continue;
		}

		//上下左右都不能走,出栈回退
		next = TopNumAndTop (&s);

	}
	printf ("迷宫已经走完!!!\n");
	
}

测试结果:

这里写图片描述

#3、带环的迷宫:

这里写图片描述

带环迷宫和之前的也不一样,标记方式改为每走一步就把值赋为前一步加一,判断下一步的方式也有所改变,代码如下:

void InitMaze (Maze* maze,int arr[H][L])
{
	int i = 0;
	int j = 0;
	for (i=0; i<H; i++)
	{
		for (j=0; j<L; j++)
		{
			maze->_Map[i][j] = arr[i][j];
		}
	}
}

void PrintMap (Maze maze)
{
	int i = 0;
	int j = 0;
	for (i=0; i<H; i++)
	{
		for (j=0; j<L; j++)
		{
			printf ("%d\t", maze._Map[i][j]);
		}
		printf ("\n\n\n");
	}
}

int IsEntry (Maze *maze, position *entry)
{
	if (entry->x == 0 || entry ->x == H-1 || entry->y == 0 || entry->y == L-1)
	{
		if (maze->_Map[entry->x][entry->y] == 1)
		{
			return 1;
		}
	}
	return 0;
}

int IsPositionOk (Maze* maze, position *pos, position *next)
{
	assert (pos != NULL);
	if (next->x >= 0 && next->x < H && next ->y >= 0 && next ->y < L)
	{
		if (maze->_Map[next->x][next->y] == 1 || maze->_Map[next->x][next->y] > maze->_Map[pos->x][pos->y])
		{
			return 1;
		}
	}
	return 0;
}


int IsExit(Maze* maze, position *entry, position *cur)//判断是否为出口
{
	assert (maze != NULL && entry != NULL && cur != NULL);

	if (cur->x == 0 || cur ->x == H-1 || cur->y == 0 || cur->y == L-1)
	{
		if (cur->x != entry->x && cur->y != entry->y)
		{
			return 1;
		}
	}

	return 0;
}

Stack* GetShortPath(Stack* path, Stack* short_path)
{
	if (StackSize (short_path) == 0 || StackSize (path) < StackSize (short_path))
	{
		int i = 0;
		for ( ;i<StackSize (path); i++)
		{
			short_path->data[i] = path->data[i];
		}
		short_path->top = path->top;
	}
	return short_path;
}

void RunInMaze (Maze *maze, position cur, position* entry, Stack* path, Stack* short_path)//走迷宫---其中maze为迷宫,cur 为 当前所在位
//置,entry 为入口位置,path 为当前正在走的路径,short_path为较短路径
{
	position up, down, left, right;
	assert (maze != NULL && entry != NULL);

	//不是出口,继续往上左右下四个方向走

	//上
	up = cur;
	up.x --;
	if(IsPositionOk (maze, &cur, &up) == 1)//位置合法
	{
		PushStack (path, up);	//入栈

		//判断当前是否为出口
		if (IsExit (maze, entry, &up) == 1)//是出口
		{
			maze->_Map[up.x][up.y] = maze->_Map[cur.x][cur.y]+1;	//标记
			short_path = GetShortPath (path, short_path);	//获取最短路径
			cur = TopNumAndTop (path);	//往回退,查找其他路径
			return;
		}

		maze->_Map[up.x][up.y] = maze->_Map[cur.x][cur.y]+1;	//标记

		RunInMaze (maze, up, entry, path, short_path);
	}

	//左
	left = cur;
	left.y --;
	if(IsPositionOk (maze, &cur, &left) == 1)//位置合法
	{
		PushStack (path, left);	//入栈

		//判断当前是否为出口
		if (IsExit (maze, entry, &left) == 1)//是出口
		{

			maze->_Map[left.x][left.y] = maze->_Map[cur.x][cur.y]+1;	//标记

			short_path = GetShortPath (path, short_path);	//获取最短路径
			cur = TopNumAndTop (path);	//往回退,查找其他路径
			return;
		}

		maze->_Map[left.x][left.y] = maze->_Map[cur.x][cur.y]+1;	//标记


		RunInMaze (maze, left, entry, path, short_path);
	}

	//右
	right = cur;
	right.y ++;
	if(IsPositionOk (maze, &cur, &right) == 1)//位置合法
	{
		PushStack (path, right);	//入栈

		//判断当前是否为出口
		if (IsExit (maze, entry, &right) == 1)//是出口
		{

			maze->_Map[right.x][right.y] = maze->_Map[cur.x][cur.y]+1;	//标记
			short_path = GetShortPath (path, short_path);	//获取最短路径
			cur = TopNumAndTop (path);	//往回退,查找其他路径
			return;
		}

		maze->_Map[right.x][right.y] = maze->_Map[cur.x][cur.y]+1;	//标记
		RunInMaze (maze, right, entry, path, short_path);
	}

	//下
	down = cur;
	down.x ++;
	if(IsPositionOk (maze, &cur, &down) == 1)//位置合法
	{
		PushStack (path, down);	//入栈

		//判断当前是否为出口
		if (IsExit (maze, entry, &down) == 1)//是出口
		{
			maze->_Map[down.x][down.y] = maze->_Map[cur.x][cur.y]+1;	//标记
			short_path = GetShortPath (path, short_path);	//获取最短路径
			cur = TopNumAndTop (path);	//往回退,查找其他路径
			return;
		}

		maze->_Map[down.x][down.y] = maze->_Map[cur.x][cur.y]+1;	//标记


		RunInMaze (maze, down, entry, path, short_path);
	}

	//四个方向都探测过,出栈回退
	cur = TopNumAndTop (path);

}

测试结果:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/A__B__C__/article/details/82713642