какое минимальное количество крестиков и ноликов может быть на поле в момент окончания игры
Крестики-нолики
Крестики-нолики — логическая игра между двумя противниками на квадратном поле 3 на 3 клетки или большего размера (вплоть до «бесконечного поля»). Один из игроков играет «крестиками», второй — «ноликами». В традиционной китайской игре используются черные и белые камни.
Игроки по очереди ставят на свободные клетки поля 3х3 знаки (один всегда крестики, другой всегда нолики). Первый, выстроивший в ряд 3 своих фигур по вертикали, горизонтали или диагонали, выигрывает. Первый ход делает игрок, ставящий крестики.
Обычно по завершении партии выигравшая сторона зачёркивает чертой свои три знака (нолика или крестика), составляющих сплошной ряд.
Классические «крестики-нолики» на поле 3×3 не представляют никакого практического интереса (разве что для маленьких детей, как начальный этап обучения логическим играм, или в качестве несложного задания по программированию для студенческой лабораторной работы) — общеизвестен алгоритм, который при правильной игре гарантирует ничью любой стороне, а при ошибке противника позволяет выиграть. Таким образом, игра находится в состоянии «ничейной смерти».
Перебор всех возможных ходов:
За крестики
Сделать первый ход в центральное поле.
Противник может ответить ходом либо в угол, либо на сторону поля.
Данный алгоритм предполагает оптимальную игру противника. Естественно, если противник допускает ошибку, позволяющую следующим ходом построить тройку, её следует построить, но при правильной игре такое невозможно. Таким образом, нолики могут гарантированно обеспечить себе только ничью.
Реализация алгоритма Минимакс на примере игры «Крестики-Нолики»
Недавно я написал непобедимую игру «Крестики-Нолики». Это был интересный и поучительный проект, который многому меня научил. Если у вас есть желание посмотреть результат — это можно сделать здесь.
Для того чтобы сделать игру непобедимой, было необходимо создать алгоритм, который может рассчитать все возможные ходы для «компьютерного» игрока. Далее, нужно использовать некоторую метрику, чтобы определить, какой ход является предпочтительным. После долгих исследований стало понятно, что алгоритм Минимакс, был тем, что мне нужно.
Понимание основ алгоритма и реализация игры заняли некоторое время. Я нашел много примеров кода и объяснений, тем не менее это оказалось не такой уж простой затеей. Надеюсь этот пост поможет некоторым из читателей оценить элегантность этого алгоритма.
Описание «Идеальной» игры «Крестики-Нолики»
Для начала давайте опишем, что мы понимаем под «идеальной» игрой — если я играю идеально, я или побеждаю в игре, или играю вничью. В случае если я играю против другого «идеального» игрока, я всегда играю вничью.
Можно ли описать эти требования количественно? Давайте для всех возможных вариантов конечного состояния игры назначить какое-то количество очков:
Давайте рассмотрим короткий пример.
На картинке изображено состояние игрового поля, и мой черед ходить. Я играю за «Х». Моя цель, очевидно, максимизация количества очков, которые я получу.
Верхняя часть картинки показывает состояние игры, и, в зависимости от моего выбора, я могу попасть в одно из трех состояний из нижней части картинки. Очевидно, что состояние, в котором я побеждаю (снизу слева) является наилучший. Если я не сделаю этот ход, игрок «О» может легко победить, и я не хочу, чтоб он победил. Таким образом, выберу ход, который принесет мне наибольшее число очков.
Но что мы знаем о втором игроке? Мы можем предположить, что он тоже играет с целью победить в игре. Игрок «О» хочет выбрать ход, который приведет к наименьшему выигрышу для нас, он хочет минимизировать наш выигрыш. Давайте посмотрим на вещи с точки зрения игрока «О» начиная с двух других состояний игры из предыдущего примера, тех, в которых я не побеждаю:
Описание алгоритма Минимакс
Суть алгоритма Минимакс это поочередный перебор возможных ходов двух игроков, при котором мы считаем, что игрок «чья очередь» выберет ход, приносящий максимальное количество очков. Предположим, что мы играем за игрока «Х», тогда описание алгоритма будет примерное таким:
Реализация алгоритма Минимакс
Надеюсь теперь у вас есть общее представление, как алгоритм Минимакс определяет наилучший ход. Давайте рассмотрим имплементацию алгоритма, чтоб закрепить наше понимание.
Вот функция, которая производит оценку состояния:
Достаточно просто, вернуть +10 если текущий игрок побеждает в игре, -10, если проигрывает и 0 в случае ничьи. Вы также можете отметить, что с точки зрения алгоритма нет разницы, какой это игрок (»Х» или «О»), важно лишь чей ход.
А теперь собственно сам алгоритм; обратите внимания что в приведенном варианте выбор хода это просто адрес ячейки на поле, т.е. [0,2] это правая верхняя ячейка на игровом поле размером 3×3.
Когда алгоритм выполняется в классе PerfectPlayer, выбор наилучшего ходя сохраняется в переменной choice, которая впоследствии используется для того, чтобы вернуть новое состояние игры в которое мы попадаем в результате выбранного игроком хода.
Идеальный игрок-самоубийца
Эта имплементация алгоритма позволит вам создать игру в «крестики-нолики», в которую вы не сможете победить. Но есть маленький нюанс, который я обнаружил в процессе тестирования игры. В случае, если мой «идеальный игрок» обнаружит состояние, в котором он или проиграет, или закончит вничью, его ход будет самоубийственным. Проще говоря, алгоритм говорит «я все равно проиграю, поэтому без разницы сейчас, или через 6 ходов».
Я обнаружил это когда передал явно некорректное состояние игрового поля и попытался выяснить, какой ход предложит алгоритм. Я ожидал, что «идеальный игрок» попытается помешать мне выиграть так долго, как сможет, но этого не произошло:
Давайте рассмотрим, что происходит здесь через призму возможных ходов (для простоты я удалил некоторые состояния)
Черт побери, что же мастер «крестиков-ноликов» должен сделать?
Даем противнику хороший бой: глубина
Наилучшим улучшением для алгоритма будет изменить его так, чтоб «идеальный игрок» играл «идеально» до самого конца, т.е. взять «глубину» (количество ходов до возможного проигрыша) в расчет при выборе хода. Простыми словами, идеальный игрок будет играть идеально, и постарается играть так долго, как только сможет.
Для того чтобы достигнуть такого результата мы будем отнимать глубину рекурсии\количество ходов от конечного состояния игры. Т.е. чем больше ходов до минимального выигрыша (и чем меньше ходов до максимального) — тем лучше.
Так, каждый раз при вызове алгоритма Минимакс глубина будет увеличена на 1, и когда мы наконец рассчитаем возможный выигрыш для конкретного конечного состояния игры мы введем поправку на глубину. Давайте посмотрим, как это выглядит на примере следующего дерева ходов:
В заключение
Я надеюсь все эти пояснения помогли вам получше понять алгоритм Минимакс, и, возможно, как можно всегда выигрывать в «крестики-нолики». Если у вас есть вопросы, или что-то вам кажется непонятным, напишите, пожалуйста, в комментариях и я улучшу статью. Полный код можно найти у меня на Github. А поиграть в получившуюся игру можно здесь: http://perfecttictactoe.herokuapp.com/.
От переводчика
Перевод сделан с разрешения автора. Мне понравилась эта статья тем, что она просто и наглядно описала алгоритм Минимакс. В статье присутствуют неточности и упрощения а также, местами, неточная терминология.
Возможно вам также будет интересен мой YouTube канал.
Стратегические крестики-нолики (Starategic Tic-Tac-Toe)
Играть одну партию в крестики-нолики более двух часов — легко.
В статье будет рассказано о том как можно привнести элементы «стратегии и тактики» в привычные всем крестики-нолики. Будут описаны и проанализированы правила игры, рассказано об игровых полях.
Что предлагается?
Игра Starategic Tic-Tac-Toe (STTT) или Стратегические крестики-нолики это, как и её прародитель, игра для двух участников для которой необходимы лишь карандаш и бумага. Она является надмножеством игры Ultimate Tic-Tac-Toe также как Ultimate Tic-Tac-Toe является надмножеством обычных крестиков-ноликов (Ordinary Tic-Tac-Toe). Задача игры — помочь игрокам приобрести навыки стратегического мышления.
Домашняя страница проекта
Содержание
Термины и определения
Осторожно, множество похожих определений и их количество может вас оттолкнуть, но без этого базиса вы не сможете понять о чём пойдёт речь далее.
На этот момент все необходимы нам определения заданы и мы можем приступить к обсуждению самой игры.
Правила игры
Задавая и анализируя данный класс игр (надмножество игры Крестики-нолики) мы, для упрощения понимания и сравнения, разделим правила игры на три части: правила хода, правила выигрыша и ограничения. Рассмотрим игру Оперативные крестики-нолики согласно данному подходу.
Оперативные крестики-нолики
Теперь, когда правила знакомой всем игры заданы согласно предлагаемому подходу, читателю будет легче ориентироваться в правилах Тактических и Стратегических крестиков-ноликов.
Наборы правил Стратегических крестиков-ноликов основываются на правилах Тактических крестиков ноликов, поэтому приведём и их в предлагаемой форме.
Тактические крестики-нолики
Как видно первый игрок сходил в третью Оперативную клетку пятого Оперативного поля, поэтому второй игрок должен ходить в третью Тактическую клетку данного Тактического поля.
Для множества студентов игроков, с кем мне приходилось сразиться, данный набор правил был соложен для понимания на слух, но в ходе первой, пробной игры большинство разбиралось, так что на данном этапе я предлагаю читателю сыграть в Тактические крестики-нолики для чего вам понадобятся карандаш/ручка, тетрадный лист (или обычный если хорошо чертите прямые) и заинтересованный товарищ.
Настало время поговорить о самих Стратегических крестиках-ноликах. В первую очередь при создании новой игры была поставлена цель расширить текущее игровое поле за счёт увеличения количества «уровней» игры, в следствии этого возникла необходимость составить новые правила хода, поскольку старые, как мы увидим ниже, были полными и не могли предоставить новые пути задания ходов игроков. За столом обсуждений будущих правил данной игры родились три основных направления в последствии преобразовавшихся в наборы правил: Тактический, Функциональный и Гиперфункциональный. Опишем данные наборы правил.
Стратегические крестики-нолики
Общие правила
Все три набора правил сохраняют правила выигрыша и ограничения на Тактическим уровне и объявляют те же правила для Стратегического уровня. Таким образом правила выигрыша и ограничения для Стратегического уровня выглядят точно также как правила Тактических крестиков-ноликов с точностью до названий клеток. Читателю предлагается самому написать правила Стратегического уровня для проверки понимания текущих терминов и положений.
Тактический набор правил
Правила Тактических крестиков-ноликов задают отображение (mapping) из множества Клеток в множество Тактических клеток для определения того куда должен ходить текущий игрок в зависимости от хода предыдущего игрока или другими совами правила хода на Тактическом уровне. Тактический набор правил сохраняет отображение из множества Клеток предыдущего Оперативного поля в множество Тактических клеток текущего Тактического поля, при этом декларируя, что отображение из множества Тактических клеток предыдущего Тактического поля в множество Стратегических клеток Стратегического поля сохраняется таким же как и отображение из множества Клеток предыдущего Оперативного поля в множество Тактических клеток текущего Тактического поля или другими словами правила хода на Стратегическом уровне такие же как и на Тактическом уровне. Наглядную иллюстрацию данного положения можно найти под спойлером.
На картинке игрок сходил в первую Оперативную клетку четвёртого Оперативного поля пятого Тактического поля, а это означает, что следующий игрок должен ходить любую из Оперативных клеток первой Тактической клетки (зелёная) четвёртого Тактического поля (красное), что в свою очередь определит ход следующего игрока.
Функциональный набор правил
Вторая идея заключалась в сопоставлении строкам 9х1 (или столбцам 1х9, как будет показано ниже это не столь значительно и выбор в пользу строк был сделан лишь из эстетики получающегося игрового поля) клеток номера Стратегической клетки, в которую должен быть произведён следующий ход. Данная идея была реализована путём помещения номеров Стратегических клеток, для следующего хода, слева в той же строке, что и Клетка текущего хода. Чтобы понять о чём идёт речь перейдите в раздел с игровыми полями. Особенности выбора номеров следующих Стратегических клеток будут раскрыты в разделе анализа игры. Правила отображения из множества Клеток текущего Оперативного поля в множество Тактических клеток следующего Тактического поля сохраняются неизменными.
Гиперфункциональный набор правил
Третья идея заключалась в определении номера Стратегической клетки следующего хода для каждой Клетки текущего хода. Данный набор правил определяет именно такое отображение, при этом правила отображения из множества Клеток текущего Оперативного поля в множество Тактических клеток следующего Тактического поля сохраняются неизменными. Особенности выбора номеров следующих Стратегических клеток будут раскрыты в разделе анализа игры.
Игровые поля
Название поля | Размер в Клетках | Можно ли нарисовать от руки | Поместится ли на половине тетрадного листа |
---|---|---|---|
Игровые поля | |||
Базовое | 29х29 | Да | Да |
Пронумерованное | 31х31 | Да | Да |
Функциональное | 35х31 | Да | Да |
Гиперфункциональное | 35х31 | Нет | Да |
Полное | — | Да | Нет |
Вспомогательные поля | |||
Поле помощи | 11х15 | Да | Да |
Поле записи ходов | 6хN | Да | Да |
Непрерывное поле записи ходов | — | Да | Да |
Далее под соответствующими спойлерами расположены изображения полей и заметки о их дизайне и предназначении.
Базовое поле — то с чего начинается игра. Имея только его вы уже можете играть в любой вариант Стратегических крестиков-ноликов, состоит из девяти полей для игры в Тактические крестики-нолики.
Пронумерованное поле — это Базовое поле, Тактические клетки которого пронумерованы для упрощения отслеживания деятельности игроков в ходе игры. Число рядом с Тактической клеткой отражает как номер Стратегической клетки (десятки) так и номер Тактической клетки (единицы).
Функциональное поле — это Пронумерованное поле на котором возможна игра (проще следить за её ходом) с Функциональным набором правил. Для данного поля положение чисел, задающих следующую Стратегическую клетку определено слева от соответствующих строчек, что позволяет сохранять размеры поля такими, чтобы оно могло уместиться на половине тетрадного листа.
Гиперфункциональное поле — на данном поле возможна игра с Гипперфункциональным набором правил, оно не может быть нарисовано от руки так как содержит градации цвета для задания чисел, обозначающих следующую Стратегическую ячейку.
Данное поле было создано для того чтобы игроки не путались при возобновлении игры и не вспоминали кому принадлежит какая клетка (Стратегическая или Тактическая). По ходу игры игроки могут отмечать свои успехи тем самым сохраняя прогресс партии.
Данное поле было разработано с целью помощи игрокам в запоминании прогресса игры, очерёдности хода, проверки правильности игрового поля. В предлагаемом варианте данного поля в течении своего хода необходимо записать номера Стратегической (S) Тактической (T) и Операционной (O) клетки, в которую игрок производит ход. Данный вариант поля преимущественно предназначен для игры с Функциональным и Гиперфункциональным набором правил, для Тактического же набора было специально разработано Непрерывное поле записи ходов. Для данного поля существует несколько вариантов исполнения, все они доступны для скачивания.
Непрерывное поле записи ходов — специально разработанное поле записи ходов, предназначенное для игры с Тактическим набором правил. Необходимость его появления была обоснована непосредственным игровым опытом автора. В данном поле дополнительные записи и повторение чисел для Тактического набора правил было сведено к минимуму. Ниже в статье приведён пример игры происходившей с использованием данного поля. Для данного поля существует несколько вариантов исполнения, все они доступны для скачивания.
Полное поле представляет собой совокупность игровых и вспомогательных полей, представленную на одном листе. Для данного поля существует несколько вариантов исполнения, все они доступны для скачивания.
Анализ игры
В данном разделе будет рассказано о том как был обоснован выбор чисел, означающих следующую Стратегическую ячейку для Функционального и Гиперфункционального набора правил. Метод анализа игры заключается в следующем:
Весь код, реализующий этапы анализа можно найти по ссылке. Код написан на Lua 5.1 и запустится как на интерпретаторе так и на JIT-компиляторе (второй более предпочтителен из-за вычислительной сложности предлагаемого метода). Оконечные этапы анализа — построение heatmap’ов и подсчёт среднего расстояния проводился в Excel.
Проанализируем полученные результаты. Как опорный возьмём результат для Тактического набора правил. И так для данного набора правил удобно взять отображение из множества Тактических клеток в него же, среднее расстояние между Тактическими клетками получилось равным 1.(8) хода. Не много, это означает, что для успешной игры в памяти стоит хранить последние два хода и думать как минимум на два хода вперёд. Heatmap можно увидеть под спойлером. Для всех heatmap’ов шкала идёт от красного к зелёному через жёлтый на увеличение.
Далее применим метод анализа к Функциональному набору правил. Для того как именно определить числа в данном наборе правил существовали некоторые предпосылки, их обсуждение выходит за рамки данной статьи, скажем лишь, что в ходе разработки был предложен довольно эффективный метод создания наборов чисел, проанализировав который мы смогли прийти к выводам об эффективности наборов выделенных из полученных.
Для данного набора правил было удобно взять отображение из множества триплетов Тактических клеток в него же (в триплеты объединены Тактические клетки 1-3, 4-6, 7-9 для каждой Стратегической ячейки). Взглянем на результаты: оптимальными были названы два набора чисел под кодовыми названиями map34 и map67, для данных наборов среднее расстояние между триплетами составило 2.(6) хода. Их особенностью является то, что расстояние от каждого триплета до самого себя составляет ровно 3 хода.
Для визуального сравнения представлены heatmap’ы других наборов:
map14
Последним проанализируем Гиперфункциональный набор правил. При детальном рассмотрении игровых полей, созданных под данный набор правил читатель мог увидеть закономерность в расположении цифр, отвечающих за следующую Стратегическую клетку. Используя данную закономерность мы создали девять наборов чисел описывающих переходя для Гиперфункционального набора правил, из которых был найден оптимальный получивший кодовое имя hmap2. Его показатели составили 2.206 хода в среднем между Тактическими клетками и ровно 3 хода чтобы попасть в туже Тактическую клетку.
Выводы и послесловие
В статье было рассказано о новой игре в своём типе — Стратегических крестиках-ноликах, дизайнерские решения в ходе создания игры были обоснованы путём анализа.
Направления будущих работ
Основными направлениями авторам представляются:
Послесловие
Историю создания и сведения об авторах можно найти на странице проекта, а также там можно найти возможные ограничения авторских прав на производную деятельность. Авторы будут рады помощи с переводом оставшегося русского текста на английский язык на главной странице проекта.