Я недавно наткнулся на игру 2048 . Вы объединяете подобные плитки, перемещая их в любом из четырех направлений, чтобы сделать плитки «большего размера». После каждого хода новая плитка появляется в случайной пустой позиции со значением либо 2
или 4
. Игра заканчивается, когда все поля заполнены, и нет ходов, которые могут объединить плитки, или вы создаете плитку со значением 2048
.
Во-первых, мне нужно следовать четко определенной стратегии, чтобы достичь цели. Итак, я подумал написать программу для этого.
Мой текущий алгоритм:
while (!game_over) {
for each possible move:
count_no_of_merges_for_2-tiles and 4-tiles
choose the move with a large number of merges
}
То , что я делаю это в любой момент, я буду стараться объединить плитки со значениями 2
и 4
, то есть, я стараюсь иметь 2
и 4
плитки, как минимум , как это возможно. Если я попробую это так, все остальные плитки будут автоматически объединены, и стратегия кажется хорошей.
Но когда я на самом деле использую этот алгоритм, я получаю около 4000 очков, прежде чем игра заканчивается. Максимальное количество баллов AFAIK чуть больше 20 000 баллов, что намного больше, чем мой текущий результат. Есть ли лучший алгоритм, чем выше?
источник
choose the move with large number of merges
быстро приводит к локальнымОтветы:
Я разработал AI 2048, используя оптимизацию expectimax вместо поиска минимакса, используемого алгоритмом @ ovolve. ИИ просто выполняет максимизацию всех возможных ходов, после чего следует ожидание всех возможных порождений тайлов (взвешенных по вероятности тайлов, т.е. 10% для 4 и 90% для 2). Насколько я знаю, невозможно сократить оптимизацию expectimax (кроме удаления крайне маловероятных ветвей), и поэтому используемый алгоритм представляет собой тщательно оптимизированный поиск методом перебора.
Представление
ИИ в его конфигурации по умолчанию (максимальная глубина поиска 8) занимает от 10 мс до 200 мс, чтобы выполнить ход, в зависимости от сложности положения доски. При тестировании ИИ достигает средней скорости перемещения 5-10 ходов в секунду в течение всей игры. Если глубина поиска ограничена 6 ходами, ИИ может легко выполнить более 20 ходов в секунду, что делает его интересным для просмотра .
Чтобы оценить результативность ИИ, я запускал ИИ 100 раз (подключался к браузерной игре через пульт дистанционного управления). Для каждой плитки ниже приведены пропорции игр, в которых эта плитка была достигнута хотя бы один раз:
Минимальная оценка по всем пробегам была 124024; максимальный результат - 794076. Средний балл - 387222. ИИ никогда не удавалось получить плитку 2048 (поэтому он никогда не проигрывал игру ни разу в 100 играх); на самом деле, он получил плитку 8192 хотя бы раз в каждом заезде!
Вот скриншот лучшего пробега:
Эта игра заняла 27830 ходов за 96 минут, или в среднем 4,8 хода в секунду.
Реализация
Мой подход кодирует всю доску (16 записей) в виде единого 64-битного целого числа (где плитки - это nybbles, то есть 4-битные порции). На 64-битной машине это позволяет передавать всю плату в одном регистре машины.
Операции сдвига битов используются для извлечения отдельных строк и столбцов. Одна строка или столбец - это 16-разрядная величина, поэтому таблица размером 65536 может кодировать преобразования, которые работают с одной строкой или столбцом. Например, перемещения реализованы как 4 поиска в предварительно вычисленной «таблице эффектов перемещения», которая описывает, как каждое перемещение влияет на одну строку или столбец (например, таблица «перемещение вправо» содержит запись «1122 -> 0023», описывающую, как строка [2,2,4,4] становится строкой [0,0,4,8] при перемещении вправо).
Оценка также осуществляется с помощью таблицы поиска. Таблицы содержат эвристические оценки, рассчитанные для всех возможных строк / столбцов, а итоговая оценка для доски - это просто сумма значений таблицы для каждой строки и столбца.
Это представление доски, наряду с подходом поиска таблиц для перемещения и подсчета очков, позволяет ИИ за короткий промежуток времени искать огромное количество игровых состояний (более 10 000 000 игровых состояний в секунду на одном ядре моего ноутбука середины 2011 года).
Сам поиск expectimax закодирован как рекурсивный поиск, который чередуется между шагами «ожидания» (тестирование всех возможных мест и значений появления тайлов и взвешивание их оптимизированных оценок по вероятности каждой возможности) и шагами «максимизации» (тестирование всех возможных ходов). и выбрать тот, который набрал лучший результат). Поиск по дереву завершается, когда он видит ранее увиденную позицию (используя таблицу транспонирования ), когда он достигает предопределенного предела глубины или когда он достигает состояния доски, которое крайне маловероятно (например, оно было достигнуто путем получения 6 "4" тайлов в ряд от стартовой позиции). Типичная глубина поиска составляет 4-8 ходов.
Эвристика
Несколько эвристик используются для направления алгоритма оптимизации к выгодным позициям. Точный выбор эвристики оказывает огромное влияние на производительность алгоритма. Различные эвристики взвешиваются и объединяются в позиционную оценку, которая определяет, насколько «хороша» данная позиция доски. Поиск оптимизации будет нацелен на максимизацию средней оценки всех возможных позиций на доске. Фактическая оценка, показанная в игре, не используется для подсчета очков на доске, поскольку она слишком сильно взвешена в пользу объединения плиток (когда отложенное объединение может принести большую выгоду).
Первоначально я использовал две очень простые эвристики, предоставляя «бонусы» для открытых квадратов и для получения больших значений на краю. Эти эвристики работали довольно хорошо, часто достигая 16384, но никогда не доходя до 32768.
Петр Моровек (@xificurk) взял мой ИИ и добавил две новые эвристики. Первой эвристикой было наказание за наличие немонотонных рядов и столбцов, которые увеличивались по мере увеличения рангов, гарантируя, что немонотонные ряды небольших чисел не будут сильно влиять на счет, но немонотонные ряды больших чисел существенно ухудшают счет. Вторая эвристика подсчитала количество потенциальных слияний (смежных равных значений) в дополнение к открытым пространствам. Эти две эвристики служат для продвижения алгоритма к монотонным доскам (которые легче объединить) и к позициям досок с большим количеством слияний (поощряя его выравнивать слияния, где это возможно, для большего эффекта).
Кроме того, Петр также оптимизировал эвристические веса, используя стратегию «мета-оптимизации» (используя алгоритм, называемый CMA-ES ), где сами веса были скорректированы для получения максимально возможного среднего балла.
Эффект этих изменений чрезвычайно значим. Алгоритм пошел от достижения плитки 16384 примерно в 13% случаев до достижения ее в течение 90% времени, и алгоритм начал достигать 32768 за 1/3 времени (тогда как старая эвристика никогда не производила плитку 32768) ,
Я считаю, что есть еще возможности для улучшения эвристики. Этот алгоритм определенно еще не «оптимален», но я чувствую, что он приближается.
То, что ИИ достигает плитки 32768 в более чем трети своих игр, является огромной вехой; Я буду удивлен, узнав, достиг ли кто-либо из игроков-людей отметки 32768 в официальной игре (т.е. без использования таких инструментов, как savestates или undo). Я думаю, что 65536 плитка в пределах досягаемости!
Вы можете попробовать ИИ для себя. Код доступен по адресу https://github.com/nneonneo/2048-ai .
источник
var value = Math.random() < 0.9 ? 2 : 4;
.Я являюсь автором программы AI, которую другие упоминали в этой теме. Вы можете посмотреть ИИ в действии или прочитать источник .
В настоящее время программа достигает примерно 90% выигрыша, выполняемого в javascript в браузере на моем ноутбуке, учитывая около 100 миллисекунд времени на обдумывание за ход, поэтому, хотя она и не идеальна (пока!), Она работает довольно хорошо.
Поскольку игра представляет собой дискретное пространство состояний, отличную информацию, пошаговую игру, такую как шахматы и шашки, я использовал те же методы, которые, как было доказано, работали в этих играх, а именно минимаксный поиск с альфа-бета-отсечкой . Поскольку там уже много информации об этом алгоритме, я просто расскажу о двух основных эвристиках, которые я использую в функции статической оценки и которые формализуют многие из интуиций, которые здесь выражают другие люди.
Монотонность
Эта эвристика пытается гарантировать, что все значения тайлов либо увеличиваются, либо уменьшаются как влево / вправо, так и вверх / вниз. Одна только эта эвристика отражает ту интуицию, о которой упоминали многие другие, что более ценные плитки должны быть сгруппированы в углу. Это, как правило, предотвращает осаждение меньших ценных плиток и будет держать доску очень организованной, так как меньшие плитки будут каскадно вставляться в большие плитки.
Вот скриншот совершенно монотонной сетки. Я получил это, запустив алгоритм с установленной функцией eval, чтобы игнорировать другие эвристики и учитывать только монотонность.
ровность
Одна только вышеупомянутая эвристика имеет тенденцию создавать структуры, в которых соседние листы уменьшаются в стоимости, но, конечно, для объединения соседние листы должны иметь одинаковое значение. Поэтому эвристика плавности просто измеряет разницу в значениях между соседними тайлами, пытаясь минимизировать это количество.
Комментатор Hacker News дал интересную формализацию этой идеи с точки зрения теории графов.
Вот скриншот совершенно гладкой сетки, любезно предоставленной этой отличной пародийной вилкой .
Бесплатные плитки
И, наконец, существует штраф за то, что слишком мало свободных фишек, так как варианты могут быстро исчерпаться, когда игровая доска становится слишком тесной.
И это все! Поиск по игровому пространству при оптимизации этих критериев дает удивительно хорошую производительность. Одно из преимуществ использования такого обобщенного подхода, а не явно закодированной стратегии перемещения, состоит в том, что алгоритм часто может находить интересные и неожиданные решения. Если вы наблюдаете за его ходом, он часто делает удивительные, но эффективные движения, например, внезапно переключая стену или угол, против которого он строит.
Редактировать:
Вот демонстрация силы этого подхода. Я раскрыл значения тайла (так что он продолжал расти после достижения 2048 года) и вот лучший результат после восьми испытаний.
Да, это 4096 наряду с 2048. =) Это означает, что он достиг неуловимого тайла 2048 на одной доске.
источник
Я заинтересовался идеей искусственного интеллекта для этой игры, не содержащей жестко запрограммированного интеллекта (т.е. без эвристики, функций подсчета очков и т. Д.). ИИ должен «знать» только правила игры и «разбираться» в игре. Это в отличие от большинства ИИ (таких как в этой теме), в которых игровой процесс, по сути, представляет собой грубую силу, управляемую функцией подсчета очков, отражающей понимание человеком игры.
AI алгоритм
Я нашел простой, но удивительно хороший игровой алгоритм: чтобы определить следующий ход для данной доски, ИИ играет в игру в памяти, используя случайные ходы, пока игра не закончится. Это делается несколько раз, при этом отслеживая счет в конце игры. Затем рассчитывается средний конечный балл за начальный ход . Начальный ход с наибольшим средним результатом выбирается следующим ходом.
При 100 ходах (т.е. в играх на память) за ход ИИ достигает 2048 плиток в 80% случаев и 4096 тайлов в 50% случаев. При использовании 10000 прогонов 2048 получает 100%, 70% для 4096 и около 1% для 8192.
Увидеть это в действии
Лучший достигнутый результат показан здесь:
Интересный факт об этом алгоритме заключается в том, что, хотя игры с произвольной игрой неудивительно довольно плохи, выбор лучшего (или наименее плохого) хода приводит к очень хорошему игровому процессу: типичная игра с искусственным интеллектом может набрать 70000 очков и 3000 последних ходов, однако Игры с произвольной игрой в памяти из любой заданной позиции дают в среднем 340 дополнительных очков примерно за 40 дополнительных ходов перед смертью. (Вы можете убедиться в этом сами, запустив ИИ и открыв консоль отладки.)
Этот график иллюстрирует эту точку: синяя линия показывает счет доски после каждого хода. Красная линия показывает лучший результат алгоритма в произвольном порядке из этой позиции. По сути, красные значения «вытягивают» синие значения вверх по направлению к ним, поскольку они являются наилучшим предположением алгоритма. Интересно видеть, что красная линия чуть-чуть выше синей линии в каждой точке, но синяя линия продолжает увеличиваться все больше и больше.
Я нахожу довольно удивительным, что алгоритм не должен на самом деле предвидеть хороший игровой процесс, чтобы выбирать ходы, которые его производят.
Позже я обнаружил, что этот алгоритм может быть классифицирован как алгоритм поиска дерева Монте-Карло .
Реализация и ссылки
Сначала я создал версию JavaScript, которую можно увидеть в действии здесь . Эта версия может запустить 100 прогонов в достойное время. Откройте консоль для дополнительной информации. ( источник )
Позже, чтобы поиграться, я использовал высоко оптимизированную инфраструктуру @nneonneo и реализовал свою версию на C ++. Эта версия допускает до 100000 пробежек за ход и даже 1000000, если у вас есть терпение. Инструкция по сборке предоставляется. Он работает в консоли, а также имеет пульт дистанционного управления для воспроизведения веб-версии. ( источник )
Результаты
Удивительно, но увеличение количества запусков кардинально не улучшает игровой процесс. Кажется, что у этой стратегии есть предел в 80000 пунктов с тайлом 4096 и всеми меньшими, очень близкими к достижению тайла 8192. Увеличение количества пробежек со 100 до 100000 увеличивает шансы на достижение этого лимита (с 5% до 40%), но не преодолев его.
Выполнение 10000 пробежек с временным увеличением до 1000000 вблизи критических позиций позволило преодолеть этот барьер менее чем в 1% случаев с достижением максимального балла 129892 и тайла 8192.
улучшения
После реализации этого алгоритма я попробовал много улучшений, включая использование минимальных или максимальных оценок или комбинации минимальных, максимальных и средних значений. Я также пытался использовать глубину: вместо того, чтобы пытаться выполнить K прогонов за ход, я пробовал K ходов за список ходов заданной длины (например, «вверх, вверх, влево») и выбирал первый ход из списка ходов с лучшим выигрышем.
Позже я реализовал дерево скоринга, которое учитывало условную вероятность того, что он сможет выполнить ход после заданного списка ходов.
Однако ни одна из этих идей не показала какого-либо реального преимущества перед простой первой идеей. Я оставил код для этих идей, закомментированный в коде C ++.
Я добавил механизм «Глубокий поиск», который временно увеличивал количество прогонов до 1000000, когда любой из прогонов мог случайно достичь следующей наивысшей плитки. Это предложило улучшение времени.
Было бы интересно узнать, есть ли у кого-нибудь другие идеи по улучшению, которые поддерживают независимость ИИ от предметной области.
2048 Варианты и Клоны
Ради интереса, я также реализовал AI как букмарклет , подключив его к элементам управления игры. Это позволяет ИИ работать с оригинальной игрой и многими ее вариантами .
Это возможно благодаря независимой от домена природе AI. Некоторые из вариантов довольно различны, такие как гексагональный клон.
источник
РЕДАКТИРОВАТЬ: Это наивный алгоритм, моделирующий сознательный мыслительный процесс человека, и дает очень слабые результаты по сравнению с ИИ, который ищет все возможности, так как он смотрит только вперед на одну плитку. Он был представлен в начале срока ответа.
Я усовершенствовал алгоритм и обыграл игру! Он может потерпеть неудачу из-за простой неудачи ближе к концу (вы вынуждены двигаться вниз, чего вам никогда не следует делать, и плитка появляется там, где должен быть ваш самый высокий уровень. Просто старайтесь держать верхний ряд заполненным, чтобы движение влево не нарушить шаблон), но в основном вы получаете фиксированную и мобильную партии. Это ваша цель:
Это модель, которую я выбрал по умолчанию.
Выбранный угол является произвольным, вы в основном никогда не нажимаете одну клавишу (запрещенный ход), а если вы это делаете, вы снова нажимаете противоположное и пытаетесь это исправить. Для будущих плиток модель всегда ожидает, что следующая случайная плитка будет равна 2 и появится на противоположной стороне от текущей модели (в то время как первая строка является неполной, в правом нижнем углу, как только первая строка завершена, в левой нижней части угол).
Здесь идет алгоритм. Около 80% побед (кажется, что всегда можно выиграть с более «профессиональными» методами ИИ, хотя я не уверен в этом.)
Несколько указателей на пропущенные шаги. Вот:
Модель изменилась из-за удачи быть ближе к ожидаемой модели. Модель, которую пытается достичь ИИ,
И цепочка туда добраться стала:
O
Представляют запрещенные места ...Таким образом, он будет нажимать вправо, затем вправо, затем (вправо или вверх в зависимости от того, где была создана четверка), затем продолжит завершать цепочку, пока не получит:
Итак, теперь модель и цепочка вернулись к:
Второй указатель, ему не повезло, и его основное место занято. Вполне вероятно, что он потерпит неудачу, но он все еще может достичь этого:
Вот модель и цепочка:
Когда ему удается достичь 128, он снова получает целый ряд:
источник
execute move with best score
Как вы можете оценить лучший результат из возможных следующих состояний?evaluateResult
вас, в основном вы пытаетесь подобраться максимально близко к наилучшему сценарию.Я копирую здесь содержание поста в своем блоге
Решение, которое я предлагаю, очень просто и легко реализуемо. Тем не менее, он достиг 131040 баллов. Представлено несколько тестов производительности алгоритма.
Алгоритм
Эвристический алгоритм оценки
Предположение, на котором основан мой алгоритм, довольно просто: если вы хотите получить более высокий балл, доска должна быть максимально аккуратной. В частности, оптимальная настройка задается линейным и монотонным убывающим порядком значений элементов мозаичного изображения. Эта интуиция также даст вам верхнюю границу для значения плитки: где n - номер плитки на доске.
(Существует возможность достичь тайла 131072, если 4 тайла генерируется случайным образом вместо 2 тайла, когда это необходимо)
Два возможных способа организации доски показаны на следующих изображениях:
Чтобы обеспечить расположение плиток в монотонном порядке убывания, показатель si рассчитывается как сумма линеаризованных значений на доске, умноженная на значения геометрической последовательности с общим отношением r <1.
Несколько линейных путей могут быть оценены одновременно, итоговая оценка будет максимальной оценкой любого пути.
Правило принятия решения
Реализованное правило принятия решения не совсем разумно, код на Python представлен здесь:
Реализация minmax или Expectiminimax, несомненно, улучшит алгоритм. Очевидно, что более сложное правило принятия решений замедлит алгоритм и потребует некоторого времени для его реализации. Я постараюсь реализовать минимаксную реализацию в ближайшем будущем. (Следите за обновлениями)
эталонный тест
В случае T2 четыре теста из десяти генерируют плитку 4096 со средним счетом 42000
Код
Код можно найти на GiHub по следующей ссылке: https://github.com/Nicola17/term2048-AI Он основан на term2048 и написан на Python. Я буду реализовывать более эффективную версию в C ++ как можно скорее.
источник
Моя попытка использует expectimax, как и другие решения выше, но без битбордов. Решение Nneonneo может проверить 10 миллионов ходов, что составляет примерно 4 глубины, при этом осталось 6 плиток и 4 возможных хода (2 * 6 * 4) 4 . В моем случае эта глубина занимает слишком много времени для изучения, я настраиваю глубину поиска expectimax в соответствии с количеством оставшихся свободных плиток:
Баллы досок вычисляются с помощью взвешенной суммы квадрата числа свободных плиток и точечного произведения 2D-сетки следующим образом:
который заставляет организовывать плитки по убыванию в виде змеи с верхней левой плитки.
код ниже или на github :
источник
cost=1x(number of empty tiles)²+1xdotproduct(snakeWeights,grid)
и мы пытаемся максимизировать эту стоимостьЯ являюсь автором контроллера 2048, который набирает больше очков, чем любая другая программа, упомянутая в этой теме. Эффективная реализация контроллера доступна на github . В отдельном репозитории также есть код, используемый для обучения функции оценки состояния контроллера. Метод обучения описан в статье .
Контроллер использует поиск expectimax с функцией оценки состояния, изученной с нуля (без опыта человека 2048) с помощью варианта обучения во временной разнице (метод обучения с подкреплением). Функция состояния-значения использует сеть с n-кортежами , которая в основном представляет собой взвешенную линейную функцию шаблонов, наблюдаемых на плате. Всего задействовано более 1 миллиарда весов .
Представление
1 ход / с: 609104 (в среднем на 100 игр)
На 10 ходов / с: 589355 (в среднем 300 игр)
При 3 слоях (около 1500 ходов / с): 511759 (в среднем 1000 игр)
Статистика тайлов за 10 ходов в секунду выглядит следующим образом:
(Последняя строка означает наличие данных плиток одновременно на доске).
Для 3-х слоев:
Тем не менее, я никогда не наблюдал, чтобы он получал плитку 65536.
источник
Я думаю, что нашел алгоритм, который работает довольно хорошо, так как я часто набираю более 10000 баллов, мой личный рекорд - около 16000. Мое решение не в том, чтобы держать большие цифры в углу, а в верхнем ряду.
Пожалуйста, смотрите код ниже:
источник
770.6
, в то время как эта получила просто396.7
. У вас есть предположение, почему это может быть? Я думаю, что это делает слишком много взлетов, даже когда влево или вправо слиться намного больше.Существует уже реализация ИИ для этой игры здесь . Выдержка из README:
В Hacker News также обсуждается этот алгоритм, который может оказаться полезным.
источник
Алгоритм
оценка
Детали оценки
Это константа, используемая в качестве базовой линии и для других целей, таких как тестирование.
Больше пробелов делает состояние более гибким, мы умножаем на 128 (что является медианой), поскольку сетка, заполненная 128 гранями, является оптимально невозможным состоянием.
Здесь мы оцениваем грани, которые имеют возможность слияния, оценивая их в обратном порядке, плитка 2 приобретает значение 2048, а плитка 2048 оценивается 2.
Здесь нам все еще нужно проверять суммированные значения, но в меньшей степени, что не прерывает параметры гибкости, поэтому у нас есть сумма {x в [4,44]}.
Государство является более гибким, если оно имеет больше свободы возможных переходов.
Это упрощенная проверка возможности слияния в этом состоянии без предварительного просмотра.
Примечание: константы могут быть изменены.
источник
constant
? Если все, что вы делаете, сравнивает результаты, то как это влияет на результаты этих сравнений?Это не прямой ответ на вопрос ОП, это больше материала (экспериментов), который я до сих пор пытался решить той же проблемой, и получил некоторые результаты и хочу поделиться некоторыми наблюдениями, мне интересно, можем ли мы дальнейшее понимание этого.
Я только что попробовал свою минимаксную реализацию с альфа-бета-отсечкой с отсечкой глубины дерева поиска в 3 и 5. Я пытался решить ту же проблему для сетки 4x4, что и проектное задание для курса edX ColumbiaX: CSMM.101x Artificial Intelligence ( AI) .
Я применил выпуклую комбинацию (пробовал разные эвристические веса) пары эвристических функций оценки, в основном из интуиции и из обсуждавшихся выше:
В моем случае, компьютерный проигрыватель абсолютно случайный, но я все же принял противоборствующие настройки и ввел агента AI-игрока в качестве максимального игрока.
У меня есть сетка 4х4 для игры.
Наблюдение:
Если я назначу слишком много весов первой эвристической функции или второй эвристической функции, в обоих случаях оценки, которые получает AI-игрок, низкие. Я играл со многими возможными назначениями веса для эвристических функций и брал выпуклую комбинацию, но очень редко ИИ-игрок мог набрать 2048. В большинстве случаев он останавливается на 1024 или 512.
Я также попробовал эвристику угла, но по какой-то причине это ухудшает результаты, какая-то интуиция почему?
Кроме того, я попытался увеличить ограничение глубины поиска с 3 до 5 (я не могу увеличить его больше, так как поиск, который занимает пространство, превышающее допустимое время даже при сокращении), и добавил еще одну эвристику, которая просматривает значения соседних плиток и дает больше очков, если они сливаются, но я все еще не могу получить 2048.
Я думаю, что будет лучше использовать Expectimax вместо минимакса, но все же я хочу решить эту проблему только с минимаксом и получить высокие оценки, такие как 2048 или 4096. Я не уверен, что я что-то упускаю.
Ниже на анимации показаны последние несколько шагов игры, в которую агент ИИ играл с компьютерным игроком:
Любые идеи будут действительно очень полезны, спасибо заранее. (Это ссылка на мой пост в блоге для статьи: https://sandipanweb.wordpress.com/2017/03/06/using-minimax-with-alpha-beta-pruning-and-heuristic-evaluation-to-solve -2048-игра-с-компьютером / и видео на YouTube: https://www.youtube.com/watch?v=VnVFilfZ0r4 )
Следующая анимация показывает последние несколько шагов игры, в которых агент AI-игрока мог получить 2048 баллов, на этот раз добавляя также эвристику абсолютного значения:
На следующих рисунках показано игровое дерево, исследуемое агентом ИИ игрока, который за один шаг воспринимает компьютер как противника:
источник
Я написал решатель 2048 на Хаскеле, главным образом потому, что сейчас изучаю этот язык.
Моя реализация игры немного отличается от реальной игры тем, что новая плитка всегда равна 2 (а не 90% 2 и 10% 4). И что новая плитка не случайная, а всегда первая доступная вверху слева. Этот вариант также известен как Det 2048 .
Как следствие, этот решатель является детерминированным.
Я использовал исчерпывающий алгоритм, который предпочитает пустые плитки. Он работает довольно быстро на глубине 1-4, но на глубине 5 он становится довольно медленным - около 1 секунды за ход.
Ниже приведен код, реализующий алгоритм решения. Сетка представлена в виде массива целых чисел длиной 16. А подсчет очков производится просто путем подсчета количества пустых квадратов.
Я думаю, что это довольно успешно из-за своей простоты. Результат, который достигается при запуске с пустой сеткой и решении на глубине 5:
Исходный код можно найти здесь: https://github.com/popovitsj/2048-haskell
источник
Этот алгоритм не оптимален для победы в игре, но он довольно оптимален с точки зрения производительности и количества необходимого кода:
источник
random from (right, right, right, down, down, up)
так говорите, не все ходы имеют одинаковую вероятность. :)Во многих других ответах используется искусственный интеллект с дорогостоящим поиском возможных вариантов будущего, эвристики, обучения и тому подобного. Это впечатляет и, вероятно, правильный путь вперед, но я хотел бы внести еще одну идею.
Смоделируйте стратегию, которую используют хорошие игроки в игре.
Например:
Читайте квадраты в порядке, показанном выше, пока значение следующих квадратов не станет больше текущего. Это представляет проблему попытки объединить другую клетку с таким же значением в этот квадрат.
Чтобы решить эту проблему, есть два способа перемещения, которые не остались ни хуже, и изучение обеих возможностей может сразу же выявить больше проблем, это формирует список зависимостей, каждая из которых требует решения еще одной проблемы в первую очередь. Я думаю, что у меня есть эта цепь или в некоторых случаях дерево зависимостей внутри при принятии решения о моем следующем шаге, особенно когда застрял.
Плитка нуждается в объединении с соседом, но она слишком мала: объедините другого соседа с этим.
Большая плитка на пути: Увеличьте значение меньшей окружающей плитки.
так далее...
Весь подход, вероятно, будет более сложным, чем этот, но не намного более сложным. Это может быть механическое чувство, когда не хватает очков, веса, нейронов и глубоких поисков возможностей. Дерево возможностей даже должно быть достаточно большим, чтобы вообще нуждаться в ветвлении.
источник