Ketika saya masih kecil, saya memainkan game Intellivision, Dungeons and Dragons: Treasure of Tarmin . Grafik 3-D menempatkan Anda pada sudut pandang orang pertama dengan realisme yang mengejutkan:
Tapi kemudian saya mendapat C-64. Dan saya dapat menggambar pada grid karakter 40x25 dengan mengitari layar, mengatur warna dengan tombol Ctrl dan angka, dan menempatkan simbol di mana pun saya inginkan (mengapa tidak bash
membiarkan saya melakukan itu?) . Set karakter memiliki komponen segitiga dan komponen blok padat. Jadi saya bisa memikirkan bagaimana seseorang dapat menghasilkan rendering perspektif seseorang dalam kotak melalui media itu.
Saya menemukan spek yang hampir berumur tiga dekade, di kertas notebook berbentuk spiral, tentang "Dungeon Construction Set" minggu ini:
( PEMBARUAN : Pembaca yang cermat akan melihat bahwa ini tidak cukup melekat pada bagian yang miring. Angka yang diperbaiki disediakan di bawah ini.)
Meskipun Harta Karun Tarmin dimainkan pada kotak, dinding hanya ada di tepi kotak kotak. Setelah mempelajari apa itu byte, saya menyadari bahwa jika saya membuat peta dari byte ... maka setiap kotak pada peta dapat memiliki empat status yang mungkin untuk masing-masing tepi:
- Tidak terhalang
- Dinding
- Pintu
- Sesuatu yang lain
Saya tidak pernah sempat menulisnya (sampai semalam). Saya pikir mungkin menyenangkan bagi orang lain untuk mencoba.
Jadi tugas Anda adalah mengimplementasikan penyaji maze berbasis karakter-mode yang mengimplementasikan spesifikasi (terkoreksi !!) saya ... tetapi menggunakan teknologi tahun 2013.
Memasukkan
Karena spek tidak menentukan rendering untuk pintu, kami hanya akan berasumsi bahwa satu-satunya pilihan adalah dinding dan bukan dinding. Untuk kesederhanaan, input Anda adalah peta yang terdiri dari garis-garis string yang terlihat seperti ini:
WN.. .N.. .N.. .N.. .N.E
W... .... .... ..S. ...E
W... .N.E W... .N.. ...E
W... .... .... .... ...E
W.S. ..S. ..S. ..S. ..SE
Itu akan menjadi peta 5x5. Sudut kiri atas (1,1) memiliki W
est dan N
dinding. Sudut kanan bawah (5,5) memiliki set dinding S
outh dan E
ast.
Ini jauh lebih tidak menyenangkan tanpa navigasi peta. Jadi minimal, tempatkan pemain Anda di (1,1) menghadap ke utara dan tawarkan kepada mereka:
[F]orward, [B]ackward, turn [L]eft, turn [R]ight or [Q]uit?
Pada setiap langkah, tampilkan tampilan 16x15 dari perspektif orang pertama, sebagaimana ditentukan oleh spesifikasi kertas notebook. Agar Anda tidak harus menghitung, ukuran dinding datar pada tiga jarak adalah:
14x13 (directly in front of you; e.g. wall is in same cell)
8x7 (one step away)
6x5 (two steps away)
Ukuran pembatas dinding miring adalah:
1x15 (your direct left or right; e.g. wall is in same cell)
3x13 (one step away)
1x7 (two steps away)
Klarifikasi
Sel yang berdekatan mungkin tidak setuju tentang dinding bersama. Jadi tepi selatan pada sebuah bujur sangkar mungkin adalah sebuah tembok, sedangkan tepi utara pada bujur sangkar di selatan itu tidak terhalang. Dalam desain aslinya saya menganggap ini sebagai fitur: itu memungkinkan ide-ide menarik seperti pintu satu arah ... atau dinding tak terlihat yang hanya muncul setelah Anda melewati mereka. Untuk penyederhanaan ini, ikuti aturan yang sama: untuk navigasi dan rendering, perhatikan hanya status tepi pada sel yang terdekat dengan Anda ke arah yang Anda hadapi .
Tampilannya jauh lebih baik dengan "shading". Jadi untuk blok penuh Anda, alternatifkan Unicode 2593 ▓ dan 2591 ░, atau gunakan
X
dan+
jika implementasi Anda adalah ASCII.Karakter segitiga Unicode (25E2 ◢, 25E3 ◣, 25E4 ◤, 25E ◥) agak timpang untuk menggambar ini. Selain tidak memiliki varian teduh, mereka sering hanya merentangkan lebar karakter dan tidak tinggi penuh ... bahkan dalam font lebar tetap. Anda dapat menggambar blok penuh atau memangkas karakter atau sesuatu yang Anda pilih di tempat yang saya inginkan diagonal. Solusi kreatif yang menarik yang menggabungkan warna dan menggunakan karakter-karakter ini daripada menghargai.
Anda dapat mengasumsikan dinding terluar diatur untuk mengikat area bermain, sehingga Anda tidak perlu khawatir membuat apa pun di luar labirin. Dinding yang lebih jauh dari Anda daripada spec diabaikan dan hanya meninggalkan ruang kosong.
Bayangan dinding yang Anda lihat langsung di depan Anda jika menghadap Utara di (1,1) harus DARK. Bernaung alternatif di dinding yang berdekatan di peta, sehingga jika semua dinding ada maka dinding yang terang tidak akan pernah berbatasan dengan dinding yang gelap.
Implementasi C-64 yang benar-benar melakukan apa yang awalnya saya maksudkan ... dengan karakter diagonal dan semuanya ... akan mengalahkan kriteria entri lainnya. :-)
Contohnya
Untuk peta contoh yang diberikan di atas ...
Di (1,3) menghadap ke selatan:
/
/+
/X+
/XX+
/XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
\XXX+
\XX+
\X+
\+
\
Di (3,2) menghadap ke selatan:
/* blank line */
X /
X /+
X /++
X +++
X +++
X +++
X +++
X +++
X +++
X +++
X \++
X \+
X \
/* blank line */
Di (3,2) menghadap ke timur:
/* blank line */
/
/X
/XX
XXX
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
XXX
\XX
\X
\
/* blank line */
Di (2,3) menghadap ke utara:
/
++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
\
sumber
X
s dalam pandangan Anda3, 2
menghadap ke selatan?Jawaban:
Commodore 64 Basic
Sobat, itu menyenangkan. Dan sulit. C64 Basic hampir tidak dapat dibatalkan, Anda bahkan tidak dapat menggunakan
print
debugging karena layar sudah diambil untuk rendering penjara bawah tanah. Anda tahu Anda bersenang-senang saat menulis kode suka55250 goto 55110
. Dijkstra akan membunuhku.Program ini menggunakan dua warna, dan karakter diagonal.
Tak perlu dikatakan saya tidak golf itu. Ia mengatakan tantangan kode sekarang. Ini 7183 byte jika Anda tertarik.
Ini lambat - pada kecepatan default, dibutuhkan beberapa detik untuk membuat adegan. Ukuran peta maksimum adalah 10 kali 10 tetapi dapat diubah dengan mengedit baris 120.
Saya telah mengembangkan dan menguji ini menggunakan emulator VICE . Kode di bawah ini ditampilkan dalam ASCII, sehingga itu berarti PETSCII bergeser . Namun, saat memasukkan peta, Anda harus menggunakan PETSCII tanpa pergeseran .
Tangkapan layar:
Kode:
Gambar kaset: unduh di sini .
Contohnya:
sumber
Aku harus melakukannya sekarang.
Bash, 12743 karakter
Harap diingat bahwa ini adalah hal pertama yang saya lakukan dengan
bash
lebih dari sekadar menyatukan beberapa perintah. Mungkin akan dapat direduksi dengan cukup banyak jika saya tidak melakukan hardcode pada semua dinding, tetapi sepertinya lebih mudah. Tidak ada konsistensi sama sekali. Format byte untuk setiap kotak dipilih dengan cara yang mengerikan. Tapi itu berhasil.Saya bahkan menambahkan dukungan untuk pergerakan melalui tombol panah :)
Ini adalah beberapa tangkapan layar untuk input sampel (Perhatikan bahwa peta saya mulai dari (0 | 0)):
Terlepas dari yang keempat, mereka semua terlihat seperti sampel juga (lihat komentar saya di OP).Cuplikan layar ini diambil pada urxvt v9.15 dengan dukungan 256 warna, mungkin akan terlihat sangat jelek di terminal 88 warna, dan terminal tanpa dukungan unicode tidak berfungsi sama sekali. Font yang saya gunakan adalah Source Code Pro oleh Adobe.
sumber
Ini versi saya, dengan Python 3. Ini kira-kira seperti karakter 3k dan bisa menjadi sedikit lebih kecil dengan sedikit usaha (ada banyak ruang putih yang bisa dihapus, untuk memulainya).
Saat ini digunakan
+X/\
sebagai karakter gambarnya, tetapi sudah diatur untuk menggambar dengan karakter Unicode jika Anda memiliki font lebar tetap yang akan membuatnya dengan benar. Ini mendukung penggunaan ubin terpisah untuk bagian miring dari dinding yang berbeda warna, meskipun saya tidak menggunakan fitur itu. Ini juga memungkinkan Anda memberikan ubin langit-langit, lantai dan "jauh", dan Anda dapat menggunakan yang berbeda ketika pemain menghadap ke timur atau barat vs utara atau selatan. Sayangnya ini tidak pernah terlihat sangat bagus, jadi mungkin semua ini harus kosong (atau sesuatu yang solid, seperti█
).Sayangnya, pada sistem Windows 7 saya, saya memiliki waktu yang mengerikan mencoba menemukan font monospace dengan set lengkap karakter blok (misalnya
▜
dan▟
). Sebagian besar yang saya temukan tidak dapat dibuat tersedia dicmd
konsol untuk beberapa alasan (mungkin karena mereka tidak sempurna monospace?). Jika menurut Anda konsol Anda lebih fungsional, coba gunakan rangkaian karakter alternatif yang saya komentari di dekat bagian atas file, yang tidak terlihat terlalu buruk bahkan hanya dengan dua warna. Itu telah mengisi langit-langit dan lantai dan sebagian besar dinding transparan.Kode:
Set karakter ditentukan di dekat bagian atas file. Urutan karakter adalah:
/
dengan dinding di bawahnya)Ada 15 dinding yang mungkin perlu dibuat oleh permainan, dalam pola seperti ini (dengan
V
menunjukkan posisi pemain dan sudut pandang):Ubin yang digunakan oleh 15 dinding didefinisikan dalam
shapes
daftar. Ini daftar 2-tupel. Nilai pertama tupel menunjukkan "paritas" dinding, dengan0
menunjukkan bahwa itu harus digambar dengan karakter yang sama dengan dinding langsung di depan karakter dan1
menunjukkan bahwa itu harus menjadi pola alternatif (misalnya+
vsX
). Nilai kedua adalah daftarx,y,t
tupel yang menunjukkan koordinat layar dan indeks ubin satu piksel (dinding yang diberikan dengan paritas ganjil akan1
ditambahkan ke masing-masing indeks ini). Bentuknya disusun berdasarkan jarak, sehingga tiga yang pertama mewakili dinding tegak lurus dua ubin di depan karakter, diikuti oleh dua dinding paralel dua ubin di depan, dan seterusnya.Fungsinya adalah:
rr
: "render" layar (dengan mencetak ubin di buffer layar).dw
: "menggambar dinding" ke penyangga layar yang disediakan. Ini menggunakan algoritma pelukis, sehingga dinding yang paling jauh digambar terlebih dahulu dan mungkin ditutup oleh yang lebih dekat.ga
: "get area" mengembalikan daftar nilai boolean yang menunjukkan dinding mana yang buram untuk posisi dan posisi peta yang diberikan.rd
: "read", generator yang membaca peta, menghasilkan garis. Ini hanya diperlukan karena konsol IDLE melakukan hal-hal aneh ketika Anda menempelkan input multi-baris daripada memasukkan satu baris sekaligus.rm
: "baca peta", parsing peta ke daftar boolean bersarang, diindeks olehm[y][x][d]
(dengand=0
menjadi Timur dand=1
Selatan). Ini juga menambahkan dua baris dan dua kolom kotak padding, untuk menghindari kesalahan indeks pada kode lainnya.cl
: "hapus" output (dengan menulis cukup baris baru untuk menggulir tampilan lama dari atas sebagian besar konsol).gl
: "game loop", tempat input dikumpulkan dan hal-hal di atas dipanggil.Beberapa "tangkapan layar":
Posisi awal:
Melihat sepanjang dinding utara:
Beberapa gambar yang cocok dengan contoh Anda (perhatikan, baris pertama kosong sedang dipotong oleh Stack Overflow, mereka ada di output program):
Dan:
Berikut adalah salah satu pandangan orang asing di peta yang disediakan, karena dinding yang sejajar dengan pandangan kami berwarna sama dengan dinding tegak lurus yang menonjol di belakangnya:
Beginilah area bidikan terakhir akan terlihat dari atas:
sumber