A*寻路算法c++版(第二版)bug修正

    这周主要把python版本的A*寻路算法给调试完了,python版本的代码会在下一篇文章中详细说明,这篇文章主要是修正了第一版的一个重大的bug,现说明如下:

    在c++第一版中的“具体工作逻辑”5-5)-b)步:

        “邻近结点的g值是否大于当前结点的g值加上当前结点到该邻近结点的距离值,如果大于,则将该邻近结点的g值修改为当前结点的g值加上当前结点到该邻近结点的距离值,并将该邻近结点父指针指向当前结点,因为该邻近结点原来的父路径g值比以当前结点作为父路径g值要大,而最终目的是要选择g值小的,所以要将父指针修改为当前结点,并修改该邻近结点的g值和f值,结束后续判断。”

        这一步是整个A*算法的最核心的一步,用到了贪婪算法的思想,第一版的bug是只修正了在棋盘chessboard结构体数组中该邻近结点元素的g_value值和f_value值,而没有更新在openlist中该邻近结点的f_value,导致openlist按列表中每个元素的f_value值重新由大到小排序时,按该邻近结点的旧f_value值排序,而这个值不是“最优解”,所以虽然最后也能找到一条路径,但是这条路径却不是按照正确的A*算法得出的最优路径。添加部分代码如图1第228行、图2第333行,都将openlist中的该邻近结点的f_value也进行了更新

图1


图2

修正前后的最佳路径对比如图3:


图3 左:修正前                 右:修正后

现将修正后的代码贴在下面:(相比第一版只添加2行代码)

// AstarFindWay1.cpp : 定义控制台应用程序的入口点。
//
// Afindpath.cpp : 定义控制台应用程序的入口点。
//定义棋盘、起点(4,3)、终点(3,17)、障碍物(2,8)(3,8)(4,8)(5,8)
//约定:棋盘外框都视为障碍物
//####################
//####################
//########b###########
//########b########e##
//###s####b###########
//########b###########
//####################
//####################
//####################
//####################
//......
#include "stdafx.h"
#include "iostream"
#include "fstream"

using namespace std;

#define chess_size 20
#define FILE_STORAGE_WAY   "d:\\AstarFindWay1.txt"	//随机数据文件存放路径

struct PARENT_POSITION
{
	int x;
	int y;

};

struct CHESS_BOARD_UNIT
{
	PARENT_POSITION ParentPosition;
	int g_value;
	int h_value;
	int f_value;
	char flag;//标识此单元是:2起点/3终点/1障碍物/0通路
};

struct OpenListUnit
{
	int ChessUnit_x;
	int ChessUnit_y;
	//int pointer;
	int f_value;

};

struct CloseListUnit
{
	int ChessUnit_x;
	int ChessUnit_y;

};

struct CurrentNeiborUnit
{
	int ChessUnit_x;
	int ChessUnit_y;
};

struct PrintPathUnit
{
	int ChessUnit_x;
	int ChessUnit_y;
};

struct ObstacleUnit
{
	int ChessUnit_x;
	int ChessUnit_y;
};
CHESS_BOARD_UNIT chessboard[chess_size][chess_size] = { 0 };//chessboard初始化为0

int Start_x, Start_y, End_x, End_y;//起点,终点坐标	
								   //ObstacleUnit Obstacle[chess_size*chess_size];//障碍物点坐标
int OpenListPosition = 0;	//指针标记open列表数组当前存放元素个数(position总指向最后一个元素的后一位置)
int CloseListPosition = 0;	//指针标记Close列表数组当前存放元素个数(position总指向最后一个元素的后一位置)

OpenListUnit OpenList[chess_size*chess_size];//open列表(定义成数组形式)
CloseListUnit CloseList[chess_size*chess_size];//close列表

void openListIncraseSort()
{
	int flag = 0;
	OpenListUnit temp;
	for (int i = 0; i < OpenListPosition; i++)//冒泡法由大到小排序
	{
		for (int j = 0; j < OpenListPosition - i; j++)
		{
			if (OpenList[j].f_value < OpenList[j + 1].f_value)//若OpenList[j].f_value < OpenList[j + 1].f_value,交换,从大到小排列
			{
				temp.ChessUnit_x = OpenList[j].ChessUnit_x;
				temp.ChessUnit_y = OpenList[j].ChessUnit_y;
				temp.f_value = OpenList[j].f_value;

				OpenList[j].ChessUnit_x = OpenList[j + 1].ChessUnit_x;
				OpenList[j].ChessUnit_y = OpenList[j + 1].ChessUnit_y;
				OpenList[j].f_value = OpenList[j + 1].f_value;

				OpenList[j + 1].ChessUnit_x = temp.ChessUnit_x;
				OpenList[j + 1].ChessUnit_y = temp.ChessUnit_y;
				OpenList[j + 1].f_value = temp.f_value;

				flag = 1;//将交换标志位置1
			}//if
		}//for2
		if (0 == flag) break;//内层循环一次都没交换,说明已经排好序
		flag = 0;//将标志位重新清0
	}//for1
	 //for(int i = 0; i < OpenListPosition; i++)
	 //{
	 //	cout << OpenList[i].ChessUnit_x << ","<< OpenList[i].ChessUnit_y << endl;
	 //}
}

//判断方格单元的属性
void detectUnitCharactor()
{
}


int dealCurrentNeibors(CloseListUnit &CurrentUnit)//判断当前结点周围8个点状态,计算g、h、f值,将周围每个点的父指针指向当前结点
{
	int OpenListFlag = 0, CloseListFlag = 0;

	int ObstacleEast = 0;	//标识当前点东边是否有障碍物
	int ObstacleSouth = 0;	//标识当前点南边是否有障碍物
	int ObstacleWest = 0;	//标识当前点西边是否有障碍物
	int ObstacleNorth = 0;	//标识当前点北边是否有障碍物

	int CurrentToNeibor = 0;//当前点到邻近点的距离
							//CloseListUnit EastUnit, SourthEastUnit, SourthUnit, SourthWestUnit, WestUnit, NorthWestUnit, NorthUnit, NorthEastUnit;//东,东南,南,西南,西,西北,北,东北
	CurrentNeiborUnit CurrentNeibors[8];//按顺序存放当前结点的东,东南,南,西南,西,西北,北,东北方向的邻结点
										//int OpenListPosition = 0;	//指针标记open列表数组当前存放元素个数(position总指向最后一个元素的后一位置)
										//int CloseListPosition = 0;	//指针标记Close列表数组当前存放元素个数(position总指向最后一个元素的后一位置)

										//东方y+1
	CurrentNeibors[0].ChessUnit_x = CurrentUnit.ChessUnit_x;
	CurrentNeibors[0].ChessUnit_y = CurrentUnit.ChessUnit_y + 1;
	//东南方x+1,y+1
	CurrentNeibors[1].ChessUnit_x = CurrentUnit.ChessUnit_x + 1;
	CurrentNeibors[1].ChessUnit_y = CurrentUnit.ChessUnit_y + 1;
	//南方x+1
	CurrentNeibors[2].ChessUnit_x = CurrentUnit.ChessUnit_x + 1;
	CurrentNeibors[2].ChessUnit_y = CurrentUnit.ChessUnit_y;
	//西南方x+1,y-1
	CurrentNeibors[3].ChessUnit_x = CurrentUnit.ChessUnit_x + 1;
	CurrentNeibors[3].ChessUnit_y = CurrentUnit.ChessUnit_y - 1;
	//西方y-1
	CurrentNeibors[4].ChessUnit_x = CurrentUnit.ChessUnit_x;
	CurrentNeibors[4].ChessUnit_y = CurrentUnit.ChessUnit_y - 1;
	//西北方x-1,y-1
	CurrentNeibors[5].ChessUnit_x = CurrentUnit.ChessUnit_x - 1;
	CurrentNeibors[5].ChessUnit_y = CurrentUnit.ChessUnit_y - 1;
	//北方x-1
	CurrentNeibors[6].ChessUnit_x = CurrentUnit.ChessUnit_x - 1;
	CurrentNeibors[6].ChessUnit_y = CurrentUnit.ChessUnit_y;
	//东北方x-1,y+1
	CurrentNeibors[7].ChessUnit_x = CurrentUnit.ChessUnit_x - 1;
	CurrentNeibors[7].ChessUnit_y = CurrentUnit.ChessUnit_y + 1;

	for (int i = 0; i < 8; i = i + 2)//对当前方格东、南、西、北四个方向的临近方格依次检测
	{
		CurrentToNeibor = (i % 2) ? 14 : 10;//当前点到邻近点的距离

											//终点
		if ('e' == chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].flag)
		{
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.x = CurrentUnit.ChessUnit_x;
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.y = CurrentUnit.ChessUnit_y;
			return 1;
			//break;//找到终点,结束循环
		}

		//超出边界点
		if (CurrentNeibors[i].ChessUnit_x < 0 || CurrentNeibors[i].ChessUnit_x>19 || CurrentNeibors[i].ChessUnit_y < 0 || CurrentNeibors[i].ChessUnit_y>19)
		{
			continue;//结束判断
		}

		//障碍物点
		if ('b' == chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].flag)
		{
			switch (i)
			{
			case 0:	ObstacleEast = 1; break;//标识当前点东边有障碍物
			case 2:	ObstacleSouth = 1; break;//标识当前点南边有障碍物
			case 4:	ObstacleWest = 1; break;//标识当前点西边有障碍物
			case 6:	ObstacleNorth = 1; break;//标识当前点北边有障碍物
			default:break;
			}

			continue;//结束判断
		}

		//将该临近点与closelist中的点逐个比较
		for (int j = 0; j < CloseListPosition; j++)
		{
			if ((CloseList[j].ChessUnit_x == CurrentNeibors[i].ChessUnit_x) && (CloseList[j].ChessUnit_y == CurrentNeibors[i].ChessUnit_y))//是closelist中的点
			{
				CloseListFlag = 1;只要是closelist中的点,就将标志位置1
				break;
			}

		}

		//将该临近点与openlist中的点逐个比较
		for (int j = 0; j < OpenListPosition; j++)
		{
			if ((OpenList[j].ChessUnit_x == CurrentNeibors[i].ChessUnit_x) && (OpenList[j].ChessUnit_y == CurrentNeibors[i].ChessUnit_y))//是openlist中的点
			{
				OpenListFlag = 1;//只要是openlist中的点,就将标志位置1
				if (chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value < chessboard[CurrentUnit.ChessUnit_x][CurrentUnit.ChessUnit_y].g_value + CurrentToNeibor)
				{
					break;//若该临近点的g值小于从起点经由当前结点到该临近结点的g值,不做任何操作
				}
				else//若该临近点的g值大于从起点经由当前结点到该临近结点的g值,将该临近结点的父指针指向当前结点,并更改该临近结点的g值,f值
				{
					//将该临近结点的父指针指向当前结点
					chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.x = CurrentUnit.ChessUnit_x;
					chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.y = CurrentUnit.ChessUnit_y;
					//更改该临近结点的g值,f值
					chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value = chessboard[CurrentUnit.ChessUnit_x][CurrentUnit.ChessUnit_y].g_value + CurrentToNeibor;
					chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].f_value = chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value + chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].h_value;
					OpenList[j].f_value = chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].f_value;//注意:第一版漏掉此处,导致openlist中的f_value没有被更新!!!
				}
			}
		}
		if ((1 == OpenListFlag) || (1 == CloseListFlag))//该邻近点是openlist或closelist中的点
		{
			OpenListFlag = 0;//清0
			CloseListFlag = 0;//清0
			continue;//结束对此邻近点的继续判断(防止把该临近点当做通路点重复加入到openlist中)
		}

		//可作为通路点
		if ('#' == chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].flag)
		{
			//将邻居结点的指针指向当前结点
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.x = CurrentUnit.ChessUnit_x;
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.y = CurrentUnit.ChessUnit_y;
			//计算该临近结点的g值,h值(曼哈顿距离),f值
			//chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value = chessboard[CurrentUnit.ChessUnit_x][CurrentUnit.ChessUnit_y].g_value + (i % 2) ? 14 : 10;//bug:"(i % 2) ? 14 : 10"竟然没有返回10!!!
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value = chessboard[CurrentUnit.ChessUnit_x][CurrentUnit.ChessUnit_y].g_value + CurrentToNeibor;
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].h_value = 10 * (abs(CurrentNeibors[i].ChessUnit_x - End_x) + abs(CurrentNeibors[i].ChessUnit_y - End_y));
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].f_value = chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value + chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].h_value;
			//将该临近点存入openlist中
			OpenList[OpenListPosition].ChessUnit_x = CurrentNeibors[i].ChessUnit_x;
			OpenList[OpenListPosition].ChessUnit_y = CurrentNeibors[i].ChessUnit_y;
			OpenList[OpenListPosition].f_value = chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].f_value;
			OpenListPosition++;
		}//if

	}//for

	for (int i = 1; i < 8; i = i + 2)//对当前方格东南、西南、西北、东北四个方向的临近方格依次检测
	{
		CurrentToNeibor = (i % 2) ? 14 : 10;//当前点到邻近点的距离

		if ((1 == ObstacleEast) && ((1 == i) || (7 == i)))//若东方格是障碍物,则东南、东北都不能通行
		{
			continue;
		}

		if ((1 == ObstacleSouth) && ((1 == i) || (3 == i)))//若南方格是障碍物,则东南、西南都不能通行
		{
			continue;
		}

		if ((1 == ObstacleWest) && ((3 == i) || (5 == i)))//若西方格是障碍物,则西南、西北都不能通行
		{
			continue;
		}

		if ((1 == ObstacleNorth) && ((5 == i) || (7 == i)))//若北方格是障碍物,则西北、东北都不能通行
		{
			continue;
		}

		//终点
		if ('e' == chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].flag)
		{
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.x = CurrentUnit.ChessUnit_x;
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.y = CurrentUnit.ChessUnit_y;
			return 1;
			//break;//找到终点,结束循环
		}

		//超出边界点
		if (CurrentNeibors[i].ChessUnit_x < 0 || CurrentNeibors[i].ChessUnit_x>19 || CurrentNeibors[i].ChessUnit_y < 0 || CurrentNeibors[i].ChessUnit_y>19)
		{
			continue;//结束判断
		}

		//障碍物点
		if ('b' == chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].flag)
		{
			continue;//结束判断
		}

		//将该临近点与closelist中的点逐个比较
		for (int j = 0; j < CloseListPosition; j++)
		{
			if ((CloseList[j].ChessUnit_x == CurrentNeibors[i].ChessUnit_x) && (CloseList[j].ChessUnit_y == CurrentNeibors[i].ChessUnit_y))//是closelist中的点
			{
				CloseListFlag = 1;只要是closelist中的点,就将标志位置1
				break;
			}

		}

		//将该临近点与openlist中的点逐个比较
		for (int j = 0; j < OpenListPosition; j++)
		{
			if ((OpenList[j].ChessUnit_x == CurrentNeibors[i].ChessUnit_x) && (OpenList[j].ChessUnit_y == CurrentNeibors[i].ChessUnit_y))//是openlist中的点
			{
				OpenListFlag = 1;//只要是openlist中的点,就将标志位置1
				if (chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value < chessboard[CurrentUnit.ChessUnit_x][CurrentUnit.ChessUnit_y].g_value + CurrentToNeibor)//当前点到邻近点的距离)
				{
					break;//若该临近点的g值小于从起点经由当前结点到该临近结点的g值,不做任何操作
				}
				else//若该临近点的g值大于从起点经由当前结点到该临近结点的g值,将该临近结点的父指针指向当前结点,并更改该临近结点的g值,f值
				{
					//将该临近结点的父指针指向当前结点
					chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.x = CurrentUnit.ChessUnit_x;
					chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.y = CurrentUnit.ChessUnit_y;
					//更改该临近结点的g值,f值
					chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value = chessboard[CurrentUnit.ChessUnit_x][CurrentUnit.ChessUnit_y].g_value + CurrentToNeibor;
					chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].f_value = chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value + chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].h_value;
					OpenList[j].f_value = chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].f_value;//重大bug,注意:第一版漏掉此处,导致openlist中的f_value没有被更新!!!
				}
			}
		}

		if ((1 == OpenListFlag) || (1 == CloseListFlag))//该邻近点是openlist或closelist中的点
		{
			OpenListFlag = 0;//清0
			CloseListFlag = 0;//清0
			continue;//结束对此邻近点的继续判断(防止把该临近点当做通路点重复加入到openlist中)
		}

		//可作为通路点
		if ('#' == chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].flag)
		{
			//将邻居结点的指针指向当前结点
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.x = CurrentUnit.ChessUnit_x;
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].ParentPosition.y = CurrentUnit.ChessUnit_y;
			//计算该临近结点的g值,h值(曼哈顿距离),f值
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value = chessboard[CurrentUnit.ChessUnit_x][CurrentUnit.ChessUnit_y].g_value + CurrentToNeibor;
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].h_value = 10 * (abs(CurrentNeibors[i].ChessUnit_x - End_x) + abs(CurrentNeibors[i].ChessUnit_y - End_y));
			chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].f_value = chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].g_value + chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].h_value;
			//将该临近点存入openlist中
			OpenList[OpenListPosition].ChessUnit_x = CurrentNeibors[i].ChessUnit_x;
			OpenList[OpenListPosition].ChessUnit_y = CurrentNeibors[i].ChessUnit_y;
			OpenList[OpenListPosition].f_value = chessboard[CurrentNeibors[i].ChessUnit_x][CurrentNeibors[i].ChessUnit_y].f_value;
			OpenListPosition++;
		}//if
	}//for
	return 0;
}


void printPath()
{
	int i = 0;//循环变量
	PrintPathUnit PathUnit;//逆序存放单路径结点(终点->起点)

	PrintPathUnit PathUnitList[chess_size*chess_size];//逆序存放所有路径结点(终点->起点)
													  //获取终点的坐标								  
	PathUnit.ChessUnit_x = End_x;
	PathUnit.ChessUnit_y = End_y;
	cout << "(" << PathUnit.ChessUnit_x << "," << PathUnit.ChessUnit_y << ")" << endl;//输出终点坐标
																					  //记录从end起第一个最佳路径结点
	PathUnit.ChessUnit_x = chessboard[End_x][End_y].ParentPosition.x;
	PathUnit.ChessUnit_y = chessboard[End_x][End_y].ParentPosition.y;

	while (!((PathUnit.ChessUnit_x == Start_x) && (PathUnit.ChessUnit_y == Start_y))) //记录从终点到起点之间的最佳路径
	{
		PathUnitList[i].ChessUnit_x = PathUnit.ChessUnit_x;
		PathUnitList[i].ChessUnit_y = PathUnit.ChessUnit_y;

		chessboard[PathUnitList[i].ChessUnit_x][PathUnitList[i].ChessUnit_y].flag = '*';//将最佳路径点用"*"表示
		cout << "(" << PathUnitList[i].ChessUnit_x << "," << PathUnitList[i].ChessUnit_y << ")" << endl;//输出路径结点坐标
																										//获取当前结点的父节点坐标
		PathUnit.ChessUnit_x = chessboard[PathUnitList[i].ChessUnit_x][PathUnitList[i].ChessUnit_y].ParentPosition.x;
		PathUnit.ChessUnit_y = chessboard[PathUnitList[i].ChessUnit_x][PathUnitList[i].ChessUnit_y].ParentPosition.y;

		i++;
	}
	cout << "(" << Start_x << "," << Start_y << ")" << endl;//输出终点坐标
	for (int i = 0; i < chess_size; i++)
	{
		for (int j = 0; j < chess_size; j++)
		{
			cout << chessboard[i][j].flag;
		}
		cout << endl;
	}

}

void FileReadMatrix()	//将文件中的数据读回至chess_size*chess_size矩阵中
{
	int i = 0;
	int j = 0;
	//uint uiTemp;	//定义变量存放从文件中读出的数据
	ifstream ifile;	//定义输入文件
	ifile.open(FILE_STORAGE_WAY);	//作为输入文件打开
	while (1)
	{
		if (ifile.eof() != 0) break;	//当读到文件结束时,ifile.eof()为真
		ifile >> chessboard[i][j].flag;	//将文件中的数据依次存放到数组中

		if ('s' == chessboard[i][j].flag)//检测并记录起始点坐标
		{
			Start_x = i;
			Start_y = j;
		}

		if ('e' == chessboard[i][j].flag)//检测并记录终点坐标
		{
			End_x = i;
			End_y = j;
		}

		j++;

		if (chess_size == j)//检测到达行尾
		{
			j = 0;
			i++;//换行
		}
	}
	for (int i = 0; i < 20; i++)
	{
		for (int j = 0; j < 20; j++)
		{
			cout << chessboard[i][j].flag;
		}
		cout << endl;
	}
}

int main()
{
	int PauseCin;

	FileReadMatrix();

	CloseListUnit CurrentUnit;

	//chessboard[4][3].flag = 's';//起点
	//chessboard[3][17].flag = 'e';//终点
	//chessboard[2][8].flag = 'b';//障碍物
	//chessboard[3][8].flag = 'b';//障碍物
	//chessboard[4][8].flag = 'b';//障碍物
	//chessboard[5][8].flag = 'b';//障碍物

	//将起点加入open列表
	OpenList[OpenListPosition].ChessUnit_x = Start_x;
	OpenList[OpenListPosition].ChessUnit_y = Start_y;
	OpenList[OpenListPosition].f_value = 0;
	//OpenList[0].pointer = 1;//指针标记open列表数组当前存放元素个数
	OpenListPosition++;//将起始结点存入openlist,position标记为1(position总指向最后一个元素的后一位置)

	while (OpenListPosition > 0)//若openlist不为空
	{
		openListIncraseSort();//openlist列表按f值大小降序排序(将最小f值点放在最后,这样只需将position减1就代表移出该点)
							  //将openlist中f值最小的点移入closelist中
		CloseList[CloseListPosition].ChessUnit_x = OpenList[OpenListPosition - 1].ChessUnit_x;
		CloseList[CloseListPosition].ChessUnit_y = OpenList[OpenListPosition - 1].ChessUnit_y;
		//openlist移出f值最小元素,清除原位置该元素信息
		OpenList[OpenListPosition - 1].ChessUnit_x = 0;
		OpenList[OpenListPosition - 1].ChessUnit_y = 0;
		OpenList[OpenListPosition - 1].f_value = 0;

		OpenListPosition--;//将OpenListPosition减1,表示从openlist中移出最后一点,即f值最小的点
		CloseListPosition++;//将OpenListPosition加1,记录closelist中增加一个元素
		CurrentUnit.ChessUnit_x = CloseList[CloseListPosition - 1].ChessUnit_x;	//获得当前结点的x坐标
		CurrentUnit.ChessUnit_y = CloseList[CloseListPosition - 1].ChessUnit_y;	//获得当前结点的y坐标

		if (dealCurrentNeibors(CurrentUnit)) break;//判断当前结点周围8个点状态,计算g、h、f值,将周围每个点的父指针指向当前结点

	}//while
	printPath();
	cin >> PauseCin;
	//FileReadMatrix();
	return 0;
}





  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值