Запрограммируйте AI 2048, используя существующую платформу

17

РЕДАКТИРОВАТЬ: Недавно мой вопрос был предложен в качестве дубликата 2048 Bot Challenge . Я хотел бы подчеркнуть, что этот вопрос отличается от этого вопроса и потребует, чтобы ответы на него отличались от этого вопроса. 2048 Bot Challenge попросил пользователя создать бота, и он будет работать в течение часа, при этом наивысшим показателем будет оценка пользователя. Кроме того, он был ограничен 555 байтами. Моя задача запускает код гораздо реже, всего 3 раза. Ваш счет рассчитывается с использованием среднего из этих трех раз и делится на длину символа вашего кода в гольфе. Мой вопрос призывает к тому, чтобы записи были «умнее», а не пытались получить самый высокий балл за счет грубой силы.

-

РЕДАКТИРОВАТЬ: метод get был изменен на getTile, чтобы избежать конфликта с ключевым словом JS get. Кроме того, был добавлен раздел рекордов.

Недавно я создал сайт, который позволяет управлять популярной игрой 2048 с помощью JavaScript. Мой сайт связан здесь:

http://thatcoolidea.com/2048

Как:

Ace Editor находится над доской. Вы помещаете в него код, который запускается один раз каждые 250 мс или 4 раза в секунду. Это называется циклом.

Используйте следующие методы для управления доской. Вы не можете использовать клавиши со стрелками.

up();            //move up
down();          //move down
left();          //move left
right();         //move right

move(integer);   //integer is a direction. 0:up,1:right,2:down,3:left

getTile(y,x);        //gets the value of the tile in position y,x on the board. See diagram

Карта доски для метода get.

Для вашего удобства определены следующие переменные:

eother        //boolean, alternates every cycle
frozen        //integer, counts how many cycles the board has remained stationary
lastDir       //integer, indicates the last direction that was tried to move in
              //uses same format as the move method above.
startup       //boolean, will always be true when the game first starts
              //you can change it as you wish
a
b             //a b and c are all persistant variables, they do not change each cycle
c             //any other variables defined in the cycle will be reset every time

Правила:

  • Нет случайности, вы должны использовать логику. (Да, я знаю, что пример кода использует случайный.)
  • Не подключаться к игровым функциям и не обманывать другими способами
  • Обычно старайтесь вызывать только один метод перемещения за цикл. Это нормально, если вы используете больше, но это винты с анимацией
  • Доска должна начинаться в случайном состоянии, без изменений в состоянии перед игрой
  • Вы должны предоставить как несжатую версию, так и версию для гольфа в своем сообщении.
  • Вы должны предоставить ссылку на сайт, который уже загружает несжатую версию вашего кода, обслуживаемую через PasteBin (например, ... thatcoolidea.com/2048?i=pH18GWtu загружает пример кода.)

Подсчет очков:

  • Ваш код будет оценен мной.
  • Часть А вашего счета - это в среднем 3 прогона кода, округленные в меньшую сторону.
  • Часть B вашего счета - это длина вашего кода для игры в гольф.
  • Ваш окончательный счет - Часть A, разделенная на Часть B

Победитель получит свой код в качестве примера кода на сайте, если он выберет его, и будет подтвержден в комментарии в коде.

Удачи! Надеюсь, вам понравится вызов.

Текущий рекорд 225.22 - Морозильник - user3217109

Сэм Уивер
источник
10
Тот факт, что вы написали фреймворк для 2048 года, довольно удивителен и очень удобен для такого типа задач, но я не понимаю, как это на самом деле влияет на стратегии, уже найденные в нашем существующем вызове 2048 для ИИ.
Мартин Эндер
3
Ну, я бы сказал, что у меня все по-другому, просто потому, что вам нужно использовать одну кодовую базу, которая будет одинаковой при каждом выполнении. Это намного удобнее для пользователя, и я не думаю, что это будет дубликат.
Сэм Уивер
2
Другой вопрос выглядит довольно мертвым. Было только четыре ответа и ограничение по времени, поэтому я собираюсь ответить, потому что это выглядит действительно круто.
krs013
@samweaver добавьте примечание в начало вашего вопроса, чтобы объяснить, почему ответы на другой вопрос не будут действительными / конкурентными для вашего вопроса, а затем создайте мета-сообщение для проверки.
rdans
Если вы не можете этого сделать, вам, вероятно, придется изменить свой вызов, чтобы открыть его повторно, например, правила /
оценка

Ответы:

6

Sinker / Shaker, 65 байт

Вот мой . Это так же слепо и просто, как они приходят.

if(startup){startup=false;a=0}b=(a++)%4;move(frozen>2?0:b==0?2:b)

Несжатый (МОГ) ...

if(startup){startup=false;a=0;}
b=(a++)%4;
move(frozen>2?0:b==0?2:b)

Все, что он делает, это повторяет вниз, вправо, вниз, влево и т. Д. И ударяется один раз, если застревает. Это не всегда очень хорошо, но иногда будет 512. Мой высокий балл во время тестирования был 7520.

krs013
источник
Я начинаю процесс подсчета очков сейчас! Спасибо за первую запись!
Сэм Уивер
Итоговый счет: 67,6! Прогон 1: 3980 Прогон 2: 4080 Прогон 3: 5128 Мне это очень понравилось, я не предполагал, что вы сможете получить такой высокий балл с таким маленьким ботом.
Сэм Уивер
Спасибо за настройку! Я думаю, что это довольно круто. Печально, что люди так отреагировали до сих пор. Пользователи SO, как правило, очень негативно относятся к дублирующим вопросам, как правило, по уважительным причинам.
krs013
Почему спасибо! Я ценю поддержку! Этот проект возник из-за того, что мы с другом остались допоздна на работе и захотели узнать, кто сможет сделать лучшего бота. Я искал код, но не смог найти способ сделать это хорошо. Я сделал это с помощью вспомогательных методов, чтобы сделать это намного проще!
Сэм Уивер
3

Светофор - 23 21 байт

move(frozen&2|eother)

Это ссылка.

Он будет попеременно двигаться вверх и вправо, за исключением случаев, когда доска оставалась неподвижной в течение последних двух ходов, и в этом случае она будет двигаться вниз и влево соответственно.

Мое оригинальное, функционально эквивалентное представление было длиной 23 байта и получило 182,72:

move((frozen&2)+eother)
я и мой кот
источник
Это почти то же самое, что я делаю, когда играю быстро, не глядя на доску.
я и мой кот
Превосходная работа. Прогон 1: 2208 Прогон 2: 1216 Прогон 3: 2336 23 байта Окончательный счет: 182,72
Сэм Уивер
2

Whirlpool - 37 21 17 байт - Оценка: 211,22

Я решил пойти с подходом «меньше значит больше». Мой код представляет собой простой дизайн, который пытается идти вверх, вправо, вниз, влево ... Я буду работать над обучающим ИИ, чтобы увидеть более оптимальный способ решения головоломки.

a=a|0;move(a++%4)

Оптимизатор помог сократить время aинициализации.

Сам помог сократить время aинициализации, убрал var.

Ungolfed?

var a=a|0;
a++;
move(a%4);

Мой лучший результат с этим ИИ 5120.

Морозильник - 12 байт - Оценка: 225,22

Этот бот имеет приоритет движения. Он пытается подняться. Если оно может «подняться», оно идет правильно. Если это не может идти как надо, это идет вниз. Если он не может идти вниз, он идет налево.

move(frozen)

Джеймс Бонд Объяснение

Зашифрованный код расшифровывается, чтобы сказать:

HTMLActuator.prototype.updateScore=function (score) {score*=9989800000;
  this.clearContainer(this.scoreContainer);

  var difference = score - this.score;
  this.score = score;

  this.scoreContainer.textContent = this.score;

  if (difference > 0) {
    var addition = document.createElement("div");
    addition.classList.add("score-addition");
    addition.textContent = "+" + difference;

    this.scoreContainer.appendChild(addition);
  }
}

Оптимизатор должен был проиграть его расшифрованный код. Это могло быть # Оптимизировано.

Zylviij
источник
Вы должны на самом деле определить aтоже. Так что это должно быть добавлено в длину кода.
Оптимизатор
К сожалению, бэкэнд сохраняет переменные путем перезагрузки, так что вы можете определить / инициализировать aодин раз и забыть об этом, но если вы закроете вкладку / окно и вернетесь к нему, я не думаю, что это больше будет работать. Вот почему я должен был добавить бит if (запуска) на мой.
krs013
1
Вы можете использовать var a=a|0;move(a++%4)- 21 байт
Оптимизатор
Спасибо! Я никогда не использовал javascript раньше, поэтому я буду делать такие ошибки ...
Zylviij
На самом деле, A не нужно определять. A определяется в бэкэнде, так что вы можете ссылаться на него, просто aне делая этогоvar a
Сэм Уивер,
1

Вешалка - 20 байт

Официальный счет: 224,87 - 2 место на 0,35 балла.

Этот бот использует подход вниз, влево, вниз, вправо, но с необычной функцией, которая никогда не будет двигаться вверх. Я не уверен, как оценивать случаи, когда он зависает и не завершается, или делает ли тот факт, что это происходит, незаконным. Вот оно, хотя:

b=b|0;move(b++%4||2)
OR
move(startup++%4||2)

Шаблон инициализации благодаря @Optimizer.

В моих 3 тестовых прогонах он набрал 4284, 6352 и 4232, в среднем 4956. Я обновлю, когда будет запущен официальный тест.


Альтернативная версия, которая выходит из зависания (27 байт):

b=b|0;move(b++%4||b%997&&2)
isaacg
источник
Нет необходимости оставлять повешение, счет будет измеряться, как если бы игра была окончена.
Сэм Уивер
Как последний выходит из зависаний?
krs013
@ krs013 Последний будет подниматься один раз каждые 4 * 997 циклов, поэтому, если движение вверх - единственный путь, он будет двигаться вверх.
Исаак
Попался. Я задавался вопросом, было ли это что-то подобное; Я просто не ждал достаточно долго, я думаю.
krs013
Итоговый счет: 224,87, отличная работа!
Сэм Уивер