Как находить выигрышные позиции в дискретной игре двух игроков?
В игре с полной информацией оба участника знают текущее состояние и доступные ходы. Чтобы доказать выигрышную стратегию, недостаточно показать одну удачную партию: нужно выбрать…
В игре с полной информацией оба участника знают текущее состояние и доступные ходы. Чтобы доказать выигрышную стратегию, недостаточно показать одну удачную партию: нужно выбрать ход, после которого любой ответ соперника оставляет возможность довести игру до победы.
Терминальные состояния
Сначала формально определяют, когда игра заканчивается и кто считается победителем. Терминальная позиция может быть выигрышной или проигрышной для игрока, которому предстоит ход, в зависимости от правила. Неверно заданная база меняет классификацию всего дерева состояний.
Обратная разметка
Позиция выигрышна, если существует хотя бы один ход в проигрышное состояние для соперника. Она проигрышна, если каждый допустимый ход ведёт сопернику в выигрышную позицию. Эти два квантора — «существует» и «для всех» — являются ядром доказательства стратегии.
Число ходов до результата
Задачи могут спрашивать победу ровно за два хода или не позднее определённого момента. Тогда одной метки W/L мало: сохраняют уровень, на котором состояние получает статус. Игрок, стремящийся выиграть, выбирает кратчайший путь к победе, а сопротивляющийся соперник — продолжение, которое её максимально откладывает.
Дерево и динамика
Полное дерево быстро растёт, но одинаковое состояние может возникнуть разными путями. Мемоизация вычисляет его статус один раз и превращает повторяющиеся ветви в ориентированный граф состояний. Если ходы монотонно уменьшают или увеличивают параметр до границы, позиции удобно размечать таблицей.
Формулировка стратегии
В ответе назовите первый ход и опишите реакцию на каждую категорию ответа соперника. Для проверки постройте небольшую таблицу достижимых состояний и убедитесь, что ни один разрешённый ответ не выпал. Конкретная стратегия и индуктивная разметка вместе дают полноценное обоснование, а не прогноз партии.
Рекурсивное определение позиции
В конечной игре позиция выигрышная, если существует ход в проигрышную позицию соперника. Она проигрышная, если ходов нет либо каждый допустимый ход ведёт в выигрышную. Вычисление начинают от терминалов и движутся против направления ходов. В ациклической игре мемоизация не даёт одной позиции вычисляться много раз.
from functools import cache
@cache
def winning(stones: int) -> bool:
if stones == 0:
return False
moves = (stones - step for step in (1, 3, 4) if stones >= step)
return any(not winning(next_state) for next_state in moves)
for stones in range(13):
print(stones, "W" if winning(stones) else "L")Чтобы предъявить стратегию, недостаточно написать «позиция выигрышная». Нужно назвать конкретный первый ход и правило ответа на каждый возможный ход соперника. Если требуется победа ровно за определённое число ходов, к состоянию добавляют глубину и аккуратно различают «не позднее» и «ровно».
Практика: стратегия для игры с камнями
Для ходов −1, −3 и −4 найдите проигрышные позиции до 30 вручную и программой. Для трёх выигрышных стартов укажите ход в проигрышное состояние. Затем измените цель: выигрывает тот, кто забрал последний камень, но ход, оставивший отрицательное число, запрещён. Объясните, почему база остаётся важнее рекурсивной формулы. В дополнительном варианте разрешите удвоение числа и задайте верхнюю границу, чтобы граф состояний оставался конечным.
Источники
- МФТИ: Программа вступительного испытания по информатике и информационно-коммуникационным технологиям.
- Поляков К.Ю., Еремин Е.А. Информатика. 11 класс. Углублённый уровень.
- Малясова С.В. Информатика и ИКТ: пособие для подготовки к ЕГЭ / под ред. Цветковой М.С. — М.: Academia, 2018. — 637 с.