์์ ๋ ธ๋์ ๋ชฉ์ ์ง ๋ ธ๋๋ฅผ ๋ถ๋ช ํ๊ฒ ์ง์ ํด ๋ ๋ ธ๋ ๊ฐ์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ํ์ ํ๋ ์๊ณ ๋ฆฌ์ฆ
- A* ์๊ณ ๋ฆฌ์ฆ์ ์ ํํ ์ต๋จ ๊ฒฝ๋ก ๋ณด๋ค๋ ์ต๋จ ๊ฒฝ๋ก์
๊ทผ์ฌ๊ฐ
์ ๊ตฌํ๋ค - ํ์ฌ ์์น๊ฐ ์ผ๋ง๋ ์ข์ ์์น์ธ์ง
์ ๋นํ ํด๋ฆฌ์คํฑ ํจ์
๋ฅผ ํตํด ์ถ์ ํ์ฌ ์ ์๋ฅผ ๋งค๊ธด๋ค - ์ ํํ ์ ๋ต์ ํฌ๊ธฐํ ๋์ ํ์ ์๋๋ ๋ค์ต์คํธ๋ผ์ ๋นํด ํจ์ฌ ๋น ๋ฅด๋ค
๋ค์์ ์ด๋ค ๋ ธ๋๋ฅผ ์ ํํ ์ง์ ๋ํ ์ฑ์ ์ด ์ด๋ฃจ์ด์ง๋ค
- F: ํ์ฌ๊น์ง ์ด๋ํ๋๋ฐ ๊ฑธ๋ฆฐ ๋น์ฉ๊ณผ ์์ ๋น์ฉ์ ํฉ์น ์ด ๋น์ฉ
- G: ์์์ ์ผ๋ก๋ถํฐ ํ์ฌ ๋ ธ๋๊น์ง์ ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ผ ์ด๋ํ๋๋ฐ ์์๋๋ ๋น์ฉ
- H: ํ์ฌ ๋ ธ๋๋ก๋ถํฐ ๋ชฉ์ ์ง๊น์ง์ ์์๋๋ ์์ ๋น์ฉ
์ด๋ฆผ์ง์, ์ฃผ๋จน ๊ตฌ๊ตฌ์ ๋ฑ์ผ๋ก ๋ถ๋ฆฌ๋ฉฐ ๊ฒฝํ์ ๊ธฐ๋ฐํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ฑฐ๋ ๋ฐ๊ฒฌํด๋ด๋ ๋ฐฉ๋ฒ์ด๋ค.
- ์ด์์ ๊ทธ๋ฆฌ์ค์ด
Heutiskein
์ผ๋ก ์ฐพ์๋ด๋ค, ๋ฐ๊ฒฌํ๋ค ๋ผ๋ ๋ป์ด๋ค
ํด๋ฆฌ์คํฑ์ด๋ ์ํฉ๊ณผ ์ง๊ด์ ๋ฐ๋ผ ํ๋ํ์ฌ ์ํ์ฐฉ์ค๋ฅผ ๊ฒช๊ณ ์ง์์ ์ป์ด ์๊ฐ์ ๋ฐ์ ์ํค๋ ๋ฐฉ๋ฒ์ด๋ค
๊ฐ ์ขํ์ ์ฐจ๋ฅผ ๋ชจ๋ ๋ํ ๊ฒ์ ๊ฑฐ๋ฆฌ๋ก ํ๋ค
$|x1-x2| + |y1-y2|$
์ฐ๋ฆฌ๊ฐ ์ค์ํ์์ ์ฌ์ฉํ๋ ๊ฑฐ๋ฆฌ๋ ์ ํด๋ฆฌ๋ ๊ฑฐ๋ฆฌ
๋ก ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ค
$\sqrt{(x1-x2)^2 + (y1-y2)^2}$
// ์ ์ ๋งค๊ธฐ๊ธฐ
// F = G + H
// F = ์ต์ข
์ ์ (์์ ์๋ก ์ข์, ๊ฒฝ๋ก์ ๋ฐ๋ผ ๋ฌ๋ผ์ง)
// G = ์์์ ์์ ํด๋น ์ขํ๊น์ง ์ด๋ํ๋๋ฐ ๋๋ ๋น์ฉ (์์ ์๋ก ์ข์, ๊ฒฝ๋ก์ ๋ฐ๋ผ ๋ฌ๋ผ์ง)
// H = ๋ชฉ์ ์ง์์ ์ผ๋ง๋ ๊ฐ๊น์ด์ง (์์ ์๋ก ์ข์, ๊ณ ์ )
Pos start = _pos;
Pos dest = _board->GetExitPos();
enum
{
DIR_COUNT = 8
};
Pos front[] =
{
Pos { -1, 0}, // UP
Pos { 0, -1}, // LEFT
Pos { 1, 0}, // DOWN
Pos { 0, 1}, // RIGHT
Pos {-1, -1}, // UP_LEFT
Pos {1, -1}, // DOWN_LEFT
Pos {1, 1}, // DOWN_RIGHT
Pos {-1, 1}, // UP_RIGHT
};
int32 cost[] =
{
10, // UP
10, // LEFT
10, // DOWN
10, // RIGHT
14,
14,
14,
14
};
const int32 size = _board->GetSize();
// ClosedList
// close[y][x] -> (y, x)์ ๋ฐฉ๋ฌธ์ ํ๋์ง ์ฌ๋ถ
vector<vector<bool>> closed(size, vector<bool>(size, false));
// best[y][x] -> ์ง๊ธ๊น์ง (y, x)์ ๋ํ ๊ฐ์ฅ ์ข์ ๋น์ฉ (์์ ์๋ก ์ข์)
vector<vector<int32>> best(size, vector<int32>(size, INT32_MAX));
// ๋ถ๋ชจ ์ถ์ ์ฉ๋
map<Pos, Pos> parent;
// OpenList
priority_queue<PQNode, vector<PQNode>, greater<PQNode>> pq;
// 1) ์์ฝ(๋ฐ๊ฒฌ) ์์คํ
๊ตฌํ
// - ์ด๋ฏธ ๋ ์ข์ ๊ฒฝ๋ก๋ฅผ ์ฐพ์๋ค๋ฉด ์คํต
// 2) ๋ค๋ฆ๊ฒ ๋ ์ข์ ๊ฒฝ๋ก๊ฐ ๋ฐ๊ฒฌ๋ ์ ์์ -> ์์ธ ์ฒ๋ฆฌ ํ์
// - openList์์ ์ฐพ์์ ์ ๊ฑฐํ๋ค๊ฑฐ๋.
// - pq์์ popํ ๋ค์์ ๋ฌด์ํ๋ค๊ฑฐ๋.
// ์ด๊ธฐ๊ฐ
{
int32 g = 0;
int32 h = 10 * (abs(dest.y - start.y) + abs(dest.x - start.x));
pq.push(PQNode{ g + h, g, start });
best[start.y][start.x] = g + h;
parent[start] = start;
}
while (pq.empty() == false)
{
// ์ ์ผ ์ข์ ํ๋ณด๋ฅผ ์ฐพ๋๋ค
PQNode node = pq.top();
pq.pop();
// ๋์ผํ ์ขํ๋ฅผ ์ฌ๋ฌ ๊ฒฝ๋ก๋ก ์ฐพ์์\
// ๋ ๋น ๋ฅธ ๊ฒฝ๋ก๋ก ์ธํด์ ์ด๋ฏธ ๋ฐฉ๋ฌธ(closed)๋ ๊ฒฝ์ฐ ์คํต
// [์ ํ]
if (closed[node.pos.y][node.pos.x])
continue;
if (best[node.pos.y][node.pos.x] < node.f)
continue;
// ๋ฐฉ๋ฌธ
closed[node.pos.y][node.pos.x] = true;
// ๋ชฉ์ ์ง์ ๋์ฐฉํ์ผ๋ฉด ๋ฐ๋ก ์ข
๋ฃ
if (node.pos == dest)
break;
for (int32 dir = 0; dir < DIR_COUNT; dir++)
{
Pos nextPos = node.pos + front[dir];
// ๊ฐ ์ ์๋ ์ง์ญ์ ๋ง๋์ง ํ์ธ
if (CanGo(nextPos) == false)
continue;
// [์ ํ] ์ด๋ฏธ ๋ฐฉ๋ฌธํ ๊ณณ์ด๋ฉด ์คํต
if (closed[nextPos.y][nextPos.x])
continue;
// ๋น์ฉ ๊ณ์ฐ
int32 g = node.g + cost[dir];
int32 h = 10 * (abs(dest.y - nextPos.y) + abs(dest.x - nextPos.x));
// ๋ค๋ฅธ ๊ฒฝ๋ก์์ ๋ ๋น ๋ฅธ ๊ธธ์ ์ฐพ์์ผ๋ฉด ์คํต
if (best[nextPos.y][nextPos.x] <= g + h)
continue;
// ์์ฝ ์งํ
best[nextPos.y][nextPos.x] = g + h;
pq.push(PQNode{ g + h, g, nextPos });
parent[nextPos] = node.pos;
}
}
// ๊ฑฐ๊พธ๋ก ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ๋ค
Pos pos = dest;
_path.clear();
_pathIndex = 0;
while (true)
{
_path.push_back(pos);
// ์์์ ์ ์์ ์ด ๊ณง ๋ถ๋ชจ์ด๋ค
if (pos == parent[pos])
break;
pos = parent[pos];
}
std::reverse(_path.begin(), _path.end());