Advertisement
Guest User

Untitled

a guest
Dec 16th, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.63 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "PathFInder.h"
  3.  
  4. #define Inf INT_MAX
  5. #define HeightNode 12
  6. #define WidthNode 15
  7. #define Nodes nodes[y][x]
  8.  
  9.  
  10. PathFinder::PathFinder(D3DXVECTOR2 position, D3DXVECTOR2 scale, D3DXCOLOR color)
  11. :nodeType(NodeType::None), color(color), startX(0), startY(0), goalX(0), goalY(0)
  12. , ptMouse(0, 0)
  13. , startPos(0, 0), goalPos(0, 0), bReadToMove(false)
  14. {
  15. wstring shaderFile = Shaders + L"Rect.fx";
  16.  
  17. float gridX = Width / scale.x;
  18. float gridY = Height / scale.y;
  19.  
  20. for (UINT y = 0; y < HeightNode; y++)
  21. {
  22. for (UINT x = 0; x < WidthNode; x++)
  23. {
  24. float positionX = x * scale.x - Width * 0.5f;
  25. float positionY = y * scale.y - Height * 0.5f;
  26.  
  27. Nodes.first = new Rect(shaderFile, D3DXVECTOR2(positionX, positionY), scale);
  28. Nodes.second.start = false;
  29. Nodes.second.goal = false;
  30. Nodes.second.wall = false;
  31. Nodes.second.f = Inf;
  32. Nodes.second.g = Inf;
  33. Nodes.second.h = Inf;
  34. Nodes.second.close = false;
  35. Nodes.second.parent.x = Inf;
  36. Nodes.second.parent.y = Inf;
  37.  
  38. }
  39. }
  40. }
  41.  
  42. PathFinder::~PathFinder()
  43. {
  44.  
  45. for (UINT y = 0; y < HeightNode; y++)
  46. {
  47. for (UINT x = 0; x < WidthNode; x++)
  48. {
  49. SAFE_DELETE(Nodes.first);
  50. }
  51. }
  52. }
  53.  
  54. void PathFinder::RenderText()
  55. {
  56. DirectWrite::GetDC()->BeginDraw();
  57. {
  58. wstring text = L"RB 시작 + 골 // LB : 장애물 // [Return] 길찾기 // [ESC] 리셋";
  59. RECT rt = { 10,80,600,200 };
  60. DirectWrite::RenderText(text, rt);
  61.  
  62. rt.top += 20;
  63. rt.bottom += 20;
  64. text = L"출발지(Yellow), 목적지(Green), 벽(Red), 닫힘(Blue), 최종길(Whithe)";
  65. DirectWrite::RenderText(text, rt);
  66. }
  67. DirectWrite::GetDC()->EndDraw();
  68. }
  69.  
  70. void PathFinder::SetStart()
  71. {
  72. for (UINT y = 0; y < HeightNode; y++)
  73. {
  74. for (UINT x = 0; x < WidthNode; x++)
  75. {
  76. if (Rect::PtInRect(Nodes.first, startPos))
  77. {
  78. Nodes.second.start = true;
  79. Nodes.second.g = 0;
  80. startX = x;
  81. startY = y;
  82. }
  83. else
  84. {
  85. Nodes.second.start = false;
  86. }
  87.  
  88. }
  89.  
  90. }
  91. }
  92.  
  93. void PathFinder::SetGoal()
  94. {
  95. for (UINT y = 0; y < HeightNode; y++)
  96. {
  97. for (UINT x = 0; x < WidthNode; x++)
  98. {
  99. if (Rect::PtInRect(Nodes.first, goalPos))
  100. {
  101. Nodes.second.goal = true;
  102. goalX = x;
  103. goalY = y;
  104. }
  105. else
  106. {
  107. Nodes.second.goal = false;
  108. }
  109.  
  110. }
  111.  
  112. }
  113. }
  114.  
  115. void PathFinder::SetWall()
  116. {
  117. for (UINT y = 0; y < HeightNode; y++)
  118. {
  119. for (UINT x = 0; x < WidthNode; x++)
  120. {
  121. if (Rect::PtInRect(Nodes.first, ptMouse))
  122. {
  123. Nodes.second.wall = true;
  124. }
  125. }
  126.  
  127. }
  128. }
  129.  
  130. void PathFinder::FindPath()
  131. {
  132. //H(예상 비용)
  133. for (UINT y = 0; y < HeightNode; y++)
  134. {
  135. for (UINT x = 0; x < WidthNode; x++)
  136. {
  137. Nodes.second.h = FindH(y, x, goalY, goalX);
  138. }
  139. }
  140. //Min F 검사 시작
  141. int count = 0;
  142. while (true)
  143. {
  144. //검사 횟수가 전체 대상보다 같으면 이상(반복문 탈출)
  145. if (count = HeightNode * WidthNode)
  146. break;
  147. count++;
  148.  
  149. //F = G + H
  150. for (UINT y = 0; y < HeightNode; y++)
  151. {
  152. for (UINT x = 0; x < WidthNode; x++)
  153. {
  154. if (Nodes.second.g != Inf)
  155. {
  156. Nodes.second.f = Nodes.second.h + Nodes.second.g;
  157. }
  158. }
  159. }
  160. //f의 최소값 구하기
  161.  
  162. //인접노드 검색 및 인덱스 저장
  163. POINT min;
  164. int count2 = 0;
  165. for (UINT y = 0; y < HeightNode; y++)
  166. {
  167. for (UINT x = 0; x < WidthNode; x++)
  168. {
  169. //검사 대상 선별
  170. if (Nodes.second.f && !Nodes.second.wall && !Nodes.second.close)
  171. {
  172. min.y = y;
  173. min.x = x;
  174. break;
  175. }
  176. count2++;
  177. }
  178. }
  179.  
  180. //더이상 최소값을 찾지 못하면 반복문 탈출
  181. if (count2 == WidthNode * HeightNode)
  182. break;
  183.  
  184. //실질적으로 minF를 구하는 곳
  185. for (UINT y = 0; y < HeightNode; y++)
  186. {
  187. for (UINT x = 0; x < WidthNode; x++)
  188. {
  189. //꺼낸 인덱스가 다른 노드보다 F값이 크면
  190. if (nodes[min.y][min.x].second.f > Nodes.second.f && !Nodes.second.wall && !Nodes.second.close)
  191. {
  192. //현재 노드를 인덱스에 다시저장
  193. min.y = y;
  194. min.x = x;
  195. }
  196. }
  197. }
  198. //왼쪽 구석 검사
  199. if (min.x != 0)
  200. {
  201. if (nodes[min.y][min.x - 1].second.g > 10 + nodes[min.y][min.x].second.g)
  202. {
  203. nodes[min.y][min.x - 1].second.g = 10 + nodes[min.y][min.x].second.g;
  204. nodes[min.y][min.x - 1].second.parent.x = min.x;
  205. nodes[min.y][min.x - 1].second.parent.y = min.y;
  206. }
  207. }
  208. //오른쪽
  209. if (min.x != WidthNode - 1)
  210. {
  211. if (nodes[min.y][min.x + 1].second.g > 10 + nodes[min.y][min.x].second.g)
  212. {
  213. nodes[min.y][min.x + 1].second.g = 10 + nodes[min.y][min.x].second.g;
  214. nodes[min.y][min.x + 1].second.parent.x = min.x;
  215. nodes[min.y][min.x + 1].second.parent.y = min.y;
  216. }
  217. }
  218. //위
  219. if (min.y != 0)
  220. {
  221. if (nodes[min.y - 1][min.x].second.g > 10 + nodes[min.y][min.x].second.g)
  222. {
  223. nodes[min.y - 1][min.x].second.g = 10 + nodes[min.y][min.x].second.g;
  224. nodes[min.y - 1][min.x].second.parent.x = min.x;
  225. nodes[min.y - 1][min.x].second.parent.y = min.y;
  226. }
  227. }
  228. //아래
  229. if (min.y != HeightNode - 1)
  230. {
  231. if (nodes[min.y + 1][min.x].second.g > 10 + nodes[min.y][min.x].second.g)
  232. {
  233. nodes[min.y + 1][min.x].second.g = 10 + nodes[min.y][min.x].second.g;
  234. nodes[min.y + 1][min.x].second.parent.x = min.x;
  235. nodes[min.y + 1][min.x].second.parent.y = min.y;
  236. }
  237. }
  238. //좌상
  239. if (min.x != 0 && min.y != 0)
  240. {
  241. if (nodes[min.y - 1][min.x].second.wall && nodes[min.y][min.x - 1].second.wall)
  242. {
  243.  
  244. }
  245. else if (nodes[min.y - 1][min.x - 1].second.g > 14 + nodes[min.y][min.x].second.g)
  246. {
  247. nodes[min.y - 1][min.x - 1].second.g = 14 + nodes[min.y][min.x].second.g;
  248. nodes[min.y - 1][min.x - 1].second.parent.x = min.x;
  249. nodes[min.y - 1][min.x - 1].second.parent.y = min.y;
  250. }
  251. }
  252. //좌하
  253. if (min.x != 0 && min.y != HeightNode - 1)
  254. {
  255. if (nodes[min.y + 1][min.x].second.wall && nodes[min.y][min.x - 1].second.wall)
  256. {
  257.  
  258. }
  259. else if (nodes[min.y + 1][min.x - 1].second.g > 14 + nodes[min.y][min.x].second.g)
  260. {
  261. nodes[min.y + 1][min.x - 1].second.g = 14 + nodes[min.y][min.x].second.g;
  262. nodes[min.y + 1][min.x - 1].second.parent.x = min.x;
  263. nodes[min.y + 1][min.x - 1].second.parent.y = min.y;
  264. }
  265. }
  266. //우상
  267. if (min.x != WidthNode - 1 && min.y != 0)
  268. {
  269. if (nodes[min.y - 1][min.x].second.wall && nodes[min.y][min.x + 1].second.wall)
  270. {
  271.  
  272. }
  273. else if (nodes[min.y - 1][min.x + 1].second.g > 14 + nodes[min.y][min.x].second.g)
  274. {
  275. nodes[min.y - 1][min.x + 1].second.g = 14 + nodes[min.y][min.x].second.g;
  276. nodes[min.y - 1][min.x + 1].second.parent.x = min.x;
  277. nodes[min.y - 1][min.x + 1].second.parent.y = min.y;
  278. }
  279. }
  280. //우하
  281. if (min.x != WidthNode - 1 && min.y != HeightNode - 1)
  282. {
  283. if (nodes[min.y + 1][min.x].second.wall && nodes[min.y][min.x + 1].second.wall)
  284. {
  285.  
  286. }
  287. else if (nodes[min.y + 1][min.x + 1].second.g > 14 + nodes[min.y][min.x].second.g)
  288. {
  289. nodes[min.y + 1][min.x + 1].second.g = 14 + nodes[min.y][min.x].second.g;
  290. nodes[min.y + 1][min.x + 1].second.parent.x = min.x;
  291. nodes[min.y + 1][min.x + 1].second.parent.y = min.y;
  292. }
  293. }
  294.  
  295. nodes[min.y][min.x].second.close = true;
  296.  
  297. //길 만들기
  298. if (nodes[min.y][min.x].second.goal)
  299. {
  300. POINT tempPoint; //MinF의 현재 위치 저장
  301. tempPoint.y = min.y;
  302. tempPoint.x = min.x;
  303.  
  304. POINT tempPoint2; //minG 의 부모 인덱스 저장
  305.  
  306. while (true)
  307. {
  308. //부모 저장
  309. tempPoint2.y = nodes[tempPoint.y][tempPoint.x].second.parent.y;
  310. tempPoint2.x = nodes[tempPoint.y][tempPoint.x].second.parent.x;
  311. //minF -> 부모로 변경
  312. tempPoint.y = tempPoint2.y;
  313. tempPoint.x = tempPoint2.x;
  314.  
  315. way.push_back(tempPoint);
  316.  
  317. //시작지점은 경로에서 제외
  318. //TempPoint가 시작 인덱스에 도달하면 반복문 종료
  319. if (nodes[tempPoint.y][tempPoint.x].second.start)
  320. break;
  321.  
  322. //부모 값이 이상한 경우
  323. if (tempPoint.y == Inf)
  324. {
  325. Reset();
  326. break;
  327. }
  328. //벡터가 한없이 커질 때
  329. if (way.size() == WidthNode * HeightNode)
  330. {
  331. Reset();
  332. break;
  333. }
  334.  
  335. }
  336. }
  337.  
  338.  
  339. }//while
  340.  
  341. }
  342.  
  343. void PathFinder::Update(D3DXMATRIX& V, D3DXMATRIX& P)
  344. {
  345.  
  346. for (UINT y = 0; y < HeightNode; y++)
  347. {
  348. for (UINT x = 0; x < WidthNode; x++)
  349. {
  350. Nodes.first->Update(V, P);
  351. }
  352. }
  353.  
  354. if (bReadToMove)
  355. {
  356. nodeType = NodeType::Start;
  357. bReadToMove = false;
  358. }
  359. else if (!bReadToMove)
  360. nodeType = NodeType::None;
  361.  
  362. //Mouse KeySetting
  363. if (Mouse->Down(1))
  364. nodeType = NodeType::Goal;
  365. else if (Mouse->Up(1))
  366. nodeType = NodeType::None;
  367.  
  368. if (Mouse->Press(0))
  369. nodeType = NodeType::Wall;
  370. else if (Mouse->Up(0))
  371. nodeType = NodeType::None;
  372.  
  373.  
  374. //ReStart
  375. if (VK_ESCAPE) Reset();
  376.  
  377. switch (nodeType)
  378. {
  379. case NodeType::Start: break;
  380. case NodeType::Goal: SetGoal(); SetStart(); break;
  381. case NodeType::Wall: SetWall(); break;
  382. }
  383.  
  384. if (Key->Down(VK_RETURN))
  385. FindPath();
  386.  
  387. }
  388.  
  389. void PathFinder::Render()
  390. {
  391. ImGui::Text("Node");
  392. ImGui::LabelText("StartPos", "%0.2f, %0.2f", startPos.x, startPos.y);
  393. ImGui::LabelText("GoalPos", "%0.2f, %0.2f", goalPos.x, goalPos.y);
  394. ImGui::LabelText("Node Type", "%d", nodeType);
  395.  
  396. for (UINT y = 0; y < HeightNode; y++)
  397. {
  398. for (UINT x = 0; x < WidthNode; x++)
  399. {
  400. //start Vec
  401. if (Nodes.second.start)
  402. {
  403. Nodes.first->Color(1, 1, 0); //노랑
  404. }
  405. //End Vec
  406. else if (Nodes.second.goal)
  407. {
  408. Nodes.first->Color(0, 1, 0); //초록
  409. }
  410. //wall
  411. else if (Nodes.second.wall)
  412. {
  413. Nodes.first->Color(1, 0, 0); //빨강
  414. }
  415. //close
  416. else if (Nodes.second.close)
  417. {
  418. Nodes.first->Color(0, 0, 1); //파랑
  419. }
  420. }
  421. }
  422.  
  423. //길
  424. for (UINT i = 0; i < way.size(); i++)
  425. {
  426. nodes[way[i].y][way[i].x].first->Color(1, 1, 1);
  427. }
  428. RenderText();
  429. for (UINT y = 0; y < HeightNode; y++)
  430. {
  431. for (UINT x = 0; x < WidthNode; x++)
  432. {
  433. Nodes.first->Render();
  434. }
  435. }
  436.  
  437.  
  438. }
  439.  
  440. UINT PathFinder::FindH(int startX, int startY, int goalX, int goalY)
  441. {
  442. int distanceX;
  443. int distanceY;
  444. int distance;
  445.  
  446. distanceX = abs(startX - goalX);
  447. distanceY = abs(startY - goalY);
  448.  
  449. return (distanceX + distanceY) * 10;
  450. }
  451.  
  452. void PathFinder::Reset()
  453. {
  454. for (UINT y = 0; y < HeightNode; y++)
  455. {
  456. for (UINT x = 0; x < WidthNode; x++)
  457. {
  458. Nodes.second.start = false;
  459. Nodes.second.goal = false;
  460. Nodes.second.wall = false;
  461. Nodes.second.f = Inf;
  462. Nodes.second.g = Inf;
  463. Nodes.second.h = Inf;
  464. Nodes.second.close = false;
  465. Nodes.second.parent.x = Inf;
  466. Nodes.second.parent.y = Inf;
  467.  
  468. Nodes.first->Color(0, 0, 0);
  469. }
  470. }
  471. way.clear();
  472. nodeType = NodeType::None;
  473. }
  474.  
  475. D3DXVECTOR2 PathFinder::Position()
  476. {
  477. return D3DXVECTOR2();
  478. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement