Die letzte Herausforderung ( Pixel-Art, Episode 1: Super Mario anzeigen ) war nur ein Training ... (und du hast es auf erstaunliche Weise abgeschlossen, danke!)
Dieses Mal musst du ein bisschen mehr arbeiten. Sie müssen alle ersten Überweltkarten von Super Mario bros auf NES anzeigen, ohne Feinde und ohne Mario.
Ihr Programm oder Ihre Funktion muss alle Pixel des folgenden Bildes anzeigen ODER eine ähnliche Bilddatei erstellen (BMP, PNG oder GIF).
Ihr Programm darf in keiner Weise auf das Internet zugreifen.
Die Ausgabe kann gezoomt werden, wenn Sie möchten, und die Pixel können ASCII- oder HTML-Elemente sein, wenn Sie möchten, solange sie die richtige Farbe haben.
Hier ist das Modell, dem du folgen musst:
Das ganze Bild: http://i.stack.imgur.com/2kfVc.png
Das Kachelset (falls erforderlich): http://img.ctrlv.in/img/14/10/19/5443f44c7eb78.png
Sie können Ihr eigenes Kachelset, eine Teilmenge oder eine Obermenge dieses Kachelsets erstellen.
Sie können Ihr Kachelset als separate Bilddatei verwenden oder es in Ihren Code einfügen (z. B. in base64). Wenn es separat ist, addieren Sie seine Größe in Bytes zu Ihrer Punktzahl.Die Karte mit den Koordinaten: http://goo.gl/c8xJIx oder http://img.ctrlv.in/img/14/10/19/544373adc9f64.png
Die Farben:
Himmelblau: # 5C94FC Schwarz: # 000000 Pink: # FCBCB0 (für die Blöcke und das Schloss) Brown: # C84C0C (für die Blöcke und das Schloss) Orange: # FC9838 (für den "?" - Block) Hellgrün: # 80D010 (für Büsche, Berge, Fahnenmast, Warp) Dunkelgrün: # 00A800 (für Büsche, Berge, Fahnenmast, Warp) Weiß: #FCFCFC (Wolken) Hellblau: # 3CBCFC (Wolken)
Kürzeste Antwort gewinnt.
BEARBEITEN: Es gibt zwei Anzeigetafeln, von denen eine in Bytes und eine in Zeichen gezählt wird.
Viel Glück!
PS: Hier sind einige Hinweise, die Ihnen bei der Optimierung Ihres Programms helfen könnten:
- Wolken, Büsche und Berge haben ein sich wiederholendes Muster (alle 48 Spalten)
- Fliegende Blöcke sind nur in den Zeilen 4 und 8 vorhanden
- Jede Kachel oder jedes Sprite der Karte verwendet höchstens 4 Farben (einschließlich blau oder transparent, je nachdem, wie Sie es sehen).
- Sträucher sind nur "Wolkenoberkante" mit einer anderen Farbpalette
- Einzel-, Doppel- und Dreifachbüsche / -wolken können mit dem gleichen Minisatz von 16 x 16 Pixel problemlos geformt werden. Dies gilt auch für die Einfach- und Dreifachberge
Antworten:
x86-Maschinencode,
1729161914681382 BytesSo funktioniert es: Kacheln werden durch eine Kombination aus RLE-Komprimierung, 2-Bit-Bildern und Prozedurcode generiert. Sobald die Kacheln im Speicher generiert wurden, erstellt das Programm eine Matrix von Kachelindizes. Dies wird zuerst mit dem sich wiederholenden Hintergrund geladen. Danach werden die Rohre, Schwimmblöcke, Pyramiden und der Fahnenmast prozedural gezogen. Die Rohre, Hügel, Büsche und Pyramiden können sich unter der Erde erstrecken, werden aber verdeckt, wenn die Felsplatten als nächstes geschrieben werden. Zum Schluss werden die Schlossplättchenwerte einfach an die richtige Stelle kopiert. Zum Generieren der Bilddatei werden der BMP-Header und die Palette als Daten in der Datei gespeichert und zuerst geschrieben. Das Programm durchläuft dann die Matrix und schreibt für jede Position die entsprechende Zeile aus der entsprechenden Kachel.
Verwendung: Führen Sie mario.com aus. Es wird "m.bmp", eine Standard-BMP-Image-Datei, generiert. Die Datei wird als versteckte Datei erstellt, da diese weniger Bytes enthält.
Laden Sie eine ZIP-Datei herunter, die den Quellcode und die Binärdatei sowie die Ausgabe enthält.
Assembler-Code zum Generieren der ausführbaren Datei:
quelle
Minimiertes Javascript (*):
1285 1258 1253 1205 11861171 Zeichen(*) Minimiert mit Closure, RegPack und ObfuscaTweet, wie von xem vorgeschlagen
Die Unicode-Version hat eine Größe von 4549 Bytes, ohne ObfuscaTweet (nur Closure und Regpack), und eine Größe von 2251 Bytes.
Geschichte:
1285 -> 1258: Variable
A
für 48 (thx @hsl), einige derfor
Schleifen zusammengeführt, zusammengeführtmt()
undmu()
unter Verwendung von Kachelindizes anstelle von Kachelzeichenfolgen mit PNGOUT png optimiert1258 -> 1253: einige weitere
for
Schleifen zusammengeführt; umbenanntmt()
inr()
; unnötige Klammern entfernt; variabelB
für 16; Definieren von 16 nicht verwendeten CSS-Sprites (ersetzt 32 durchA
); 1 nicht benutzte Zeile anzeigen (ersetzt 14 durchB
); entfernte Funktione()
; verkürztt()
,g()
,c()
; verwendenfor(i=0;i<n;)f(i++)
stattfor(i=0;i<n;i++)f(i)
wo möglich1253 -> 1205: Body Style in CSS Part verschoben statt
<body style=...>
; Einigefor
Schleifen wurden durchf
Anrufe ersetzt. optimierte Funktionenr
,q
;</head><body>
scheint auch unnötig<html><head>
zu sein; Funktiont(i)
für CSS-Mapping entfernt; CSS Namenb0
..b31
statta
..z
,aa
..ff
1205 -> 1186: Funktion
n
umbenannt inN
; Neue Funktionn
, die ein Array mit Delta-Codierung verarbeitet1186 -> 1171: Hügel und Verzerrungen können jederzeit "groß" gezeichnet werden, die unteren Teile werden von Steinblöcken überzeichnet; verwenden Sie
d
für Wolken und Büsche; Einige unnötige Semikolons wurden entferntDies ist ein verfahrenstechnischer Versuch. Es gibt überall Muster, eine der magischen Zahlen ist 48 (Kachellücke zwischen Wolken, Büschen und Bergen). Das Kachelset wird als Base64-Daten-URL-String codiert und als CSS-Stylesheet verwendet. In Javascript ist das 212x14-Array
m
mit Kachelindizes gefüllt. Weitere Informationen finden Sie in der kommentierten, nicht verkürzten Version.Funktioniert in Chrome 38 (Strg + T für neuen Tab, Strg + Umschalt + J für Javascript-Konsole, Code dort einfügen) und Firefox 33 (wenn mit HTML-Javascript-Tags umschlossen). Es gibt auch eine JS-Bin-Version .
Es gibt noch Raum für Optimierungen, ich werde Updates veröffentlichen und es wäre schön, wenn einige JS / CSS / HTML-Leute Optimierungen / Korrekturen vorschlagen könnten.
Minimiert:
Nicht abgeschlossen und kommentiert:
quelle
function l(i,j,s){for(k=0;k<j;k++)n(i+k*W,s);}
kann gekürzt werden, indem man k ++ in die Funktion extrahiert, denke ich? So kann die nächste Zeile mit j.Python3
1638157616161513 Bytes581 Code + 932 Daten
↑ Dies ist das Originallevel. In der Mitte befindet sich das von diesem Skript erzeugte PPM. Unten ist ein Unterschied, und dies zeigt, dass die Palette und die Karte nicht genau übereinstimmen! Ich habe das auf Datenfehler und nicht auf mein Skript zurückgeführt;)
(ohne Kommentare gezählte Bytes, Zeilenumbruch und Einzug der zweiten Ebene
\t
)Daten (Base64-kodiert zum Einfügen; dekodieren und als Datei mit dem Namen "i" speichern):
Die Datendatei ist ein benutzerdefiniertes Format, das ich für dieses Problem erstellt habe, und wird als LZMA gespeichert.
Zuerst werden alle 32 Kacheln serialisiert. Es gibt 9 Farben in der Palette, und dies dauert unkomprimiert 8219 Bytes. (Ich fand heraus, dass das Komprimieren der Kacheln mit 4 Bit pro Pixel überhaupt nicht zu einer Komprimierung beitrug. Ich habe nicht versucht, die beste Reihenfolge der Kacheln zu erzwingen, und ich verliere hier wahrscheinlich ein paar Punkte.)
Die Karte besteht aus 212x14 = 2968 Blöcken.
Dann werden die Anweisungen zum erneuten Erstellen der Karte jetzt codiert.
Zuerst folgt ein Abschnitt mit "put" -Befehlen, mit denen eine Reihe von Kacheln aus der Kachel-Palette auf der Karte an einem bestimmten x, y platziert werden. Da es 32 Kacheln gibt, gebe ich einen Lauf derselben Kachel an, wobei ich eine Zahl größer als 32 anstelle des Kachelindex verwende.
Dann folgt ein Abschnitt mit "Kopieren" -Befehlen, mit denen ein Rechteck der aktuellen Karte an eine andere Stelle kopiert wird. Es gibt eine spezielle Bitmaske, die angibt, ob die Kopie gespiegelt werden soll.
Ein kurzes Beispiel für einen Befehlspuffer:
(Ich sagte kurz , aber das ist tatsächlich fast die Hälfte des gesamten Befehlspuffers, der benötigt wird, um die gesamte Karte zu erstellen. Die überwiegende Mehrheit der Bytes in den Daten sind die 32 Quellkacheln selbst.)
Dann folgt ein zweiter Abschnitt mit "put" -Befehlen und schließlich ein weiterer Abschnitt mit "copy" -Befehlen.
Da sich diese überschreiben können, kann ich Kopierteile erstellen, die ich später lösche oder ändere.
Zweifellos kann ich ein paar Bytes mehr davon abschneiden, indem ich zum Beispiel Puts in kleine Kopien
eval
verwandle und einen gezippten Quellcode ausführe, oder indem ich mit PNG spiele (was mit bildspezifischen Filtern DEFLATE ist). Aber ich mag Dinge, die so ausführlich sind.quelle
3,11
scheint die Kachel in der Palette zu fehlen. Es scheint ein wenig Rauschen auf der Karte zu sein20,12
und die allgemeinen Umrisse von Bäumen und Wolken können ein Ausrichtungsfehler in der Palette sein. Es gibt nur 9 Farben, es kann also kein Mischartefakt sein.Javascript,
106910721024 Zeichen (1957 Byte)RegPacked und Obfuscatweeted
Freier Code
Ich habe diesen Code ausgeblendet, weil unten ungolfter Code steht.
Code-Snippet anzeigen
Ungolfed Code
Ich habe zuerst Kacheln in Sprites mit @ schnaaders minimiertem Daten-URI gemacht.
0 ~ v
(die 0 ~ 31 in Basis 31 ist) repräsentiert jede Kachel.Und ich habe die Karte von Hand in Kacheln umgewandelt. Diese Daten haben 212 Zeichen pro Zeile.
Dann habe ich wiederholende Zeichen (wie
7
(Himmel) und1
(Boden)) durch ersetztrepeat()
.Ich habe
7
s und einige Blöcke gefunden und ein anderes7
Muster wird wiederholt. Also habe ich eine andere Funktion gemacht, um es kompakt zu machen. Sie können es bei nicht verschleierten Quellcode sehen.Schließlich habe ich meinen 2341-Byte-Golf-Code neu gepackt und obfuscatweetet.
Es war eine sehr lustige Herausforderung. Vielen Dank! Und danke an @xem für weitere Tricks.
quelle
JavaScript:
3620 (autsch)34293411Aktualisierung
Update # 1: Entfernte
var
Definitionen und legen Sie die Variablendeklarationen in Klammern der ersten Verwendung. Entfernt,getElementById()
da es auch beim Laden als Variable nach ID verfügbar ist. Verwenden SiecloneNode()
anstelle voncreateElement('CANVAS')
. Umbenannt in main vonxMx
nachM
. Skalierungsfunktion entfernt :(, (im Beispiel immer noch verfügbar. )Einige Kommentare zum erweiterten Code hinzugefügt. (Dieser Code wird bei den Entfernungen nicht aktualisiert. Die folgende Zeile ("Mini-Code") lautet.)
Update Nr. 2: Entfernte die Hauptfunktion
M()
als Ganzes und ließ den Code im Stammverzeichnis laufen . Dazu müsste der Code in einem Load Wrapper oder am Ende des Dokuments platziert werden.Update Nr. 3: Statistik hinzugefügt.
Mini-Code:
Bla bla:
- Demo am Ende des Beitrags.
Verwenden von Canvas als Basis für einen Versuch, dies zu lösen. Endete mit ungefähr 6000 Zeichen, aber nach einigem Hin und Her (und einer benutzerdefinierten Komprimierung - mit Hin und Her und auch Änderungen daran) bin ich jetzt bei der angegebenen Nummer. Immer noch hoch, aber andererseits ist die Qualität gut ;-).
Es enthält auch eine Skala Option, erstes Argument für die
xMx()
, auch bekannt als „main“ Funktion. 1 = normale Größe (wie bei 16-Bit-Kacheln). Es gibt nicht viel Raum für Optimierungen. Wenn Sie also Brüche verwenden, passen einige der Kacheln nicht am besten zusammen. Bei ganzen Zahlen sollte es OK sein. [1]Aber: warnen, hochgehen, schnell Ressourcen fressen und eine riesige Leinwand schaffen. (Alles wird auf einmal gemalt.) Wenn die ursprüngliche Breite 3392 Pixel beträgt, wird sie schnell riesig. [1]
[1] Ab Update 1 wurde dieses entfernt. Es ist in der Demo vorhanden.
Statistiken:
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 Byte ";" zwischen dem Haupt- / Datencode.
Die komprimierten Daten sind ein Array Å und ein "Objekt" Ø. Wobei Å die Platzierung der Fliesen und der Ø die Daten für das Bemalen der Fliesen enthält. Der Ø hätte auch ein Array sein sollen - aber als mein Code mit so etwas begann:
Es endete so wie es ist. Ich werde vielleicht sehen, ob ich das nicht beheben kann. Im Idealfall hätte ich es mit JSON anstelle von eval () syntaktisch analysierbar gemacht, aber das wäre kein Punkt in einem Wettbewerb wie diesem. Wie es jetzt ist, kann JSON aufgrund fehlender Anführungszeichen um die ID-Teile nicht analysiert werden.
Demo
Hier ist eine Geige, wo man den Code in Aktion sehen kann. Den Code in der Geige habe ich etwas erweitert (und einige HTML / CSS-Stile auf der ganzen Welt hinzugefügt - aber das Bild von sich selbst ist selbsttragend.):
MARIOS WELT
Erweiterter Code:
Erweiterter und (etwas) neu angeordneter Code:
quelle
var
, um Variablen zu deklarieren. Sie werden automatisch deklariert, wenn Sie sie definieren. Sie sollten also in der Lage sein, sievar D,C,c,S,s,R,F,Z,
aus Ihrem Code zu entfernen . (auch können Sie ersetzen/.{2}/
mit/../
.)var
, beließ es aber, da ich es ausführen musste, als ich es veröffentlichte. Jetzt erledigt Die RegExp war eine schöne, irgendwie nicht geschafft, das zu sehen;)ev(a|i)l
Routine). Wenn es "legal" ist, dann OK.eval(unescape(escape('𨑬𩑲𭀨𘣆𘠩').replace(/uD./g,'')))
funktioniert wie beabsichtigt. Und ja, Ihre Punktzahl wird in Zeichen gezählt, sodass Sie Tricks wie Unicode-Komprimierung und Eval verwenden können. Damit könnten Sie eine Punktzahl in der Nähe von 1750 erzielen!Python
133113261314127212681217 Bytes(Code:
219214202186182, Daten:362 + 750 = 1112363 + 723 = 1086346 + 689 = 1035)Die Idee hier ist, dass ich zuerst eine Karte mit einer Größe von einem Sechzehntel in jeder Dimension generiere, wobei jedes Pixel durch den Index in der Kachelkarte farbig wird. Um sicherzustellen, dass dieselbe Palette verwendet wurde, habe ich zuerst die angegebene Kachelkarte und die Karte zu einem einzigen Bild kombiniert. Daraus und aus der Kachelkarte (beide Minifragmente) können wir nun die ursprüngliche Karte neu generieren. (Der Code für diesen Vorgang ist unter dem Einreichungscode zu sehen.) Es ist zu beachten, dass ich die Kachelkarte als Datei "t" und die erzeugte Karte als Bild "m" gespeichert habe.
BEARBEITEN: Ich habe angefangen zu untersuchen, wie die Reihenfolge der Kacheln die Komprimierung beeinflusst, und der Exploration halber habe ich 10000 zufällige Permutationen generiert und sie mit diesem Ergebnis komprimiert: Dies war alles mit den Kacheln in einer Zeile, da dies den Code ziemlich reduzierte Bit. Ich habe ähnliche Dinge mit unterschiedlichen Konfigurationen versucht (2 * 16, 4 * 8), aber keine mit einem besseren Durchschnittsergebnis.
Angenommen, png würde mit größeren zusammenhängenden ähnlichen Bereichen besser komprimiert, dann habe ich ein Werkzeug erstellt, mit dem ich die Kacheln verschieben kann, und unter Verwendung eines von mir als zusammenhängender empfundenen Bildes habe ich das Kachelbild von 750b auf 723 gesenkt.
EDIT2: Nachdem (viel) mehr analysiert wurde, wie png tatsächlich funktioniert, und viel experimentiert wurde (noch nicht abgeschlossen), wurden die Bilder jetzt noch weiter komprimiert. Link unten aktualisiert. Ich werde später mehr über diese Analyse schreiben, wenn sie abgeschlossen ist.
Neue verwendete Bilder finden Sie hier: http://imgur.com/a/RgkXx
Hier sind die anderen Bilder, die dabei erzeugt werden: http://imgur.com/a/HXTGA , obwohl einige aufgrund der obigen Bearbeitung etwas veraltet sind.
Das Skript, das ich geschrieben habe, um die Karte zu verkleinern, ist ziemlich grob, aber hier ist es (könnte auch wegen der obigen Änderungen veraltet sein):
quelle
Perl 5 + PNG: 689 + 593 = 1282
Ein fehlgeschlagener Versuch, eine PNG-komprimierte Kachelkarte aus Christians Lösung durch Perl-Code zu ersetzen. Am Ende sind es 65 Bytes länger. Nimmt die gleichen PNG-Kacheln für die Eingabe und generiert eine PNG für die Ausgabe.
Verwendung:
perl mario.pl <tiles.png >world.png
quelle
JS:
40123921 ZeichenJS wird verwendet, um viele Unicode-Zeichen zu entpacken und ein img-Tag zu schreiben, wobei src das im OP angegebene Bild ist, das als PNG gespeichert, komprimiert, in base64 codiert und gekürzt wird.
Demo: http://jsbin.com/fojidejoco/1/
PS: Ich weiß, dass es ein bisschen schummelt (auch wenn die Regeln es zulassen), aber zumindest gibt es uns ein Ziel: Mach es in weniger als 4012 Zeichen.
Benutztes Werkzeug:
quelle