항상 플레이어가 오른족으로 갈 수 있는지 확인하는 방법. 디아블로 동굴 맵 밝힐 때 주로 쓰는 그 방법을 코드로 표현.
Init 함수에서 우수법으로 지나갈 길을 전부 저장하고 Update 함수에서 플레이어를 저장한 포지션으로 순서대로 이동 시킨다.
Stack 으로 막다른 길의 Pos 를 전부 삭제 시킨다.
void Player::Init(Board* board)
{
_pos = board->GetEnterPos();
_board = board;
Pos pos = _pos;
_path.clear();
_path.push_back(pos);
// 목적지 도착하기 전에는 계속 실행
Pos dest = board->GetExitPos();
Pos front[4] =
{
Pos {-1,0}, // UP
Pos {0,-1}, // LEFT
Pos {1,0}, // DOWN
Pos {0,1}, // RIGHT
};
while (pos != dest)
{
// 1. 현재 바라보는 방향을 기준으로 오른쪽으로 갈 수 있는지 확인
int32 newDir = (_dir - 1 + DIR_COUNT) % DIR_COUNT;
if (CanGo(pos + front[newDir]))
{
// 오른쪽 방향으로 90도 회전.
_dir = newDir;
// 앞으로 한 보 전진
pos += front[_dir];
_path.push_back(pos);
}
// 2. 현재 바라보는 방향을 기준으로 전진할 수 있는지 확인.
else if (CanGo(_pos + front[_dir]))
{
// 앞으로 한 보 전진.
pos += front[_dir];
_path.push_back(pos);
}
else
{
// 왼쪽 방향으로 90도 회전.
_dir = (_dir + 1) % DIR_COUNT;
/*switch (_dir)
{
case DIR_UP:
_dir = DIR_LEFT;
break;
case DIR_LEFT:
_dir = DIR_DOWN;
break;
case DIR_DOWN:
_dir = DIR_RIGHT;
break;
case DIR_RIGHT:
_dir = DIR_UP;
break;
}*/
}
}
// 막힌 길 쪽의 포지션을 없애는 작업
stack<Pos> s;
for (int i = 0; i < _path.size() - 1; ++i)
{
if (s.empty() == false && s.top() == _path[i + 1])
{
s.pop();
}
else
s.push(_path[i]);
}
// 목적지 도착
if (_path.empty() == false)
{
s.push(_path.back());
}
vector<Pos> path;
while (s.empty() == false)
{
path.push_back(s.top());
s.pop();
}
std::reverse(path.begin(), path.end());
_path = path;
}
void Player::Update(uint64 deltaTick)
{
if (_pathIndex >= _path.size())
{
return;
}
if (_sumTick >= MOVE_TICK)
{
_sumTick = 0;
_pos = _path[_pathIndex];
_pathIndex ++ ;
}
_sumTick += deltaTick;
}
bool Player::CanGo(Pos pos)
{
TileType tileType = _board->GetTileType(pos);
return tileType == TileType::EMPTY;
}
'자료구조 알고리즘' 카테고리의 다른 글
길찾기3 다익스트라 길찾기 (0) | 2024.05.29 |
---|---|
길찾기2 BFS 를 이용하기 (0) | 2024.05.29 |
레드 블랙 트리 (1) | 2024.05.29 |
이진 탐색 트리 (0) | 2024.05.29 |
힙으로 구현한 우선순위 큐 (0) | 2024.05.29 |