Vlad-Shcherbina / icfpc2014-tbd

fourth place
Do What The F*ck You Want To Public License
4 stars 0 forks source link

Дискуссия: Lightning Round Submission #16

Closed manpages closed 10 years ago

manpages commented 10 years ago

Выжимка информации о том, чего нам не хватает и как мы будем это доделывать.

manpages commented 10 years ago

Для lightning'a было принято следующее решение — странслировать пакмана руками (с помощью или без помощи идей с промежуточным языком от fj, AST yole или лейблов от vorber).

Приоритетнее всего сделать

Важно сделать

Нужно сделать до дедлайна, но в последнюю очередь

Сейчас работает только Аня, те, кто просыпаются — присоединяйтесь к её работе. Vorber, Vlad, fj и manpages отваливаются на 6-8 часов.

Хочется небольшого гайда по коду в этом обсуждении. @Vlad-Shcherbina — ?

Vlad-Shcherbina commented 10 years ago

По коду.

Есть понятие спецификации для гостов и пакмана. Это строка, содержащая нужную информацию для создания соотуетствующего AI класса. AI классы никогда не создаются явно!

Спецификации гостов:

Cпецификации пакмана:

Очень желательно, чтобы стратегии были детерминированными. Это позволяет смотреть осмысленные реплеи. GhostAI_Random этому свойству не удовлетворяет, надо переделать prng с фиксированным сидом.

Стратегии гостов на питоне: ghost_ai.py. Сюда надо добавлять новые классы. #4 Это нужно чтобы победить в лайтнинге. Стратегии пакмана на питоне: lm_ai.py. Same. #5 Чтобы победить в лайтнинге нужно сделать несколько простых реализаций (возможно, параметризованных) и выбрать наилучшую, возможно подкручивая параметры

Провести набор матчей на разных картах с разными гостами - tournament.py. Посмотреть результаты этого турнира - tournament_viewer.py (детали в #6 ). Надо запускать чтобы понимать какой пакман лучше и победить в лайтнинге

visualizer.py - можно управлять пакманом, можно запустить с ai. Он же используется для просмотра риплеев с турнира. Перемотка назад - клавишей b (см. #7 ). Может пригодиться чтобы идентифицировать слабости пакмана и победить в лайтнинге

Генератор карт: map_generator.py. Можно расширять возможности, а можно просто варьировать параметры и генерить. #3 Это нужно сделать чтобы победить в лайтнинге

Fj-евский парсер gcc: asm_parser.py, peg_parser.py. Вроде он достаточно общий, чтобы можно было парсить и язык чуть более высокого уровня на нём, на детали не смотрел.

Есть ещё две реализации интерпретатора гцц, в скратчах у @vorber и @yole . Вроде обе почти готовы :)

test_all.py - не забывайте запускать.

Ещё чтобы победить в лайтнинге надо будет оттранслировать питонового пакмана в гцц-шный, но теоретически это можно сделать без написания кода, вручную и тестируя на их js шняге.

fj128 commented 10 years ago

У нас есть дикая проблема: game.py нифига не написана таким образом чтобы нормально сочетаться с GCC интерпретаторами.

Я поправил lambda_man_ai_from_spec чтобы он работал чуть более в соответствии с реальными требованиями GCC interpreter (ну, отдавал ему код хотя бы сразу), но этого недостаточно. GCC интерпретеру нужно чтобы ему ещё дали начальное состояние world тогда. И я как-то не соображу как это правильно сделать, потому что опять всё состоит из неочевидных коллбэков потому что Map сама инициализирует AI, блджад! Прям в процессе чтения карты, когда она ещё недочитана!

Почему нельзя было сделать чтение карты отдельно, получение конкретных AI для всего -- отдельно? Вызов статической функции чтобы получить экземпляр объекта через типа dependency injection -- это тоже коллбэк, Влад, с типичными коллбэковскими проблемами. Map не должна быть активным объектом, она должна проинициализить себя И БОЛЬШЕ НИЧЕГО НЕ ТРОГАТЬ.

Ещё я перефигачил vorber_gcc чтобы он не пытался сам ничего парсить, а жрал результат вызова asm_parser.parse_gcc(). А так же юзал command_enums для команд. Вроде, работает. Таким же образом надо перефигачить все остальные GCC интерпретаторы, потому что они должны получать тупо список команд, а не парсить их сами, потому что гипотетический парсер более высокоуровнего языка должен выдавать список команд, а не текстовый файл.

Алсо там нужно разобраться и поправить reset(), я не очень понимаю в какой именно момент оно должно вызываться и что должно делать. Т.е. как будто run() должен очистить control stack и запихнуть туда трапнутый стек фрейм, но что насчёт других стеков?

Ещё это всё в принципе вроде должно работать через gcc_wrapper, который сейчас вообще никакой, то есть там self не хватает в половине методов. Я его сейчас попытаюсь пофиксить.

Пока мы не решим эти проблемы, мы не сможем запускать GCC.

fj128 commented 10 years ago

Так, я пофиксил интерфейсы GCCInterface and GCCWrapper, по крайней мере что касается передачи параметров внутрь, функции marshall_int и marshall_cons это ровно то, что нужно.

Я не уверен насчёт initialize/step части интерфейса. Хотелось бы чтобы GCC предоставлял что-нибудь типа низкоуровневого call(address_or_closure, *initial_stack), а GCCWrapper реализовывал логику инициализации и последующих вызовов полностью сам. Но это Макс должен решить, я не разбираюсь во внутренностях GCC.

Что осталось:

  1. решить как это всё же делать и имплементировать это в vorber_gcc. И поправить gcc_wrapper соответственно. И разобраться где же нужно очищать какие стеки в gcc.
  2. в gcc_wrapper имплементировать конверсию world -> list/tuple/int в marshall_world

Далее, я вроде пофиксил callback hell в game.py, добавив LambdaManAI.initialize и вызов его для лямбда-мэнов после того как карта проинициализилась. Я не тестил, но по-моему теперь дожно всё работать! Ну, если пофиксить пункты выше.

Правда, в процессе обнаружилась ещё одна проблема:

  1. питоновские лямбдамэны (да и GCCWrapper) по идее должны наследоваться от LambdaManAI. Проблема в том, что game.py импортирует все модули в которых есть классы которые могут использоваться в качестве LambdaManAI до того как определяет класс LambdaManAI. Hilarity ensues. Сдаётся мне что нужно перефигачить динамический импорт классов (lambda_man_ai_from_spec и ghost тоже) на полную динамичность, чтобы они грузили модуль через __import__.

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

fj128 commented 10 years ago

Вместо того, чтобы забыться сном, я сходил до морька и выпил там пива.

Да, я был дико прав насчёт интерфейса GCC. В результате он выглядит так:

class GCCInterface(object):
    def call(self, address_or_closure, *args):
        'Call a function or closure.'

    def marshall_int(self, i):
        'Return an opaque handle representing i'

    def marshall_cons(self, car, cdr):
        'Return an opaque handle representing (car, cdr)'

Я оставил комментарии в имплементации VorberGCC, кому не влом, посмотрите чё там как и напишите код по моим указаниям. Я думаю, в результате оно ВНЕЗАПНО заработает.

Yole -- можешь свой gcc тоже перефигачить таким же образом, если не хочется на Максов смотреть.

gcc_wrapper должен работать кроме неимплементированной конверсии map -> tuple/list/int в marshall_world_state() и может ещё надо проверки на вменяемость возвращённых данных из call в initialize и step добавить.

Давайте уже, напишите кто-нибудь этот код, всё же ясно что делать =)

vorber commented 10 years ago

Я свою машину допилил до соответствия. FJ там был не совсем прав на тему что чистить и куда складывать (параметры извне должны складываться в environment а не на дата стэк, возвращаемое значение - одно(CONS) - на дата стэке) но это детали, сделал пару тестовых прогонов через call - seems working. Yole занимается конвертацией map->tuple для marhsall_world_state

yole commented 10 years ago

Нешмогла.