Показ діапазону на шестикутній сітці


10

Ось така ситуація.

У мене є шестикутна дошка, і одиниця на ній, зі швидкістю або значенням переміщення 4. Різна місцевість має різну вартість. Коли я натискаю на пристрій, гра повинна показувати мені дальність руху.

Моє рішення полягало в тому, щоб перевірити кожен шестигранник у діапазоні 4, за допомогою A * накладання маршруту, і якщо вартість шляху була меншою за 4, то ця шестигранна знаходилася в діапазоні. Насправді гра добре показала мені діапазон цієї одиниці.

Моє запитання: чи є інше рішення для пошуку діапазону на шестигранних сітках або квадратній сітці, тому що навіть якщо я справді пишаюся тим, що я зробив у своєму рішенні, я думаю, це трохи перебільшено? :))

Що змушує мене задати це питання? Я помітив, що коли швидкість одиниці становить 4 або 6 або навіть 8, час на обчислювальний діапазон для мого комп'ютера був справді хорошим, але коли швидкість становила 10 і більше, я помітив, що мені потрібно почекати кілька секунд, щоб обчислити .У реальних іграх я, швидше, не бачу подібного, і мій A * прокручування досить добре оптимізований, тому я думаю, що моє рішення неправильне.

Дякую за будь-які відповіді.


1
Я погоджуюся з Byte56, що алгоритм пошуку першого ширини є хорошим рішенням. Це не означає, що ви не повинні намагатися бути творчими, але, наскільки добре відомі алгоритми, це хороший варіант, який добре застосовується.
theJollySin

Відповіді:


11

Ви маєте рацію, що A * - це трохи надмірність, але не набагато. Ви не повинні бачити затримок, як ви. A * - це лише модифікований алгоритм Діжикстри . Оскільки ви не використовуєте кінцеву позицію (оскільки ваша кінцева позиція просто "наскільки ви можете піти"), використання A * з додаванням евристики не є необхідним. Просто використання Dijikstra або простого широти першого пошуку буде достатньо.

Наприклад, Дікікстра рівномірно розподілиться в усіх напрямках:

введіть тут опис зображення

(Простий широта першого пошуку буде схожа на цю)

Слідкуйте за витратами на проїзд до кожного вузла. Як тільки вузол має максимальну вартість поїздки, більше не обробляйте його підключені вузли. (Аналогічно тому, де вузли впадають у стіну внизу).

Якщо у вас виникають проблеми з продуктивністю лише на 10 вузлів, вам потрібно буде переглянути, як ви отримуєте доступ до вузлів. Широкий перший пошук повинен мати можливість переміщатися по сотню вузлів без помітної затримки (звичайно, не на кілька секунд). Розгляньте можливість зберігання простої версії вашого світу у графічному форматі для швидкого переходу.


Ви можете знайти відстань між двома вузлами за допомогою BFS та врахувавши перешкоди / різні ваги?
Лука Б.

Вартість переміщення між вузлами здебільшого повинна бути попередньо обчислена. Вартість не розраховується за допомогою BFS, BFS - алгоритм переходу вузлів. Як ви визначаєте вартість проїзду з одного вузла на інший, не залежить від того, як ви проходите через вузли.
MichaelHouse

Дякую, тепер я бачу, чому моє мислення було неправильним, ключовим для цього було таке твердження "Оскільки ви не використовуєте кінцеву позицію (оскільки ваша кінцева позиція просто" наскільки ви можете піти ")". У своєму рішенні я було закінчення, це був блок. Я просто вирішив проблему з неправильного напрямку. Спочатку я визначив кордон, а потім звідти я повернувся до свого підрозділу, таким чином я, ймовірно, багато разів проходив через ті самі вузли. коли моя швидкість збільшується, кількість обчислень збільшується також багато. Як ви мені показуєте, я завжди відвідуватиму вузол один раз. У мене просто була неправильна точка зору, дійсно дякую, це спрощує багато.
user23673

4

Amit Patel забезпечив чудовий ресурс для отримання діапазонів на своєму сайті . У статті він використовує наступний алгоритм збирання шестигранних плиток у межах діапазону:

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)))

Це створює межі, вирівняні з шестигранною сіткою:

введіть тут опис зображення

Це знайде всі шестигранники на певній відстані від центральної шестигранниці, якщо ви хочете розглянути перешкоди, скористайтеся першим пошуком у широті від моєї іншої відповіді.


1

Якщо комусь це потрібно, ось реалізація алгоритму Пателя 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;
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.