Последний вызов ( Pixel-art, эпизод 1: показ Super Mario ) был просто тренировкой ... (и вы ее выполнили потрясающим образом, спасибо!)
На этот раз вам придется работать немного больше. Вы должны отобразить все первые карты мира Super Mario bros на NES, без врагов и без Mario.
Ваша программа или функция должна отображать все пиксели следующего изображения ИЛИ создавать файл изображения, похожий на него (BMP, PNG или GIF).
Ваша программа никоим образом не должна иметь доступ к Интернету.
Вывод может быть увеличен, если вы хотите, и пиксели могут быть ASCII или HTML-элементами, если вы хотите, если они имеют правильный цвет.
Вот модель, которой вы должны следовать:
Целое изображение: http://i.stack.imgur.com/2kfVc.png
Набор плиток (если вам это нужно): http://img.ctrlv.in/img/14/10/19/5443f44c7eb78.png
Вы можете создать свой собственный набор плиток, подмножество или расширенный набор этого.
Вы можете использовать свой набор плиток как отдельный файл изображения или включить его в свой код (например, в base64). Если он отдельный, добавьте его размер в байтах к вашему счету.Карта с координатами: http://goo.gl/c8xJIx или http://img.ctrlv.in/img/14/10/19/544373adc9f64.png
Цвета:
Небесно-голубой: # 5C94FC Черный: # 000000 Розовый: # FCBCB0 (для блоков и замка) Коричневый: # C84C0C (для блоков и замка) Оранжевый: # FC9838 (для блока "?") Светло-зеленый: # 80D010 (для кустов, гор, флагштока, основы) Темно-зеленый: # 00A800 (для кустов, гор, флагштока, основы) Белый: #FCFCFC (облака) Голубой: # 3CBCFC (облака)
Кратчайший ответ выигрывает.
РЕДАКТИРОВАТЬ: будет две табло, одна из которых подсчитывается в байтах, а другая - в символах.
Удачи!
PS: Вот некоторые заметки, которые могут помочь вам оптимизировать вашу программу:
- Облака, кусты и горы имеют повторяющийся узор (каждые 48 столбцов)
- Летающие блоки присутствуют только в строках 4 и 8
- Каждая плитка или спрайт карты использует не более 4 цветов (включая синий или прозрачный, в зависимости от того, как вы их видите)
- Кусты - это просто "верхушка облаков" с другой цветовой палитрой
- Одиночные, двойные и тройные кусты / облака могут быть легко сформированы с использованием одного и того же мини-набора из 16x16 пикселей. Это также верно для одиночных и тройных гор
Ответы:
Машинный код x86,
1729161914681382 байтКак это работает: плитки генерируются комбинацией сжатия RLE, 2-битных изображений и процедурного кода. Как только плитки генерируются в памяти, программа создает матрицу индексов плиток. Это сначала загружается с повторяющимся фоном. После этого трубы, плавающие блоки, пирамиды и флагшток прорисовываются процедурно. Трубы, холмы, кусты и пирамиды могут простираться под землей, но прикрываются, когда каменные плитки пишутся дальше. Наконец, значения плитки замка просто копируются в правильное местоположение. Для создания файла изображения заголовок и палитра BMP сохраняются в файле в виде данных и записываются первыми. Затем программа проходит через матрицу, записывая соответствующую строку из соответствующей плитки для каждой позиции.
Использование: Запустите mario.com, он сгенерирует «m.bmp», стандартный файл образа BMP. Файл создается как скрытый файл, поскольку в результате получается меньше байтов.
Загрузите ZIP-файл, содержащий исходный код и двоичный файл, а также вывод.
Код сборки для генерации исполняемого файла:
источник
Сокращение Javascript (*):
1285 1258 1253 1205 11861171 символов(*) Сокращено с использованием Closure, RegPack и ObfuscaTweet, как предложено xem
Размер Unicode - 4549 байт, без ObfuscaTweet (только для Closure и Regpack), размер - 2251 байт.
История:
1285 -> 1258: переменная
A
для 48 (thx @hsl), объединила некоторыеfor
циклы, объединилаmt()
иmu()
, используя индексы тайлов вместо строк тайлов, оптимизировала png с PNGOUT1258 -> 1253: объединены еще несколько
for
петель; переименованmt()
вr()
; убраны лишние брекеты; переменнаяB
для 16; определение 16 неиспользуемых CSS-спрайтов (заменяет 32 наA
); показывает 1 неиспользуемый ряд (заменяет 14 наB
); удаленная функцияe()
; укороченаt()
,g()
,c()
; используяfor(i=0;i<n;)f(i++)
вместо того,for(i=0;i<n;i++)f(i)
где это возможно1253 -> 1205: перемещен стиль тела в часть CSS вместо
<body style=...>
; заменил некоторыеfor
циклы наf
вызовы; Оптимизированные функцииr
,q
;</head><body>
кажется ненужным<html><head>
тоже;t(i)
убрана функция отображения CSS; CSS именаb0
..b31
вместоa
..z
,aa
..ff
1205 -> 1186: функция
n
переименована вN
; новая функцияn
, работающая с массивом с дельта-кодированием1186 -> 1171: холмы и перекосы могут быть нарисованы "большими" в любое время, нижние части перекрыты каменными блоками; использование
d
для облаков и кустарников; убрал несколько ненужных точек с запятойЭто процессуальная попытка. Повсюду есть шаблоны, одно из магических чисел - 48 (разрыв между облаками, кустами и горами). Набор плиток кодируется в виде строки URL-адреса Base64 и используется в качестве таблицы стилей CSS. В Javascript массив 212x14
m
заполнен индексами . Смотрите закомментированную unminified версию для более подробной информации.Работает в Chrome 38 (Ctrl + T для новой вкладки, Ctrl + Shift + J для консоли javascript, вставьте туда код) и Firefox 33 (если обернуты тегами JavaScript javascript). Также есть версия JS bin .
Еще есть место для оптимизации, я буду публиковать обновления, и было бы неплохо, если бы некоторые JS / CSS / HTML люди могли предложить оптимизацию / исправления.
уменьшенная:
Unminified и прокомментировал:
источник
function l(i,j,s){for(k=0;k<j;k++)n(i+k*W,s);}
можно сократить путем извлечения k ++ в функцию, я думаю? Так может следующая строка с j.Python3
1638157616161513 байт581 код + 932 данных
Top Эта вершина является оригинальным уровнем. В середине - PPM, сгенерированный этим сценарием. Внизу есть различие, и это показывает, что палитра и карта не совпадают точно! Я объясняю это сбоями данных, а не сценарием;)
(байты считаются без комментариев, разворачивается строка и отступ второго уровня
\t
)Данные (в кодировке base64 для вставки; декодирование и сохранение в виде файла с именем «i»):
Файл данных - это пользовательский формат, который я создал для этой проблемы, и он хранится как LZMA.
Сначала все 32 плитки сериализуются. В палитре 9 цветов, и это занимает 8219 байт без сжатия. (Я обнаружил, что попытка сжимать тайлы с частотой 4 бита на пиксель не помогла вообще сжать. Я не пытался использовать грубую силу для лучшего упорядочивания тайлов, и я, вероятно, потерял здесь несколько очков.)
Есть 212x14 = 2968 блоков, составляющих карту.
Затем инструкции по воссозданию карты теперь закодированы.
Сначала идет раздел команд "put", которые размещают некоторую последовательность плиток из палитры плиток на карте в определенный x, y. Поскольку существует 32 плитки, я указываю прогон той же плитки, используя число больше 32, а не индекс плитки.
Затем идет раздел «копировать» команды, которые копируют некоторый прямоугольник текущей карты в другое место. Существует специальная битовая маска, которая отмечает, должна ли копия быть зеркальной.
Краткий пример буфера команд:
(Я сказал коротко , но на самом деле это почти половина общего буфера команд, необходимого для создания всей карты; подавляющее большинство байтов в данных - это сами 32 фрагмента источника)
Затем следует второй раздел команд «put» и, наконец, еще один раздел команд «copy».
Поскольку они могут перезаписывать друг друга, я могу создавать части для копирования, которые впоследствии стираю или изменяю.
Я, несомненно, могу побороть еще несколько байтов, например, превратив путы в маленькие копии и выполняя
eval
трюк на сжатом исходном коде, или играя с PNG (то есть с DEFLATE с помощью фильтров, специфичных для изображения). Но мне нравятся многословные вещи, как они есть.источник
3,11
кажется, отсутствует в палитре. Кажется, на карте вокруг есть какой-то шум,20,12
и общий контур деревьев и облаков может быть смещением выравнивания в палитре? Есть только 9 цветов, поэтому это не может быть какой-либо артефакт смешивания.Javascript,
106910721024 символа (1957 байт)RegPacked и Obfuscatweeted
Необъяснимый код
Я спрятал этот код, потому что ниже приведен код без ключа.
Показать фрагмент кода
Код без правил
Сначала я превратил плитки в спрайты с помощью минимизированного URI данных @ schnaader.
0 ~ v
(который составляет 0 ~ 31 в основании 31) представляет каждую плитку.И я конвертировал карту в плитки вручную. Эти данные имеют 212 символов в строке.
Затем я заменил повторяющиеся символы (например,
7
(небо) и1
(земля)) наrepeat()
.Я нашел
7
s и несколько блоков, и другой7
образец повторяется. Поэтому я сделал еще одну функцию, чтобы сделать его компактным. Вы можете увидеть это в необъяснимом исходном коде.Наконец я RegPacked, и Obfuscat написал мой код для игры в гольф 2341 байт.
Это было очень забавное испытание. Благодарность! И спасибо @xem за больше трюков.
источник
JavaScript:
3620 (ай)34293411Обновления
Обновление № 1: Удалены
var
определения и помещены объявления переменных в скобках первого использования. Удалено,getElementById()
поскольку оно также доступно при загрузке как переменное по идентификатору. ИспользованиеcloneNode()
вместоcreateElement('CANVAS')
. Переименован в главный изxMx
вM
. Удалена функция масштабирования :(, (все еще доступно в примере. )Добавлены некоторые комментарии к расширенному коду. (Этот код не обновляется при удалении. Строка ниже («Мини-код») есть.)
Обновление № 2: Удалил основную функцию
M()
в целом и разрешил запуск кода в корне . Это потребует, чтобы код был помещен в загрузочную оболочку или в конец документа.Обновление № 3: Добавлена статистика.
Мини код:
Бла бла
- Демо в конце поста.
Использование холста в качестве основы для попытки решить эту проблему. Закончилось около 6000 символов, но после некоторой тряски (и нестандартного сжатия - с тряпкой и настройками) я теперь на заявленном количестве. Все еще высоко, но опять же качество хорошее ;-).
Он также включает в себя параметр масштаба, первый аргумент функции
xMx()
, называемой «основной» . 1 = нормальный размер (как в 16-битных тайлах). Существует не так много места для настройки, так что если вы используете дроби, некоторые плитки не подходят друг к другу. На целых числах все должно быть в порядке. [1]Но: предупреждение, идущее вверх, быстро съедает ресурсы и превращается в огромный холст. (Это все нарисовано за один раз.) Когда исходная ширина составляет 3392 пикселей, она быстро становится огромной. [1]
[1] Начиная с обновления № 1 это было удалено. Это присутствует в демо.
Статистика:
Main code : 870
Compression:
Main data : 2176 (17,480 bits)
Key : 128 ( 1,024 bits)
Code : 236
Whole she bang : 2540
Decompressed data : 5608 (44,864 bits)
Total : 3410
[1][1]: +1 байт, ";", между основным кодом / кодом данных.
Сжатые данные представляют собой один массив Å и один «объект» Ø. Где Å - размещение плитки, а Ø - данные для рисования плитки. Ø также должен был быть массивом - но мой код начинался примерно так:
Все закончилось как есть. Я, возможно, посмотрю, смогу ли я это исправить. В идеале я бы сделал его разборчивым с JSON вместо eval (), но это не было бы точкой в конкурсе, подобном этому. Как и сейчас, он не может быть проанализирован JSON из-за пропущенных кавычек вокруг частей id.
демонстрация
Вот скрипка, где можно посмотреть код в действии. Код в скрипте, который я несколько расширил (и добавил несколько стилей HTML / CSS по всему миру - но само изображение является самостоятельным.):
MARIOS WORLD
Расширенный код:
Расширенный и (немного) переставленный код:
источник
var
для объявления переменных; они автоматически объявляются при их определении, поэтому вы сможете удалить ихvar D,C,c,S,s,R,F,Z,
из своего кода. (также вы можете заменить/.{2}/
на/../
.)var
но оставил это, поскольку я должен был бежать, когда я отправил это. Готово сейчас. RegExp был хорошим, как-то не удалось увидеть это;)ev(a|i)l
процедуры). Если это "законно", тогда ОК.eval(unescape(escape('𨑬𩑲𭀨𘣆𘠩').replace(/uD./g,'')))
работает как задумано. И да, ваш счет засчитывается в символах, так что вы можете полностью использовать такие приемы, как сжатие Unicode и eval. С этим вы можете получить счет около 1750!питон
133113261314127212681217 байт(код:
219214202186182, данные:362 + 750 = 1112363 + 723 = 1086346 + 689 = 1035)Идея здесь заключается в том, что я сначала создаю карту, равную 16-ому размеру в каждом измерении, где каждый пиксель окрашен индексом на карте мозаичного изображения. Чтобы убедиться, что использовалась одна и та же палитра, я сначала объединил данную карту тайлов и карту в одно изображение. Из этой карты и карты тайлов (оба минимизированных PNG) мы теперь можем восстановить исходную карту. (Код для этого процесса можно увидеть под кодом отправки). Следует отметить, что я сохранил карту тайлов в виде файла «t», а сгенерированную карту в виде изображения «m».
РЕДАКТИРОВАТЬ: я начал исследовать, как упорядочение плиток влияет на сжатие, и ради исследования я сгенерировал 10000 случайных перестановок и сжал их с таким результатом: это было все с плитками в одну строку, так как это уменьшило код довольно немного. Я пробовал похожие вещи с разными конфигурациями (2 * 16, 4 * 8), но ни один из них не показал лучшего среднего результата.
Предполагая, что png будет лучше сжиматься с большими непрерывными подобными областями, я создал инструмент, который позволил бы мне перемещать плитки, и используя то, что я воспринимал как более непрерывное изображение, я уменьшил изображение плитки до 723 с 750b.
РЕДАКТИРОВАТЬ 2: После (намного) большего анализа того, как на самом деле работает png, и большого количества экспериментов (все еще продолжающихся), изображения теперь были сжаты еще больше. Ссылка ниже обновлена. Я напишу больше об этом анализе позже, когда он будет завершен.
Новые используемые изображения находятся здесь: http://imgur.com/a/RgkXx
Вот другие изображения, сгенерированные в процессе: http://imgur.com/a/HXTGA , хотя некоторые немного устарели из-за вышеуказанного редактирования.
Сценарий, который я написал для уменьшения карты, довольно грубый, но здесь идет речь (также может быть устаревшим из-за изменений выше):
источник
Perl 5 + PNG: 689 + 593 = 1282
Неудачная попытка заменить сжатую карту листов PNG из решения Кристиана на код Perl. В конце концов, это на 65 байт длиннее. Принимает те же плитки PNG на входе и генерирует PNG на выходе.
Использование:
perl mario.pl <tiles.png >world.png
источник
JS:
40123921 символJS используется для распаковки многих символов Unicode и записи тега img, в котором src - это изображение, указанное в OP, сохраненное в формате PNG, сжатое, закодированное в base64 и обрезанное.
Демо-версия: http://jsbin.com/fojidejoco/1/
PS: я знаю, что это немного обманывает (даже если правила позволяют это), но, по крайней мере, это дает нам цель: сделать это менее чем за 4012 символов.
Используемые инструменты:
источник