#include "pch.h"
#include <iostream>
#include <vector>
#include <windows.h>
using namespace std;
//行 高
#define ROW 12
//列 宽
#define COL 12
#define ZXDJ 10
#define XXDJ 14
struct MyPoint
{
int row;
int col;
//g起点到当前点代价
//w权重
//h当前点到终点的预估代价 忽略障碍只看直线
//f = g+h+w
int g, h, f;
void setF() { f = g + h; }
};
//八个方向
enum direct {
p_up,p_down,p_left,p_right,p_lup,p_ldown,p_rup,p_rdown
};
//辅助地图节点
//记录走过没,代价值
struct pathNode
{
int val;//值
bool isFind;//走过没,true走过
};
//判断pos点能不能走,能true
bool canWalk(MyPoint pos, pathNode pathMap[ROW][COL]) {
//不在地图内
if (pos.row < 0||pos.row>=ROW||pos.col<0||pos.col>=COL) {
return false;}
//是障碍,不能走
if (pathMap[pos.row][pos.col].val == 1)return false;
//走过了
if (pathMap[pos.row][pos.col].isFind == 1)return false;
return true;
}
//树的节点类型,使用树存储走过路径
struct treeNode {
MyPoint pos;
treeNode* pParent;//指向父节点指针
vector<treeNode*> child;//保存所有孩子节点数组
};
//计算g值
int getG(MyPoint pos,MyPoint endPos);
int main()
{
//地图 0:路 1:障碍 2:大楼 3:井盖
int map[ROW][COL] = {
{0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0},
};
//2 起点和重点
MyPoint begPos = {1,1};
MyPoint endPos = { 5,10 };
//3 记录,辅助地图,初始化
pathNode pathMap[ROW][COL] = { 0 };
for (int i = 0;i<ROW;i++)
for (int j = 0; j < COL; j++)
{
pathMap[i][j].val = map[i][j];
}
//4 创建一棵树
treeNode* pRoot = NULL;
//5 标记起点点走过
pathMap[begPos.row][begPos.col].isFind = true;
//6 起点入数成为根节点
pRoot = new treeNode;
memset(pRoot, 0, sizeof treeNode);//清空
pRoot->pos = begPos;
//7 准备一个数组保存所有评估点
vector<treeNode*> buff;
//迭代器找最小点
vector<treeNode*>::iterator itMin;
vector<treeNode*>::iterator it;
//8 寻路
bool isFindEnd = false;
//当前点
MyPoint currentPos = begPos;
//当前树节点
treeNode* pTemp = pRoot;
while (true)
{
//8.1 检查当前点哪些需要计算
for (int i = 0; i < 8; i++) {
treeNode* pChild = new treeNode;
memset(pChild, 0, sizeof treeNode);
pChild->pos = pTemp->pos;
switch (i)
{
case p_up:
pChild->pos.row--;
pChild->pos.g = 10;
break;
case p_down:
pChild->pos.row++;
pChild->pos.g = 10;
break;
case p_left:
pChild->pos.col--;
pChild->pos.g = 10;
break;
case p_right:
pChild->pos.col++;
pChild->pos.g = ZXDJ;
break;
case p_lup:
pChild->pos.col--;
pChild->pos.row--;
pChild->pos.g = XXDJ;
break;
case p_ldown:
pChild->pos.col--;
pChild->pos.row++;
pChild->pos.g = XXDJ;
break;
case p_rup:
pChild->pos.col++;
pChild->pos.row--;
pChild->pos.g = XXDJ;
break;
case p_rdown:
pChild->pos.col++;
pChild->pos.row++;
pChild->pos.g = XXDJ;
break;
default:
break;
}//8.2 计算所有点f
//8.2.1 判断是否计算(能走不)
if (canWalk(pChild->pos,pathMap)) {
//8.2.2 jisuanf
pChild->pos.g = getG(pChild->pos, endPos);
pChild->pos.setF();
//8.2.3 判断能否入树buff
pTemp->child.push_back(pChild);
pChild->pParent = pTemp;
buff.push_back(pChild);
//printf("(%d,%d)", pChild->pos.row, pChild->pos.col);
}
}
//cout << endl;
//Sleep(2000);
//8.3 找出f值最小的点,走,并从buff中删除该店
itMin = buff.begin();
for (it = buff.begin(); it != buff.end(); it++) {
if ((*itMin)->pos.f > (*it)->pos.f) {
itMin = it;
}
}
pathMap[pTemp->pos.row][pTemp->pos.col].isFind = true;
pTemp = *itMin;//走
buff.erase(itMin);
//8.4 判断是否找到重点,判断整个地图是否没有终点
if (pTemp->pos.row == endPos.row&&
pTemp->pos.col == endPos.col) {
isFindEnd = true;
break;
}
if (buff.empty()) { break; }
}
//9 打印路径
if (isFindEnd) {
printf("找到终点了!\n");
while (pTemp) {
printf("(%d,%d)", pTemp->pos.row, pTemp->pos.col);
pTemp = pTemp->pParent;
}
cout << "\n";
}
cout << fun();
system("pause");
}
int getG(MyPoint pos, MyPoint endPos) {
int x = ((pos.col > endPos.col) ? (pos.col - endPos.col) : (endPos.col - pos.col));
int y = ((pos.row > endPos.row) ? (pos.row - endPos.row) : (endPos.row - pos.row));
return ZXDJ * (x + y);
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门提示:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件