육각 격자에 표시 범위


10

여기 상황이 있습니다.

나는 육각형 보드를 가지고 있으며, 속도 또는 이동 값이있는 장치가 있습니다. 4. 다른 지형에는 다른 비용이 있습니다. 단위를 클릭하면 게임에 이동 범위가 표시되어야합니다.

내 솔루션은 A * 경로 찾기를 사용하여 4 개의 범위에서 각 16 진수를 확인하고 경로 비용이 4 미만인 경우이 16 진수가 범위 내에 있습니다. 마침내 게임은 그 장치의 범위를 멋지게 보여줍니다.

내 질문은 : 내 솔루션에서 실제로 한 일을 자랑스럽게 생각하더라도 16 진수 그리드 또는 사각형 그리드에서 범위를 검색하는 다른 솔루션이 있습니까?

단위 속도가 4 또는 6 또는 8 일 때 컴퓨터의 컴퓨팅 범위까지 걸리는 시간이 실제로 좋았지 만 속도가 10 이상인 경우 계산을 위해 몇 초 정도 기다려야한다는 것을 알았습니다. . 실제 게임에서는 오히려 이와 같은 것을 보지 못하고 내 A * 경로 찾기는 다소 최적화되어 있으므로 내 솔루션이 잘못되었다고 생각합니다.

답장을 보내 주셔서 감사합니다.


1
광범위한 첫 번째 검색 알고리즘이 좋은 솔루션이라는 Byte56에 동의합니다. 이것은 창의성을 발휘하려고하지 말아야 할 것이 아니라 잘 알려진 알고리즘이 적용되는 한 잘 적용되는 알고리즘입니다.
theJollySin

답변:


11

A *는 약간 과잉이지만 많은 것은 아닙니다. 당신처럼 지연이 보이지 않아야합니다. A *는 실제로 수정 된 Dijikstra의 알고리즘 입니다. 종료 위치를 사용하지 않기 때문에 (종료 위치는 "가능한 한"가능하므로) 휴리스틱이 추가 된 A *를 사용할 필요는 없습니다. Dijikstra 또는 간단한 너비 우선 검색 만으로 충분합니다.

예를 들어 Dikikstra는 모든 방향으로 고르게 퍼집니다.

여기에 이미지 설명을 입력하십시오

(간단한 너비의 첫 번째 검색은 이와 유사합니다)

각 노드로 이동하는 비용을 추적하십시오. 노드가 최대 이동 비용에 도달하면 연결된 노드를 더 이상 처리하지 마십시오. (노드가 아래 벽으로 들어가는 곳과 유사합니다).

10 개의 노드만으로 성능 문제가 발생하는 경우 노드에 액세스하는 방법을 살펴보고 싶을 것입니다. 광범위한 첫 번째 검색은 눈에 띄는 지연없이 (몇 초가 아닌) 수백 개의 노드를 탐색 할 수 있어야합니다. 간단한 순회를 위해 간단한 세계 버전을 그래프 형식으로 저장해보십시오.


BFS를 사용하고 장애물 / 다른 가중치를 고려하여 두 노드 사이의 거리를 찾을 수 있습니까?
Luke B.

노드 간 이동 비용은 대부분 사전 계산되어야합니다. 비용은 BFS를 사용하여 계산되지 않으며 BFS는 노드를 순회하기위한 알고리즘입니다. 한 노드에서 다른 노드로 이동하는 비용을 결정하는 방법은 노드를 순회하는 방법과 무관합니다.
MichaelHouse

고마워, 이제 내 생각이 왜 틀렸는 지 알 수 있는데, 그 핵심은 "당신은 끝 위치를 사용하지 않기 때문에 (끝 위치가"가서 할 수있는 한 "") "라는 진술이었습니다. 끝 위치가 있었는데 그것은 단위였습니다. 방금 잘못된 방향으로 문제를 해결했습니다. 먼저 국경을 결정한 다음 거기에서 다시 같은 단위로 여러 번갔습니다. 내 속도가 증가하면 계산 횟수도 많이 증가합니다. 표시하는 방식은 항상 노드를 한 번 방문합니다.
user23673

4

Amit Patel은 자신의 사이트에서 범위얻는 데 훌륭한 자료를 제공했습니다 . 이 기사에서 그는 범위 내에서 16 진 타일을 수집하기 위해 다음 알고리즘을 사용합니다.

for each -N  Δx  N:
    for each max(-N, x-N)  Δy  min(N, x+N):
        Δz = xy
        results.append(H.add(Cubex, Δy, Δz)))

이것은 16 진 그리드와 정렬 된 경계를 만듭니다 :

여기에 이미지 설명을 입력하십시오

이것은 중심 16 진수의 특정 거리 내에있는 모든 육각형을 찾을 것입니다. 장애물을 고려하고 싶다면 다른 대답에서 너비 우선 검색을 사용하십시오.


1

누군가가 필요로하는 경우 Patel 알고리즘의 C # 구현은 다음과 같습니다.

IEnumerable<Hex> GetRange(Hex center, int range)
    {
        var inRange = new List<Hex>();
        for (int q = -range; q <= range; q++)
        {
            int r1 = Math.Max(-range, -q - range);
            int r2 = Math.Min(range, -q + range);
            for (int r = r1; r <= r2; r++)
            {
                inRange.Add(center.Add(new Hex(q, r, -q - r)));
            }
        }

        return inRange;
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.