Щоб успішно застосувати min / max до покрокової стратегічної гри, потрібно правильно застосувати всі доступні шахові прийоми ...
Функція оцінювання
Навіть шахові двигуни мають дуже погану міцність, якщо ваші функції оцінки погані. Найпростіший варіант функції оцінювання: 1 = гра, виграна білим, -1 = гра, виграна чорним, 0 = всі інші випадки; Але це призведе до дуже поганих показників. Те саме відбувається з вашою покроковою грою! Якщо ви хочете використовувати min / max (з обрізкою альфа / бета та інше), як у шахах, ви також повинні застосувати розумну оціночну функцію! Крім того, ви не можете порівнювати ефективність цих алгоритмів при застосуванні до стратегічної гри з випадком, який застосовується до шахів.
Те, що виконують функції оцінювання шахових двигунів, - це оцінка таких предметів:
- Наскільки добре розташоване положення шматка на дошці?
- Скільки разів напав шматок?
- Скільки разів захищається шматок?
- Наскільки добре кожен твір може вільно «рухатися» по дошці? (або: скільки плиток "контролює")
Ці частини функції оцінювання потрібно спочатку "перекласти" у вашу гру:
- Положення штуки: Це, наприклад, на пагорбі, який розширює дальність стрільби?
- Нападник: Скільки загрожує кожен шматок? (наприклад, сума значень атаки одиниць, здатних атакувати спеціальний підрозділ, помножена на деяку ймовірність нападу на нього; ймовірність збільшується, якщо одиниця вже пошкоджена; зменшується, якщо багато інших одиниць знаходяться в зоні дії атакуючої частини)
- Власна атака: Скільки одиниць може напасти на кожну одиницю?
- Захист: Скільки власних штук поруч (на допомогу)? Можливо, підрозділ може не атакувати підрозділи на мінімальній відстані, а краще захистити його одиницею, що має можливість атакувати поблизу підрозділи.
- Мобільність: Наскільки мобільний ваш пристрій? (може втекти?)
Різні оцінки повинні бути підсумовані за функцією зважування (factor_a * rating_a + factor_b * ranting_b + ...) для всіх одиниць ...
У стратегічних іграх також слід враховувати залишені ресурси (золото, дерево, ...).
Якщо ваша оцінювальна функція є достатньою, у більшості випадків вам не потрібно справді шукати "глибоко" в дереві. Тож вам, мабуть, потрібно лише детальніше ознайомитись з 3 або 10 найбільш перспективними варіантами. Дивіться наступний розділ ...
Можливі рухи в кожній позиції
Найбільш проблематичним питанням використання min / max для стратегічних ігор є те, що ви можете командувати декількома одиницями за один оборот, тоді як у шахах вам дозволяється командувати лише одним блоком (за винятком кастингу, але це чітко визначена комбінація руху). Це спричиняє 5 ^ N можливих переміщень для N одиниць для кожної «позиції» (шаховий термін), якщо ви вирішите лише «рухатись на північ, південь, захід, схід АБО зупинка» для кожної одиниці. Ви можете вирішити це, розбивши складну команду на команди низького рівня: наприклад, виберіть дію для підрозділу A, увійдіть у глибину та вирішіть для блоку B .... вирішіть для блоку N ..., а потім закінчіть цей поворот. Але, це одне не змінює складності! Ви повинні оптимізувати порядок, в якому дії призначаються одиницям (наприклад, перший блок B, C, D, а потім блок A). Ви можете записати вплив рішення для кожної одиниці під час останнього розрахунку, а потім сортувати за важливістю. Таким чином обрізку альфа-бета можна використовувати для того, щоб відрізати будь-яку погану комбінацію з дерева пошуку дуже рано. Найвищим пріоритетом завжди має бути "не робити більше нічого і закінчувати свою чергу" (нульовий хід обрізки) у кожній ітерації. Таким чином ви можете "пропустити" призначення завдань більшості підрозділів і дозволити їм просто продовжувати те, що вони робили раніше. Таким чином, пошук швидко піде в глибину, просто подивившись на "критичні" одиниці (наприклад, ті, які дійсно зараз в бою). Не забудьте лише один раз командувати кожним підрозділом ... Ви також можете використовувати деяку випадковість, щоб переконатися, що "важливі" одиниці також час від часу отримують команду. Особливо, підрозділи, які закінчують якусь роботу (наприклад,
Ітераційне поглиблення + таблиця кешування / хешу
Потім ви можете «інтерактивне поглиблення» все більше і більше заглиблюватися в глибину, поки не буде досягнуто деякого часового обмеження. Таким чином, ви будете шукати глибше, якщо менше одиниць, і у вас завжди є якийсь "результат", якщо ви перестанете шукати кращого рішення. Ітераційне поглиблення вимагатиме використання хеш-таблиці для кешування попередніх результатів пошуку. Це також дозволяє повторно використовувати деякі результати пошуку за останніми поворотами (гілка дерева пошуку, яка охоплює команди, які були фактично виконані в останню чергу). Щоб здійснити це, вам потрібна дуже хороша хеш-функція (подивіться на "ключ zbrist"), який може бути ітераційно оновлений. Оновлення хеш-ключа означає, що ви можете просто взяти хеш-ключ старої "позиції" і можете просто натиснути на зміну позиції (наприклад, зніміть одиницю у позиції x і поставте її у положення y). Таким чином, обчислення хеш-ключа є швидким, і вам не потрібно обробляти ситуацію з усіма дошками, щоб обчислити її, просто перевірити, чи містить хеш попередній запис для цієї позиції. У такий спосіб ви повинні переконатися, що не трапляються хеш-зіткнення.
Недетермінована поведінка
Недетермінована поведінка є проблемою для мінімальних / максимальних пошуків. Це означає, що невірно, чи вдаритеся ви в атаку (наприклад, ймовірність 10%). Тоді ви не можете просто планувати, що це станеться. У цьому випадку вам потрібно змінити алгоритм і поставити між ними шар "ймовірності". Це трохи схоже на "його ймовірність повернути". Кожен незалежний результат слід розглядати окремо. Оцінка через цей «шар» глибини повинна бути відібрана для вибірки (відбір проб monte carlo), а результат поглибленої оцінки повинен бути зважений на ймовірність виникнення. Різні результати шару ймовірності повинні розглядатися як різні попередні ходи (але замість min / max слід розраховувати "середнє"). Це, звичайно, збільшить складність дерева пошуку.
Підсумок
Застосувавши всі ті прийоми (які використовуються в сучасних шахових двигунах) до детермінованої гри, ви, безсумнівно, зможете досягти розумних результатів і для гри. Для недетермінованих ігор це, мабуть, буде складніше, але я думаю, що все-таки керований.
Хороший ресурс для пояснення цих прийомів (для шахів) - http://chessprogramming.wikispaces.com/
Ви навіть можете реалізувати якусь спрямовану випадковість у min / max пошуку. Замість того, щоб детерміновано досліджувати найкращі результати спочатку в кожній ітерації, ви можете просто рандомізувати це, і нехай його порядок визначається розподілом вірогідності, який базується на поточних оцінках ...