Dernier défi ( Pixel-art, épisode 1: afficher Super Mario ) n'était qu'un entraînement ... (et vous l'avez terminé de manière incroyable, merci!)
Cette fois, vous devez travailler un peu plus. Vous devez afficher toute la première carte du monde de Super Mario bros sur NES, sans ennemis et sans Mario.
Votre programme ou fonction doit afficher tous les pixels de l'image suivante OU produire un fichier image similaire (BMP, PNG ou GIF).
Votre programme ne doit en aucun cas accéder à Internet.
La sortie peut être agrandie si vous le souhaitez, et les pixels peuvent être des éléments ASCII ou HTML si vous le souhaitez, tant qu'ils ont la bonne couleur.
Voici le modèle que vous devez suivre:
L'image entière: http://i.stack.imgur.com/2kfVc.png
Le jeu de tuiles (si vous en avez besoin): http://img.ctrlv.in/img/14/10/19/5443f44c7eb78.png
Vous pouvez produire votre propre jeu de tuiles, sous-jeu ou surensemble de celui-ci.
Vous pouvez utiliser votre jeu de tuiles en tant que fichier image distinct ou l'inclure dans votre code (par exemple, en base64). S'il est séparé, ajoutez sa taille en octets à votre score.La carte avec les coordonnées: http://goo.gl/c8xJIx ou http://img.ctrlv.in/img/14/10/19/544373adc9f64.png
Les couleurs:
Bleu ciel: # 5C94FC Noir: # 000000 Rose: # FCBCB0 (pour les blocs et le château) Marron: # C84C0C (pour les blocs et le château) Orange: # FC9838 (pour le bloc "?") Vert clair: # 80D010 (pour buissons, montagnes, mât de drapeau, chaîne) Vert foncé: # 00A800 (pour buissons, montagnes, mât de drapeau, chaîne) Blanc: #FCFCFC (nuages) Bleu clair: # 3CBCFC (nuages)
La réponse la plus courte l'emporte.
EDIT: Il y aura deux tableaux de score, l'un où les scores sont comptés en octets et l'autre où ils sont comptés en caractères.
Bonne chance!
PS: Voici quelques notes qui pourraient vous aider à optimiser votre programme:
- Les nuages, les buissons et les montagnes ont un motif répétitif (toutes les 48 colonnes)
- Les blocs volants ne sont présents que sur les lignes 4 et 8
- Chaque tuile ou image-objet de la carte utilise au plus 4 couleurs (y compris le bleu ou le transparent, selon la façon dont vous la voyez)
- Les buissons sont juste "au sommet des nuages" avec une palette de couleurs différente
- Des buissons / nuages simples, doubles et triples peuvent facilement être formés en utilisant le même mini-jeu de pièces 16x16px. Cela est également vrai pour les montagnes simples et triples
Réponses:
Code machine x86,
1729161914681382 octetsFonctionnement: les vignettes sont générées par une combinaison de compression RLE, d'images 2 bits et de code procédural. Une fois les tuiles générées en mémoire, le programme crée alors une matrice d'index de tuiles. Ceci est d'abord chargé avec l'arrière-plan extensible. Après cela, les tuyaux, les blocs flottants, les pyramides et le mât de drapeau sont dessinés de manière procédurale. Les tuyaux, les collines, les buissons et les pyramides peuvent s'étendre sous le sol, mais sont couverts lorsque les tuiles de roche sont écrites ensuite. Enfin, les valeurs des tuiles Château sont simplement copiées au bon endroit. Pour générer le fichier image, l'en-tête et la palette BMP sont stockés dans le fichier en tant que données et sont écrits en premier. Le programme parcourt ensuite la matrice, en écrivant la ligne appropriée à partir de la tuile correspondante pour chaque position.
Utilisation: exécutez mario.com, il générera "m.bmp", un fichier image BMP standard. Le fichier est créé en tant que fichier caché, car cela a fini par être moins d'octets.
Téléchargez un fichier ZIP contenant le code source et le binaire, plus la sortie.
Code d'assembly pour générer le fichier exécutable:
la source
Javascript minimisé (*):
1285 1258 1253 1205 11861171 caractères(*) Minifié à l'aide de Closure, RegPack et ObfuscaTweet, comme suggéré par xem
La version Unicode a une taille de 4549 octets, sans ObfuscaTweet (fermeture et Regpack uniquement), la taille est de 2251 octets.
Histoire:
1285 -> 1258: variable
A
pour 48 (thx @hsl), fusion de certainesfor
boucles, fusionmt()
etmu()
, en utilisant des index de tuiles au lieu de chaînes de tuiles, optimisé png avec PNGOUT1258 -> 1253: fusion de quelques
for
boucles supplémentaires ; renommémt()
enr()
; enlevé les accolades inutiles; variableB
pour 16; définir 16 sprites CSS inutilisés (remplace 32 parA
); montrant 1 ligne inutilisée (remplace 14 parB
); fonction suppriméee()
; raccourcit()
,g()
,c()
; utiliserfor(i=0;i<n;)f(i++)
au lieu defor(i=0;i<n;i++)f(i)
si possible1253 -> 1205: style de corps déplacé vers la partie CSS au lieu de
<body style=...>
; remplacé certainesfor
boucles par desf
appels; fonctions optimiséesr
,q
;</head><body>
semble également inutile<html><head>
;t(i)
suppression de la fonction de mappage CSS; Noms CSSb0
..b31
au lieu dea
..z
,aa
..ff
1205 -> 1186: fonction
n
renommée enN
; nouvelle fonctionn
qui fonctionne sur un tableau avec codage delta1186 -> 1171: les collines et les chaînes peuvent être dessinées "grandes" à tout moment, les parties inférieures sont surplombées par des blocs de pierre; utiliser
d
pour les nuages et les buissons; supprimé des points-virgules inutilesIl s'agit d'une tentative de procédure. Il y a des motifs partout, l'un des nombres magiques est 48 (écart entre les carreaux entre les nuages, les buissons et les montagnes). Le jeu de tuiles est codé en tant que chaîne d'URL de données Base64 et utilisé comme feuille de style CSS. En Javascript, le tableau 212x14
m
est rempli d'index de tuiles. Voir la version non minimisée commentée pour plus de détails.Fonctionne dans Chrome 38 (Ctrl + T pour le nouvel onglet, Ctrl + Maj + J pour la console javascript, collez-y le code) et Firefox 33 (s'il est entouré de balises HTML javascript). Il existe également une version JS bin .
Il y a encore de la place pour les optimisations, je publierai des mises à jour et ce serait bien si certaines personnes JS / CSS / HTML pouvaient suggérer des optimisations / corrections.
Minifié:
Non minimisé et commenté:
la source
function l(i,j,s){for(k=0;k<j;k++)n(i+k*W,s);}
peut être raccourci en extrayant k ++ à la fonction, je pense? Tout comme la ligne suivante avec j.Python3
1638157616161513 octetsCode 581 + données 932
↑ Ce haut est le niveau d'origine. Au milieu se trouve le PPM généré par ce script. En bas se trouve un diff, ce qui montre que la palette et la carte ne correspondent pas exactement! Je mets cela sur le compte du problème de données et non de mon script;)
(octets comptés sans commentaires, retrait de ligne et retrait de deuxième niveau
\t
)Données (encodées en base64 à coller; décoder et enregistrer en tant que fichier nommé "i"):
Le fichier de données est un format personnalisé que j'ai fait pour ce problème et est stocké en tant que LZMA.
Tout d'abord, les 32 tuiles sont sérialisées. Il y a 9 couleurs dans la palette, et cela prend 8219 octets non compressés. (J'ai trouvé qu'essayer de compresser les tuiles à 4 bits par pixel n'a pas aidé la compression du tout. Je n'ai pas essayé de forcer brutalement le meilleur ordre des tuiles, et je perds probablement quelques points ici.)
Il y a 212x14 = 2968 blocs composant la carte.
Ensuite, les instructions pour recréer la carte sont maintenant encodées.
Vient d'abord une section de commandes "put" qui placent une séquence de tuiles de la palette de tuiles sur la carte à un x, y particulier. Comme il y a 32 tuiles, je spécifie une exécution de la même tuile en utilisant un nombre supérieur à 32 plutôt que l'index de tuile.
Vient ensuite une section de commandes "copier" qui copient un rectangle de la carte actuelle vers un autre endroit. Il existe un masque de bits spécial qui indique si la copie doit être mise en miroir.
Un court exemple de tampon de commande:
(J'ai dit court , mais c'est en fait près de la moitié du tampon de commande total nécessaire pour créer la carte entière; la grande majorité des octets dans les données sont les 32 tuiles source elles-mêmes)
Vient ensuite une deuxième section de commandes "put" et enfin une autre section de commandes "copy".
Parce que ceux-ci peuvent se remplacer les uns les autres, je peux créer des parties de copie que j'efface ou modifie ultérieurement.
Je peux sans doute en raser quelques octets de plus en - par exemple - en transformant les mises en petites copies et en faisant l'
eval
astuce sur un code source compressé, ou en jouant avec PNG (qui est DEFLATE avec des filtres spécifiques à l'image) aussi. Mais j'aime les choses verbeuses telles qu'elles sont.la source
3,11
semble manquer dans la palette. Il semble y avoir un peu de bruit sur la carte20,12
et le contour général des arbres et des nuages peut être un problème d'alignement dans la palette? Il n'y a que 9 couleurs, il ne peut donc pas s'agir d'artefact de mélange.Javascript,
106910721024 caractères (1957 octets)RegPacked et Obfuscatweeted
Code non obscurci
J'ai caché ce code car il y a du code non golfé ci-dessous.
Afficher l'extrait de code
Code non golfé
J'ai d'abord fait des tuiles en sprites avec l'URI de données minifiées @ schnaader.
0 ~ v
(qui est compris entre 0 et 31 dans la base 31) représente chaque tuile.Et j'ai converti la carte en tuiles à la main. Ces données ont 212 caractères par ligne.
Ensuite, j'ai remplacé le caractère répétitif (comme
7
(ciel) et1
(sol)) parrepeat()
.J'ai trouvé des
7
s et des blocs, et un autre7
motif est répété. J'ai donc fait une autre fonction pour le rendre compact. Vous pouvez le voir sur le code source non obscurci.Enfin, j'ai RegPacked et Obfuscatweeted mon code de golf de 2341 octets.
C'était un défi très drôle. Merci! Et merci à @xem pour plus d'astuces.
la source
JavaScript:
3620 (ouch)34293411Mises à jour
Mise à jour # 1: Suppression des
var
définitions et mise des déclarations de variables entre crochets de première utilisation. SupprimégetElementById()
car il est également disponible en charge en tant que variable par ID. UtilisercloneNode()
au lieu decreateElement('CANVAS')
. Renommé principal dexMx
àM
. Suppression de la fonction de mise à l'échelle :(, (toujours disponible dans l'exemple. )Ajout de quelques commentaires au code développé. (Ce code n'est pas mis à jour avec les suppressions. La ligne ci-dessous, ("Mini code") , est.)
Mise à jour # 2: Suppression de la fonction principale
M()
dans son ensemble et laisser le code s'exécuter à la racine . Cela nécessiterait que le code soit placé dans un wrapper de chargement ou à la fin du document.Mise à jour # 3: Ajout de statistiques.
Mini code:
Bla bla:
- Démo en fin de post.
Utilisation de canvas comme base pour tenter de résoudre ce problème. Je me suis retrouvé avec environ 6000 caractères, mais après quelques manipulations (et une compression personnalisée - avec des manipulations et des ajustements à ce sujet également), je suis maintenant au nombre indiqué. Toujours haut, mais là encore la qualité est bonne ;-).
Il comprend également une option d'échelle, premier argument de la fonction
xMx()
, dite "principale" . 1 = taille normale (comme dans les tuiles 16 bits). Il n'y a pas beaucoup de place pour les ajustements, donc si l'on utilise des fractions, certaines des tuiles ne s'emboîtent pas mieux. En nombres entiers, cela devrait être OK. [1]Mais: avertissement, monter, mange rapidement des ressources et constitue une immense toile. (Tout est peint en une seule fois.) Lorsque la largeur d'origine est de 3392 pixels, elle devient rapidement énorme. [1]
[1] Depuis la mise à jour # 1, cela a été supprimé. Il est présent dans la démo.
Statistiques:
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 octet, ";", entre le code principal / données.
Les données compressées sont un tableau, Å, et un "objet" , Ø. Où Å contient le placement des tuiles et Ø contient les données pour peindre les tuiles. Le Ø aurait dû également être un tableau - mais comme mon code a commencé avec quelque chose comme ceci:
Il a fini tel quel. Je vais peut-être voir si je ne peux pas résoudre ce problème. Idéalement, je l'aurais rendu analysable avec JSON au lieu de eval (), mais ce ne serait pas un point dans un concours comme celui-ci. Comme il est maintenant, il ne peut pas être analysé en JSON en raison de guillemets manquants autour des parties id.
Démo
Voici un violon où l'on peut voir le code en action. Le code du violon que j'ai développé quelque peu (Et ajouté un style HTML / CSS dans le monde entier - mais l'image de lui-même est auto-entretenue.):
MARIOS WORLD
Code développé:
Code développé et (un peu) réarrangé:
la source
var
pour déclarer des variables; ils sont automatiquement déclarés lorsque vous les définissez, vous devriez donc pouvoir les supprimervar D,C,c,S,s,R,F,Z,
de votre code. (vous pouvez également le remplacer/.{2}/
par/../
.)var
mais l'ai laissé comme je devais courir quand je l'ai posté. Fait maintenant. Le RegExp était sympa, d'une manière ou d'une autre, n'a pas réussi à voir cela;)ev(a|i)l
routine). Si c'est "légal", alors OK.eval(unescape(escape('𨑬𩑲𭀨𘣆𘠩').replace(/uD./g,'')))
fonctionne comme prévu. Et oui, votre score est compté en caractères afin que vous puissiez totalement utiliser des astuces comme la compression Unicode et eval. Vous pourriez avoir un score proche de 1750 avec ça!Python
133113261314127212681217 octets(code:
219214202186182, données:362 + 750 = 1112363 + 723 = 1086346 + 689 = 1035)L'idée ici est que je génère d'abord une carte d'un 16e de la taille de chaque dimension, où chaque pixel est coloré par l'index de la carte de tuiles. Pour m'assurer que la même palette était utilisée, j'ai d'abord combiné la carte de tuiles donnée et la carte en une seule image. À partir de cela et de la carte de tuiles (les deux pngs minifiés), nous pouvons maintenant régénérer la carte d'origine. (Le code de ce processus peut être vu sous le code de soumission). Il convient de noter que j'ai enregistré la carte de tuiles sous forme de fichier "t" et la carte générée sous forme d'image "m"
EDIT: J'ai commencé à explorer comment l'ordre des tuiles a influencé la compression, et pour les besoins de l'exploration, j'ai généré 10000 permutations aléatoires et les ai compressées avec ce résultat: tout cela avec les tuiles sur une seule ligne, car cela réduisait le code assez bit. J'ai essayé des choses similaires avec différentes configurations (2 * 16, 4 * 8), mais aucune avec un meilleur résultat moyen.
En supposant que png se comprimerait mieux avec des régions similaires continues plus grandes, j'ai construit un outil qui me permettrait de déplacer les tuiles, et en utilisant ce que je percevais comme une image plus continue, j'ai obtenu l'image des tuiles à 723 à partir de 750b.
EDIT2: Après beaucoup (beaucoup) plus d'analyses sur le fonctionnement réel de png, et beaucoup d'expérimentations (toujours en cours), les images ont maintenant été encore plus compressées. Le lien ci-dessous a été mis à jour. J'écrirai plus sur cette analyse plus tard lorsqu'elle sera terminée.
Les nouvelles images utilisées sont ici: http://imgur.com/a/RgkXx
Voici les autres images générées au cours du processus: http://imgur.com/a/HXTGA , bien que certaines soient un peu dépassées en raison de la modification ci-dessus.
Le script que j'ai écrit pour réduire la carte est assez grossier, mais voici (peut aussi être obsolète en raison des changements ci-dessus):
la source
Perl 5 + PNG: 689 + 593 = 1282
Une tentative infructueuse de remplacer la carte de tuiles compressée PNG de la solution de Christian par du code Perl. Au final, c'est 65 octets de plus. Prend les mêmes tuiles PNG en entrée et génère un PNG en sortie.
Usage:
perl mario.pl <tiles.png >world.png
la source
JS:
40123921 caractèresJS est utilisé pour décompresser de nombreux caractères Unicode et écrire une balise img dont src est l'image donnée dans l'OP, enregistrée au format PNG, compressée, codée en base64 et découpée.
Démo: http://jsbin.com/fojidejoco/1/
PS: Je sais que c'est un peu de la triche (même si les règles le permettent), mais au moins, cela nous donne un objectif: le faire en moins de 4012 caractères.
Les outils utilisés:
la source