전술 RPG를위한 알고리즘?


15

C ++에서 매우 나쁜 전술 RPG를 작성하는 데 어려움을 겪고 있습니다. 지금까지 2D 타일 맵이 있으며 wikipedia 의 의사 코드를 기반으로 A * 알고리즘이 작동했습니다 .

그러나 실제 전술 RPG는 평평한 비행기에서 가장 좋은 길을 찾아 이동하지 않습니다. 이동 범위가 제한되어 있으며 위 또는 아래로 올라 가야합니다. 파이널 판타지 전술을 사용한 적이 있다면 이동 및 점프 통계에 영향을받습니다. 내가 잃어버린 곳이야 대상으로 향하는 가장 좋은 경로를 찾도록 A * 알고리즘을 변경하려면 어떻게해야합니까? 키 차이와 통계를 어떻게 고려해야합니까? 격차를 뛰어 넘는 방법은 무엇입니까?

도움이된다면 지금 내지도는 Vector of Tile 객체로 표현됩니다. 각 타일에는 북쪽, 남쪽, 동쪽 및 서쪽 타일에 대한 포인터가 있으며,지도의 가장자리를 따라 타일이 없거나 타일을 통과 할 수없는 경우 nullptr로 설정됩니다.


5
왜 이동 범위가 문제인지 모르겠습니다. 최단 경로를 찾은 다음 해당 경로를 따라 '속도'사각형을 이동하십시오.
Mooing Duck

답변:


33

등반과 격차는 다른 비용 함수입니다. 갭을 뛰어 넘을 수있는 유닛의 경우 보통 (?) 비용이 있고, 비 점프 유닛의 경우 임의로 높은 비용이 있습니다. 어려운 지형과 마찬가지로 상승 비용이 추가됩니다. A * 알고리즘은 비용 함수를 잘 처리 할 수 ​​있으므로 구현이 아직 수행하지 않는 경우 비용 함수로 A *를 구현하는 방법에 대해 Google에 문의하십시오.

그러나 A *가 전술 RPG에 특히 좋은 접근 방법이라고 생각하지 않습니다. 더 정확하게는 완전한 이야기가 아닙니다. 당신은 당신의 유닛이 그들의 목표를 맹목적으로 엉망으로 만들지 않기를 원하며, 궁극적 인 목표를 향해 나아가고 적들과 맞서기 위해 노력하는 동안, 자신들이 엄폐물, 높은지면을 이용하기 위해 자신을 위치시키기를 원합니다. 따라서 각 움직임의 종점의 전술적 가치는 목표가 얼마나 가까운지가 아니라 매우 중요합니다. 이를 위해서는 단순한 길 찾기보다 더 심층적 인 문제 해결이 필요합니다.


10
'전술적 포지셔닝'에 대한 장점은 있지만 이러한 결정은 기본 경로 찾기보다 높은 수준에서 적용될 수 있습니다. 반면에, 일종의 전술 분석기에 의해 생성 된 경로 찾기 알고리즘의 노드에 비용을 적용하는 것이 좋은 옵션 일 수 있습니다. 예를 들어, 적에게 지형을 가로 질러 가시선이있는 경우 해당 지형의 노드가 매우 높은 비용이되도록합니다.
DrMcCleod

1
@DrMcCleod : 사실, 그것은 "더 정확하게 말하면, 완전한 이야기가 아닙니다"라는 의미입니다. 처리의 일부를 수행하기 위해 확실히 A * 또는 다른 알고리즘을 사용할 수는 있지만 유닛이 발사 될 수있는 지형을 가로 질러 이동하는 것이 더 잘 처리되기 때문에 이동 비용을 통해 감시 노드를 피하는 것과 같은 접근법을 피할 것이라고 생각합니다 위험 / 보상 계산, IMO.
Jack Aidley

13

유닛의 모든 가능한 이동 옵션을 원할 경우 Dijkstra 's Algorithm을 사용하십시오 .

A *와 Dijkstra의 차이점은 Dijkstra가 주어진 비용으로 달성 할 수있는 가장 짧은 경로를 모두 제공한다는 것입니다. 반면에 A *는 목적지에 도달 할 수있는 좋은 경로를 먼저 계산하는 것을 선호합니다.

따라서 A 지점에서 B 지점까지의 최단 경로를 원할 경우 A *가 좋습니다. 그러나 모든 가능한 이동 옵션과 각각의 최단 경로를 원한다면 Dijkstra가 원하는 것입니다.

Dijksta의 알고리즘을 특정 대상 노드없이 실행하지만 최대 비용을 초과해서는 안됩니다 (단위 이동 범위). 노드로 여행 할 때 최대 비용을 초과하면 방문하지 마십시오. 방문하지 않은 에지가 부족하여 알고리즘이 종료되면 방문 세트의 각 노드가 가능한 대상이며 노드의 이전 노드 마커는 초기 노드까지의 경로를 나타내는 링크 된 목록을 형성합니다.

점프와 관련하여 : A *와 Dijkstra에서 또 다른 엣지로 표현 될 수 있습니다. 일반 모서리를 횡단하거나 다른 모서리를 횡단하는 것과 동일한 비용이 발생할 수 있습니다. "jump_height"매개 변수를 알고리즘에 전달하면 알고리즘이 지정된 높이를 초과하는 점프 에지를 무시하도록 지시합니다.


9
여기서 언급 할 가치가있는 A*것은 실제로 Dijkstra의 일반 화일 뿐이므로, 하나를 이해하면 다른 것을 이해하기가 너무 어렵지 않아야합니다.
큐빅

8
실제로 A * 알고리즘에서 0 만 반환하는 휴리스틱이 있으면 축하합니다! Dijkstra의 알고리즘을 작성했습니다.
Yann

9
"Dijkstra는 주어진 비용으로 달성 할 수있는 가장 짧은 경로를 모두 제공합니다. 목적지 중 어느 것도 목적지에 도달하지 못하면 비용이 1 씩 증가하고 계속됩니다." -그것이 작동하는 방식이나 출력되는 것이 아닙니다. 실제로 가중 그래프에 대한 너비 우선 검색을 일반화 한 것입니다. 하나의 최단 경로를 찾습니다. A *는 거리 휴리스틱을 사용할 수있는 경우에 대한 일반화입니다.
BlueRaja-대니 Pflughoeft

1
이것이 왜 그렇게 공명되었는지 잘 모르겠습니다. 실용적인 관점에서 Dijkstra는 더 이상 사용되지 않습니다. 교육 및 역사적 이유로 CS에서 진행됩니다. A *조차도 심각한 작업에는 더 이상 사용되지 않습니다. Google지도는 확실히 사용하지 않습니다. 요즘에는 ArcGraph 변형을보고 계실 것입니다.
MSalters

2
@MSalters Dijkstra 및 A *는 전술 RPG와 같은 간단한 문제에 대한 완벽한 알고리즘입니다. 유효한 타일 (타일)의 범위는 매우 좁으며 타일을 가로 질러 이동할 수있는 매우 제한된 방법이 있습니다 (직각 형, 때로는 대각선). 계산적으로, 현대 기계에서는 상당히 작은 값이 무엇인지에 대한 차이를 무시할 수 있으므로 여기에 설명 된 목적에 대해 간단한 것이 충분할 때 더 복잡한 구현을 방해하는 이유는 무엇입니까?
Valthek

2

다른 답변에는 좋은 정보가 있으므로 반드시 읽으십시오.

그러나 귀하의 질문에 대답하기 위해 : 연결된 의사 코드를 기반으로 heuristic_cost_estimatetileA에서 tileB까지의 비용을 계산하는 일종의 기능 이 있습니다 (인접한 것으로 가정). 해당 비용에 플랫 (1)을 사용하는 대신 타일 통계와 단위 통계 및 가장자리 통계를 포함하도록 조정해야합니다.

예를 들면 다음과 같습니다.

if (edge == JUMP && !unit.canJump()) 
    return INF;
if (tile.Type == Forest && unit.moveType == HORSE) 
    return 2;
//Other cases here
//-----
else 
    return 1;

이것은 당신에게 당신의 길을 줄 것입니다. 그런 다음 이동 지점을 소비하면서 경로를 따라 장치를 이동하고 나머지 포인트 <edgeCost 일 때 중지합니다. 잔류 점수 = 1로 끝나는 경우에는 이것이 최적이 아닐 수 있지만 실습 RPG에는 충분해야합니다. 실제로 Jack Aidley가 지적한 것처럼 더 전술적 인 방법을 원할 것입니다!

도전 과제 :
더 발전하려면 X 거리 내의 모든 공간을 찾기 위해 제안 된대로 지 익스트라를 사용하고 싶을 것입니다. 그러면 목록의 각 공간을 목표와의 근접성, 방어력에 따라 "최고의"장소로 평가하려고합니다 해당 정보를 기반으로 타일을 선택한 다음 지 익스트라를 사용하여 방금 계산 한 경로를 따라 이동합니다.


1

등반 비용과 갭은 비용 만 수정하기 때문에 사소한 문제입니다. 길 찾기 (및 대부분의 전술 AI)는 방문 할 모든 노드의 비용을 합산하여 최소화하는 것입니다. 통과 할 수없는 절벽은 무한한 (매우 높음) 비용을 가지며, 경사면은 정상보다 비용이 높습니다.

그러나 이것은 실제 적 들이 최적의 경로를 찾지 하기 때문에 최상의 해결책이 아닌 전 세계적으로 최적의 경로를 찾습니다. 그것은 비현실적이며 때로는 플레이어에게 명백하고 성가신 점입니다 (특히 AI도 기본적으로 무적입니다. 최적화를 선택하기 때문에).

좋은 시뮬레이션은 의도적으로 최상의 경로를 찾지 못합니다. 훨씬 더 좋은 알고리즘은 계층 적 경로 찾기를 수행하는 것입니다. 다른 방법이 없다면지도에 직선을 그려 4-5 개의 웨이 포인트를 취한 다음 지금까지의 노드 가중치 만 고려하여 한 웨이 포인트에서 다음 웨이 포인트로 경로 찾기 알려진 다른 노드 weigth를 "무관심"으로 설정합니다. 또는 더 거친 그리드에서 A *를 먼저 실행 한 다음 큰 노드에서 다음 노드로 경로를 찾을 수 있습니다 (그러나지도에 선을 그리는 것도 좋습니다).

이것은 훨씬 더 현실적이며 그래프가 훨씬 작기 때문에 처리 능력의 일부를 소비합니다 . 예, 유닛이 절벽을 향해 움직일 수 없다는 것을 알기 위해서만 절벽을 향해 움직일 수 있습니다. 괜찮아요, 진짜 적들도 마찬가지입니다. 다음 번에는 다시 발생하지 않습니다 (이제 무한한 비용이 알려져 있기 때문에).


1
"간단한 계층 적 경로 찾기"는 꽤 어리석은 것처럼 보일 수 있습니다. 산등성이로 곧장 걸어가는 길을 막는 경로 만 발견됩니다. 그런 다음 산길을 통과하여 다음 웨이 포인트로 이동합니다. 전처리 과정에서 산이 앞을 향하고 경유지를 통과했음을 확인했을 것입니다. 그러나 그렇게하지 않더라도 계획된 과정을 벗어나면 나머지 계획을 다시 세워야합니다.
MSalters

@MSalters : 첫 번째 시도 후에도 "라인 그리기"방법으로 발생할 수 있습니다. 거친 그리드 계층 적 방법 (예 : 평균, 중간 값 또는 노드 내 최대 비용 값)을 사용하면 두 번 이상 발생할 가능성이 없습니다. 그것은 인간의 적들이 어떻게 행동하는지와 거의 똑같습니다. 당신이 알고 있거나 산 사슬처럼 멀리서 볼 수있는 큰 장애물 피하고 , 그렇지 않으면 거친 직선 경로를 계획하고 길을 물으십시오. 산이 있다는 것을 알지 못하면 곧장 산으로갑니다.
데이먼
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.