Tantangan terakhir ( Pixel-art, episode 1: tampilan Super Mario ) hanyalah pelatihan ... (dan Anda menyelesaikannya dengan cara yang luar biasa, terima kasih!)
Kali ini, Anda harus bekerja sedikit lagi. Anda harus menampilkan semua peta Overworld bros Super Mario pertama di NES, tanpa musuh, dan tanpa Mario.
Program atau fungsi Anda harus menampilkan semua piksel gambar berikut ATAU menghasilkan file gambar yang mirip dengannya (BMP, PNG, atau GIF).
Program Anda tidak boleh mengakses internet dengan cara apa pun.
Outputnya bisa diperbesar jika Anda mau, dan pikselnya bisa elemen ASCII atau HTML jika Anda mau, asalkan warnanya tepat.
Inilah model yang harus Anda ikuti:
Seluruh gambar: http://i.stack.imgur.com/2kfVc.png
The tileset (jika Anda membutuhkannya): http://img.ctrlv.in/img/14/10/19/5443f44c7eb78.png
Anda dapat menghasilkan tileset, subset atau superset dari yang ini.
Anda dapat menggunakan tileset Anda sebagai file gambar terpisah atau memasukkannya ke dalam kode Anda (misalnya, dalam base64). Jika terpisah, tambahkan ukurannya dalam byte ke skor Anda.Peta dengan koordinat: http://goo.gl/c8xJIx atau http://img.ctrlv.in/img/14/10/19/544373adc9f64.png
Warna:
Biru langit: # 5C94FC Hitam: # 000000 Merah Muda: # FCBCB0 (untuk blok dan kastil) Brown: # C84C0C (untuk balok dan kastil) Oranye: # FC9838 (untuk blok "?") Hijau muda: # 80D010 (untuk semak-semak, gunung, tiang bendera, lungsin) Hijau tua: # 00A800 (untuk semak-semak, gunung, tiang bendera, warp) Putih: #FCFCFC (awan) Biru muda: # 3CBCFC (awan)
Jawaban terpendek menang.
EDIT: Akan ada dua papan skor, satu di mana skor dihitung dalam byte dan satu di mana mereka dihitung dalam karakter.
Semoga berhasil!
PS: Berikut adalah beberapa catatan yang dapat membantu Anda mengoptimalkan program Anda:
- Awan, semak-semak dan pegunungan memiliki pola berulang (setiap 48 kolom)
- Blok terbang hanya ada pada jalur 4 dan 8
- Setiap ubin atau sprite peta menggunakan paling banyak 4 warna (termasuk biru atau transparan, tergantung pada bagaimana Anda melihatnya)
- Semak-semak hanyalah "puncak awan" dengan palet warna yang berbeda
- Semak / awan tunggal, ganda, dan tiga dapat dengan mudah dibentuk menggunakan set mini yang sama, yaitu potongan 16x16px. Ini juga berlaku untuk gunung tunggal dan rangkap tiga
Jawaban:
Kode Mesin x86,
1729161914681382 BytesCara kerjanya: Ubin dihasilkan oleh kombinasi kompresi RLE, gambar 2bit, dan kode prosedural. Setelah ubin dihasilkan dalam memori, program kemudian membuat matriks indeks ubin. Ini pertama kali dimuat dengan latar belakang berulang. Setelah itu, pipa, balok apung, piramida, dan tiang bendera digambar secara prosedural. Pipa-pipa, bukit-bukit, semak-semak, dan piramida dapat meluas di bawah tanah, tetapi ditutup ketika ubin batu ditulis berikutnya. Akhirnya, nilai ubin kastil hanya disalin ke lokasi yang benar. Untuk menghasilkan file gambar, header dan palet BMP disimpan dalam file sebagai data, dan ditulis terlebih dahulu. Program kemudian berjalan melalui matriks, menulis baris yang sesuai dari ubin yang sesuai untuk setiap posisi.
Penggunaan: Jalankan mario.com, ini akan menghasilkan "m.bmp", file gambar BMP standar. File ini dibuat sebagai file tersembunyi, karena itu akhirnya menjadi lebih sedikit byte.
Unduh file ZIP yang berisi kode sumber dan biner, plus keluaran.
Kode perakitan untuk menghasilkan file yang dapat dieksekusi:
sumber
Javascript diperkecil (*):
1285 1258 1253 1205 11861171 karakter(*) Diminimalkan menggunakan Penutupan, RegPack dan ObfuscaTweet, seperti yang disarankan oleh xem
Versi Unicode berukuran 4.549 byte, tanpa ObfuscaTweet (hanya Penutupan dan Regpack), ukurannya 2.251 byte.
Sejarah:
1285 -> 1258: variabel
A
untuk 48 (thx @hsl), menggabungkan beberapafor
loop, digabungmt()
danmu()
, menggunakan indeks ubin, bukan string ubin, dioptimalkan png dengan PNGOUT1258 -> 1253: menggabungkan beberapa
for
loop lagi ; diganti namanyamt()
menjadir()
; menghapus kawat gigi yang tidak perlu; variabelB
untuk 16; mendefinisikan 16 sprite CSS yang tidak digunakan (menggantikan 32 denganA
); menunjukkan 1 baris yang tidak digunakan (menggantikan 14 denganB
); fungsi yang dihapuse()
; dipersingkatt()
,g()
,c()
; menggunakanfor(i=0;i<n;)f(i++)
alih-alihfor(i=0;i<n;i++)f(i)
jika memungkinkan1253 -> 1205: memindahkan gaya tubuh ke bagian CSS bukannya
<body style=...>
; mengganti beberapafor
loop denganf
panggilan; fungsi dioptimalkanr
,q
;</head><body>
tampaknya tidak perlu<html><head>
juga; fungsit(i)
untuk pemetaan CSS dihapus; Nama CSSb0
..b31
bukana
..z
,aa
..ff
1205 -> 1186: fungsi
n
diubah namanya menjadiN
; fungsi barun
yang beroperasi pada array dengan pengkodean delta1186 -> 1171: bukit-bukit dan lungsin dapat ditarik "besar" kapan saja, bagian-bagian yang lebih rendah dapat ditarik oleh balok-balok batu; gunakan
d
untuk awan dan semak-semak; menghapus beberapa titik koma yang tidak perluIni adalah upaya prosedural. Ada pola di mana-mana, salah satu angka ajaib adalah 48 (celah ubin antara awan, semak-semak dan gunung). Ubin dikodekan sebagai string url data Base64 dan digunakan sebagai stylesheet CSS. Dalam Javascript, array 212x14
m
diisi dengan indeks ubin. Lihat versi tanpa komentar yang dikomentari untuk detail lebih lanjut.Berfungsi di Chrome 38 (Ctrl + T untuk tab baru, Ctrl + Shift + J untuk konsol javascript, tempel kode di sana) dan Firefox 33 (jika dibungkus dengan tag javascript HTML). Ada versi JS bin juga.
Masih ada beberapa ruang untuk optimasi, saya akan memposting pembaruan dan alangkah baiknya jika beberapa orang JS / CSS / HTML dapat menyarankan optimasi / koreksi.
Diperkecil:
Tidak ditagih dan dikomentari:
sumber
function l(i,j,s){for(k=0;k<j;k++)n(i+k*W,s);}
dapat dipersingkat dengan mengekstraksi k ++ ke fungsi, saya pikir? Begitu juga dengan baris berikutnya dengan j.Python3
1638157616161513 byte581 kode + 932 data
↑ Bagian atas ini adalah level asli. Di tengah adalah PPM yang dihasilkan oleh skrip ini. Di bagian bawah adalah diff, dan ini menunjukkan bahwa palet dan peta tidak sepenuhnya setuju! Saya menempatkan ini ke kesalahan data dan bukan skrip saya;)
(byte dihitung tanpa komentar, indentasi baris-terbuka dan level kedua
\t
)Data (base64-disandikan untuk ditempelkan; decode dan simpan sebagai file bernama "i"):
File data adalah format khusus yang saya buat untuk masalah ini dan disimpan sebagai LZMA.
Pertama-tama 32 ubin diserialisasi. Ada 9 warna dalam palet, dan ini membutuhkan 8219 byte tanpa kompresi. (Saya menemukan bahwa mencoba untuk mengompres ubin pada 4-bit-per-pixel tidak membantu kompresi sama sekali. Saya tidak mencoba dan memaksa dengan paksa pemesanan ubin yang terbaik, dan saya mungkin kehilangan beberapa poin di sini.)
Ada 212x14 = 2968 blok yang menyusun peta.
Kemudian instruksi untuk membuat kembali peta sekarang disandikan.
Pertama adalah bagian dari perintah "put" yang menempatkan beberapa urutan ubin dari palet ubin pada peta pada x, y. Karena ada 32 ubin, saya menentukan menjalankan ubin yang sama menggunakan nomor lebih besar dari 32 daripada indeks ubin.
Kemudian muncul bagian dari perintah "salin" yang menyalin beberapa persegi panjang dari peta saat ini ke tempat lain. Ada bit-mask khusus yang menandai jika salinannya harus dicerminkan.
Contoh perintah penyangga pendek:
(Saya katakan singkat , tapi itu sebenarnya hampir setengah dari total buffer perintah yang diperlukan untuk membuat seluruh peta; sebagian besar byte dalam data adalah 32 sumber petak sendiri)
Kemudian muncul bagian kedua dari perintah "put" dan akhirnya bagian lain dari perintah "copy".
Karena ini dapat saling menimpa, saya dapat membuat bagian salinan yang kemudian saya hapus atau ubah.
Saya pasti dapat mencukur beberapa byte lagi dengan - misalnya - mengubah menempatkan menjadi salinan kecil dan dengan melakukan
eval
trik pada kode sumber gzip, atau bermain dengan PNG (yang DEFLATE dengan filter khusus gambar) juga. Tapi aku suka hal-hal seperti apa adanya.sumber
3,11
sepertinya hilang dari palet. Tampaknya ada beberapa kebisingan di peta sekitar20,12
dan garis besar umum pohon dan awan mungkin kesalahan perataan di palet? Hanya ada 9 warna, jadi tidak bisa berupa artefak campuran.Javascript,
106910721024 karakter (1957 byte)RegPacked dan Obfuscatweeted
Kode tidak diobotasi
Saya menyembunyikan kode ini karena ada kode ungolfed di bawah ini.
Tampilkan cuplikan kode
Kode tidak dikunci
Saya pertama kali membuat ubin menjadi sprite dengan URI data minna @ schnaader.
0 ~ v
(yaitu 0 ~ 31 dalam basis 31) mewakili setiap ubin.Dan saya mengubah peta menjadi ubin dengan tangan. Data ini memiliki 212 karakter per baris.
Kemudian saya mengganti karakter berulang (seperti
7
(langit) dan1
(tanah)) denganrepeat()
.Saya menemukan
7
s dan beberapa blok, dan7
pola lain diulang. Jadi saya membuat fungsi lain untuk membuatnya kompak. Anda dapat melihatnya di kode sumber yang tidak diobotasi.Akhirnya saya RegPacked, dan Obfuscatweet kode golf saya 2.341 byte.
Itu tantangan yang sangat lucu. Terima kasih! Dan terima kasih kepada @xem untuk lebih banyak trik.
sumber
JavaScript:
3620 (aduh)34293411Pembaruan
Pembaruan # 1: Menghapus
var
definisi dan meletakkan deklarasi variabel di dalam tanda kurung penggunaan pertama. DihapusgetElementById()
karena juga tersedia saat dimuat sebagai mudah dihapus oleh ID. MenggunakancloneNode()
bukancreateElement('CANVAS')
. Berganti nama utama darixMx
menjadiM
. Menghapus fitur penskalaan :(, (masih tersedia dalam contoh. )Menambahkan beberapa komentar ke kode yang diperluas. (Kode itu tidak diperbarui dengan penghapusan. Baris di bawah ini, ("Kode mini") , adalah.)
Pembaruan # 2: Menghapus fungsi utama
M()
secara keseluruhan dan membiarkan kode berjalan di root . Ini akan membutuhkan kode ditempatkan di dalam pembungkus beban atau di akhir dokumen.Pembaruan # 3: Statistik ditambahkan.
Kode mini:
Blah blah:
- Demo di akhir posting.
Menggunakan kanvas sebagai dasar untuk upaya mengatasi ini. Berakhir dengan sekitar 6000 karakter, tetapi setelah beberapa mengutak-atik (dan kompresi kustom - dengan mengutak-atik dan tweak juga) saya sekarang di nomor yang ditentukan. Masih tinggi, tapi sekali lagi kualitasnya bagus ;-).
Ini juga termasuk opsi skala, argumen pertama ke fungsi
xMx()
, alias "utama" . 1 = ukuran normal (seperti pada ubin 16 bit). Tidak ada banyak ruang untuk tweaker, jadi jika seseorang menggunakan pecahan, beberapa ubin tidak cocok bersama. Pada bilangan bulat itu harus OK. [1]Tapi: peringatan, naik, cepat makan sumber daya dan membuat kanvas besar. (Semuanya dicat dalam sekali jalan.) Ketika lebar aslinya adalah 3392 piksel dengan cepat menjadi besar. [1]
[1] Sejak pembaruan # 1 ini telah dihapus. Itu hadir dalam demo.
Statistik:
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, ";", antara kode utama / data.
Data yang dikompresi adalah satu array, Å, dan satu "objek" , Ø. Di mana Å memegang penempatan ubin dan Ø memegang data untuk mengecat ubin. Ø seharusnya array juga - tetapi ketika kode saya mulai dengan sesuatu seperti ini:
Itu berakhir seperti apa adanya. Saya mungkin akan melihat apakah saya tidak bisa memperbaikinya. Idealnya saya akan membuatnya dapat diuraikan dengan JSON bukan eval (), tetapi itu tidak akan menjadi poin dalam kontes seperti ini. Seperti sekarang, JSON tidak dapat diuraikan karena ada kutipan yang hilang di sekitar bagian id.
Demo
Berikut adalah biola di mana orang dapat melihat kode dalam aksi. Kode dalam biola yang saya kembangkan agak (dan menambahkan beberapa style HTML / CSS di seluruh dunia - tetapi gambar itu sendiri berkelanjutan.):
MARIOS DUNIA
Kode yang diperluas:
Diperluas dan (sedikit) disusun ulang kode:
sumber
var
untuk mendeklarasikan variabel; mereka secara otomatis dideklarasikan ketika Anda mendefinisikannya, sehingga Anda harus dapat menghapusvar D,C,c,S,s,R,F,Z,
dari kode Anda. (Anda juga dapat menggantinya/.{2}/
dengan/../
.)var
tetapi meninggalkannya karena saya harus menjalankan ketika saya mempostingnya. Sekarang selesai. RegExp itu bagus, entah bagaimana tidak berhasil melihatnya;)ev(a|i)l
rutin). Jika "legal" maka OK.eval(unescape(escape('𨑬𩑲𭀨𘣆𘠩').replace(/uD./g,'')))
berfungsi seperti yang dimaksudkan. Dan ya, skor Anda dihitung dalam karakter sehingga Anda benar-benar dapat menggunakan trik seperti kompresi Unicode dan eval. Anda bisa mendapatkan skor mendekati 1750 dengan itu!Python
133113261314127212681217 byte(kode:
219214202186182, data:362 + 750 = 1112363 + 723 = 1086346 + 689 = 1035)Idenya di sini adalah bahwa saya pertama kali menghasilkan peta ukuran ke 16 di setiap dimensi, di mana setiap piksel diwarnai oleh indeks di peta ubin. Untuk memastikan bahwa palet yang sama digunakan, saya pertama kali menggabungkan peta petak yang diberikan dan peta menjadi satu gambar. Dari ini dan peta petak (keduanya png yang diperkecil) sekarang kita dapat membuat kembali peta asli. (Kode untuk proses ini dapat dilihat di bawah kode pengiriman). Perlu dicatat bahwa saya menyimpan peta ubin sebagai file "t" dan peta yang dihasilkan sebagai gambar "m"
EDIT: Saya mulai mengeksplorasi bagaimana urutan ubin mempengaruhi kompresi, dan demi eksplorasi saya menghasilkan 10.000 permutasi acak dan mengompresnya dengan hasil ini: Ini semua dengan ubin dalam satu baris, karena itu mengurangi kode cukup banyak sedikit. Saya mencoba hal serupa dengan konfigurasi yang berbeda (2 * 16, 4 * 8), tetapi tidak ada yang memiliki hasil rata-rata yang lebih baik.
Dengan asumsi bahwa png akan mengkompres lebih baik dengan daerah serupa yang terus menerus lebih besar, saya membangun sebuah alat yang akan memungkinkan saya memindahkan ubin, dan menggunakan apa yang saya anggap sebagai gambar yang lebih berkelanjutan, saya mendapatkan gambar ubin ke 723 dari 750b.
EDIT2: Setelah banyak analisis lebih lanjut tentang bagaimana png benar-benar bekerja, dan banyak bereksperimen (masih berlangsung), gambar sekarang telah dikompresi lebih jauh. Tautan di bawah ini diperbarui. Saya akan menulis lebih banyak tentang analisis ini nanti ketika sudah selesai.
Gambar baru yang digunakan ada di sini: http://imgur.com/a/RgkXx
Berikut adalah gambar-gambar lain yang dihasilkan dalam proses: http://imgur.com/a/HXTGA , meskipun beberapa agak ketinggalan zaman karena edit di atas.
Skrip yang saya tulis untuk mengurangi peta cukup kasar, tetapi begini (mungkin juga sudah usang karena perubahan di atas):
sumber
Perl 5 + PNG: 689 + 593 = 1282
Upaya gagal untuk mengganti peta ubin terkompresi PNG dari solusi Christian dengan kode Perl. Pada akhirnya lebih panjang 65 byte. Mengambil petak PNG yang sama pada input dan menghasilkan PNG pada output.
Pemakaian:
perl mario.pl <tiles.png >world.png
sumber
JS:
40123921 karakterJS digunakan untuk membongkar banyak karakter Unicode dan menulis tag img yang src adalah gambar yang diberikan dalam OP, disimpan sebagai PNG, dikompresi, disandikan dalam base64 dan dipangkas.
Demo: http://jsbin.com/fojidejoco/1/
PS: Saya tahu itu sedikit curang (walaupun aturan mengizinkannya), tapi paling tidak, itu memberi kita tujuan: lakukan dalam kurang dari 4012 karakter.
Alat yang digunakan:
sumber