Ketika saya masih kecil, anak-anak akan berkeliaran di toko-toko komputer dan bermain Hunt the Wumpus sampai staf mengusir kami. Itu adalah permainan sederhana, dapat diprogram di komputer rumah pada pertengahan tahun 1970-an, mesin sangat sederhana sehingga alih-alih mikroprosesor ukuran anak ayam, saya pikir beberapa dari mereka mungkin memiliki anak ayam nyata di sana.
Mari kita membangkitkan jaman dulu dengan mereproduksi game di perangkat keras modern.
Pemain mulai di ruang acak di peta icosahedral (dengan demikian total ada 20 kamar, saling terhubung seperti wajah icosahedron, dan setiap kamar memiliki tiga pintu keluar yang persis).
Wumpus dimulai di ruang berbeda yang dipilih secara acak. Wumpus bau, dan baunya dapat dideteksi di salah satu dari tiga kamar yang berdekatan dengan lokasinya, meskipun arah bau tidak mungkin bagi pemain untuk menentukan. Gim ini hanya melaporkan "Anda mencium wumpus."
Pemain membawa busur dan panah yang tak terbatas, yang dapat dia tembak kapan saja ke ruangan di depannya. Jika wumpus ada di ruangan itu, ia mati dan pemain menang. Jika wumpus tidak ada di ruangan itu, ia terkejut dan bergerak secara acak ke salah satu dari tiga kamar yang terhubung ke lokasi saat ini.
Satu, kamar yang dipilih secara acak (dijamin bukan ruangan tempat pemain memulai) berisi jurang tanpa dasar. Jika pemain berada di ruangan yang bersebelahan dengan pit, ia merasakan angin sepoi-sepoi, tetapi tidak tahu dari mana pintu angin itu berasal. Jika dia masuk ke ruangan dengan lubang, dia mati dan wumpus menang. Wumpus tidak terpengaruh oleh lubang.
Jika pemain masuk ke kamar wumpus, atau jika wumpus masuk ke kamar pemain, wumpus menang.
Pemain menentukan arah yang dihadapinya dengan angka (1 = kanan, 2 = kiri, 3 = belakang), dan kemudian aksi (4 = menembakkan panah, 5 = berjalan ke arah yang ditentukan).
Demi mencetak gol, setiap senar permainan ("Anda merasakan angin sepoi-sepoi," "Anda mencium wumpus," "Panah Anda tidak mengenai apa pun", dll.) Dapat dianggap satu byte. Tidak menyalahgunakan ini untuk menyembunyikan kode game dalam teks; ini hanya untuk berinteraksi dengan pemain.
Kurangi 10% dari jumlah byte Anda untuk mengimplementasikan megabats, yang dimulai di ruang acak yang berbeda dari pemain (meskipun mereka dapat berbagi kamar dengan wumpus dan / atau lubang). Jika pemain masuk ke ruangan dengan kelelawar, kelelawar akan membawa pemain ke ruangan lain yang dipilih secara acak (dijamin tidak akan menjadi ruangan dengan lubang atau wumpus di dalamnya), sebelum terbang ke lokasi acak baru mereka sendiri. Di tiga kamar yang bersebelahan dengan kelelawar, mereka dapat terdengar mencicit, tetapi pemain tidak diberi informasi tentang dari kamar mana suara itu berasal.
Kurangi 35% dari jumlah byte Anda untuk mengimplementasikan antarmuka grafis yang menunjukkan peta icosahedral dan semacam indikasi informasi yang sejauh ini dimiliki pemain tentang lokasi lubang, wumpus, dan kelelawar (jika ada), relatif terhadap pemain. Jelas, jika wumpus bergerak atau pemain digerakkan oleh kelelawar, peta harus diatur ulang.
Hitungan byte terendah, jika disesuaikan, menang.
Kode sumber BASIC untuk versi gim (tidak harus sesuai dengan aturan di atas dan, dalam hal apa pun, sama sekali tidak diklik) dapat ditemukan di situs web ini dan mungkin yang lain.
sumber
Jawaban:
GolfScript, 163
Skor diperoleh dengan mengambil hitungan byte (290), menambahkan jumlah string yang digunakan untuk interaksi dengan pengguna (6) dan mengurangi panjang gabungan dari string tersebut (133). Umpan baris adalah bagian dari string dan berkontribusi pada jumlah byte.
Tonggak sejarah
Porting jawaban professorfish ini dari Bash ke GolfScript. Nilai: 269
Bertindak atas saran Peter Taylor dalam komentar. Nilai: 250
Peter Taylor refactored seluruh kode saya dan membantu saya untuk mengompres tabel pencarian. Nilai: 202
Mengganti tabel pencarian kamar yang berdekatan dengan pendekatan matematika. Nilai: 182
Input, output, dan fungsi yang mendukung kembali pendekatan matematika. Nilai: 163
Ucapan terima kasih yang besar ditujukan kepada Peter Taylor untuk semua bantuannya.
Bagaimana itu bekerja
Ke-20 kamar diwakili sebagai simpul dodecahedron, yang telah diberi nomor dari 0 hingga 19 dengan cara sebagai berikut:
Untuk menemukan kamar yang berdekatan dengan kamar N dan memesannya dengan cara searah jarum jam, kita harus mempertimbangkan empat kasus:
Jika N ≡ 0 mod 4 (verteks biru), ruang yang berdekatan adalah 19 - N , N + 2 mod 20 dan N - 2 mod 20 .
Jika N ≡ 1 mod 4 (titik hijau), ruang yang berdekatan adalah 19 - N , N - 4 mod 20 dan N + 4 mod 20 .
Jika N ≡ 2 mod 4 (titik kuning), ruang yang berdekatan adalah 19 - N , N - 2 mod 20 dan N + 2 mod 20 .
Jika N ≡ 3 mod 4 (red vertex), ruang yang berdekatan adalah, 19 - N , N + 4 mod 20 dan N - 4 mod 20 .
sumber
Q
dengan19rand 97+
; 2 di@
dengan97%3*&>
..., lebih lanjut 1 oleh inliningQ
sebagai{19rand 97+}2*:,\:H
, beberapa dengan mengganti|
dengan*
, yang sering cara terbaik untuk melakukanif
.B
tidak ada gunanya, dan saya pikir beberapa variabel lagi bisa dihilangkan dengan menggunakan stack.256base 20base
(dan mungkin juga menghilangkan beberapa +/- 97). Satu-satunya downside adalah bahwa itu akan memerlukan karakter yang tidak dapat dicetak.You were killed by the wumpus
tanpa menyebutkan panah yang hilang. Itu sebabnya saya menambahkan dalam versi yang tidak cantik.2*2+
=>)2*
REV0 C ++ (Visual Studio pada Windows) 405Di bawah ini adalah permainan, menunjukkan bahwa (asalkan Anda tidak memulai tepat di sebelah bahaya) dengan permainan yang benar Anda selalu bisa menang. Pemain merasa mudah, berbalik dan melakukan putaran berlawanan arah jarum jam yang lengkap. Saat ia membutuhkan tepat 5 gerakan untuk merasakan angin sepoi-sepoi lagi, ia tahu lubang di sebelah kanannya, dan berada sejauh mungkin. Demikian pula, ketika dia mencium wumpus, tidak tahu apakah itu benar atau kiri, dia berbalik dan melakukan putaran searah jarum jam. Dibutuhkan 5 langkah untuk mencium wumpus lagi, jadi dia tahu itu ke kiri dan menembak dengan pasti.
Jika dia memutar ke arah lain, dia akan menemukan wumpus lebih cepat dan tahu itu ke arah yang sama dengan yang dia putar.
REV1 C (GCC di Cygwin), 431-35% bonus = 280,15Baris baru ditambahkan untuk kejelasan. Perubahan dari Rev 0 adalah sebagai berikut:
Terima kasih banyak kepada @Dennis karena merekomendasikan kompiler GCC pada emulator Cygwin Linux untuk Windows. Kompiler ini tidak memerlukan
include
s dalam program rev 0, dan memungkinkan defaultint
tipe untuk variabel danmain.
Ini adalah tip golf yang mengubah hidup!Selain itu berjalan di Linux berarti itu
\f
menyebabkan kursor bergerak ke bawah tanpa melakukan carriage return (tidak seperti di Windows di mana ia hanya menghasilkan simbol yang dapat dicetak.) Ini telah memungkinkan pemendekan pernyataan printf yang mencetak papan.Beberapa tips tambahan dari Dennis di komentar, dan salah satu dari saya: perubahan kondisi saat memeriksa apakah panah mengenai wumpus:
if(q==w)
>if(q-w)
(..else .. dibalik)Penambahan tampilan grafis menunjukkan informasi yang pemain ketahui tentang di mana wumpus dilebur / angin sepoi-sepoi terasa untuk mengklaim bonus 35%. (Saya menghapus versi debug yang lama ini yang menunjukkan posisi persis wumpus dan lubang. Hal ini dapat dilihat pada riwayat edit.)
REV2 C (GCC di Cygwin), bonus 389-35% = 252,85
Sekali lagi terima kasih kepada Dennis untuk refactoring kode saya:
Konstanta Char
m[]
diganti dengan literal (saya tidak tahu Anda bisa mengindeks literal.)Pembibitan angka acak dengan variabel tumpukan (ketergantungan sistem, beberapa sistem mengacak alokasi memori sebagai ukuran keamanan.)
Makro dengan
puts
diganti dengan makro denganprintf
dan kode tambahan yang harus dijalankan ketika pesan yang ditampilkan ditempatkan di dalamprintf
argumen (keuntungan diambil dari wajah bahwa printf tidak mencetak beberapa argumen terakhir jika tidak ada cukup penentu format dalam string format.)if
digantikan oleh||
Perhitungan posisi baru pemain / wumpus ditempatkan di dalam makro baru.
Menang / kalah pesan yang ditempatkan di luar
while
lingkaran.if
diganti oleh operator kondisional.Gunakan operator bersyarat untuk menembakkan panah. Jika pemain absen, ini membutuhkan baik mencetak pesan dan menyesuaikan posisi wumpus. Dennis menawarkan beberapa cara untuk menggabungkan
printf
dan menghitung posisi wumpus menjadi satu ekspresi, tetapi saya telah menggunakan salah satu dari cara saya sendiri.printf
mengembalikan jumlah karakter yang dicetak, yangYour arrow didn't hit anything\n
adalah 31 (11111 biner.) Jadi31&Q(w)==Q(w)
,.Kontribusi saya yang lain untuk pengeditan ini adalah menghilangkan beberapa tanda kurung yang tidak perlu.
Keluaran
Di sini pemain telah menemukan di mana Wumpus berada, tetapi memilih untuk melakukan penjelajahan menyeluruh untuk mencari tahu persis di mana lubang itu juga. Tidak seperti versi debug lama saya yang menunjukkan di mana wumpus dan lubang berada di sepanjang permainan, ini hanya menunjukkan kamar di mana pemain telah mengunjungi dan merasakan angin sepoi-sepoi (1) mencium wumpus (2) atau keduanya (3). (Jika pemain menembak panah dan meleset, variabel yang
a
berisi info posisi wumpus diatur ulang.)REPRESENTASI ICOSAHEDRON
Catatan: bagian ini didasarkan pada rev 1
Fitur bintang saya! Tidak ada grafik dalam kode saya. Untuk menjelaskan cara kerjanya, lihat peta dunia di bawah ini. Setiap titik pada icosahedron dapat diwakili oleh garis lintang 0-3 dan garis bujur 0-4 (atau satu angka
long*4+lat
,.) Garis bujur yang ditandai pada peta hanya melewati wajah-wajah dengan garis bujur nol, dan garis garis lintang melewati pusat wajah dengan garis lintang nol.Pemain dapat berorientasi pada 3 kemungkinan sumbu, diwakili oleh simbol-simbol sebagai berikut: utara-selatan
-
-timur laut-barat daya\
-tenggara/
. Di setiap ruangan tertentu ia memiliki tepat satu pintu keluar pada masing-masing kapak yang tersedia untuknya. Pada layar yang ditampilkan, pemain membuat putaran searah jarum jam lengkap. Secara umum mudah untuk mengidentifikasi dari pemain yang menandai dari mana ia berasal, dan oleh karena itu ia boleh pergi ke mana.Satu kasus yang agak sulit bagi mata yang belum diinisiasi adalah yang keempat. Ketika Anda melihat kemiringan pada salah satu baris kutub ini, pemain telah datang dari sel kutub terdekat ujung luar kemiringan dan umumnya menghadap ke arah khatulistiwa. Dengan demikian pemain menghadap tenggara dan opsinya adalah: 15 (SELATAN, sel ke kanan) 25 (northEAST, sel di atas) atau 35 (northWEST, sel di bawah.)
Jadi, pada dasarnya saya memetakan icosahedron ke kisi 5x4, dengan sel-sel bernomor 19 hingga 0 dalam urutan dicetak. Langkah ini dilakukan dengan menambah atau mengurangi dari posisi saat ini, tergantung pada garis lintang dan arah pemain, per tabel di bawah ini.
Jika pemain keluar dari bawah (barat) papan, ia kembali ke sisi atas (timur) dan sebaliknya, sehingga posisinya diambil modulo 20. Secara umum gerakan dikodekan ke dalam m [] dengan menambahkan ascii 80 (
P
) ke nilai mentah memberikan karakter yang ditunjukkan di bawah ini, tetapi prinsip kelipatan 20 dapat ditambahkan tanpa mempengaruhi operasi.Input pemain (dibagi 10 untuk menghapus digit kedua) ditambahkan ke arah saat ini dan diambil modulo 3 untuk mendapatkan arah baru. Ini berfungsi dengan baik di sebagian besar kasus. Namun ada masalah ketika dia berada di ruang kutub dan bergerak menuju kutub. Ini akan menjadi jelas ketika melipat peta di bawah ini bahwa jika dia meninggalkan ruangan menghadap "timur laut" dia akan memasuki alun-alun baru yang menghadap "tenggara" sehingga koreksi harus dilakukan. Ini dilakukan di baris
e=(d+i/10)*m[p%4]%3;
dengan perkalian denganm[p%4]
. Empat nilai pertama m [] dipilih sedemikian rupa sehingga, selain fungsinya di atas, mereka juga memiliki karakteristikm[1]%3==m[2]%3==1
danm[0]%3==m[3]%3==2
. Ini meninggalkan arah sendirian untuk kamar khatulistiwa dan menerapkan koreksi yang diperlukan untuk kamar kutub.Waktu logis untuk melakukan koreksi adalah setelah pindah. Namun untuk menyimpan karakter itu dilakukan sebelum pindah. Karenanya nilai-nilai tertentu dalam m [] harus ditransformasikan. Jadi 2 karakter terakhir
LT
bukanTL
per tabel di atas misalnya.KODE TIDAK TERGERAK
ini adalah kode rev 1, yang kurang dikaburkan daripada rev 2.
Ini akan berjalan di GCC / Linux. Saya telah memasukkan dalam komentar kode tambahan yang diperlukan untuk membuatnya berjalan di Visual studio / Windows. Itu perbedaan besar!
ISU DAN KURIOISITAS
Saya telah mengambil keuntungan dari poin yang disebutkan oleh @professorfish, jika wumpus dan pit mulai di tempat acak, tidak ada kebutuhan bagi pemain untuk memulai di tempat acak. Pemain selalu mulai di kamar 19 menghadap ke utara.
Saya mengerti bahwa ketika wumpus "tidak terpengaruh oleh lubang", wumpus dapat mulai masuk, atau memasuki ruangan di mana lubang itu berada. Secara umum ini menyederhanakan hal-hal kecuali satu poin. Saya tidak memiliki variabel khusus untuk menunjukkan bahwa permainan telah berakhir; itu berakhir ketika pemain bertepatan dengan wumpus atau lubang. Jadi, ketika pemain menang, saya menampilkan pesan yang menang tetapi memindahkan lubang ke pemain untuk keluar dari lingkaran! Saya tidak bisa menempatkan pemain di lubang karena wumpus mungkin ada di sana dan saya akan mendapatkan pesan tentang wumpus yang tidak saya inginkan.
Program rev0 bekerja dengan sempurna di studio visual, tetapi IDE mengatakan "tumpukan rusak di sekitar variabel i" saat keluar. Hal ini karena scanf sedang mencoba untuk menempatkan
int
ke dalamchar.
Dennis melaporkan perilaku yang salah pada mesin Linux nya karena hal ini. Pokoknya itu diperbaiki dengan menggunakan tipe yang benar di rev 1.Garis untuk menampilkan papan di rev 0 adalah canggung dan muncul sedikit berbeda pada platform lain. Di
printf(" %c%c%c")
tengah% c adalah karakter yang dapat dicetak ditampilkan. % C terakhir adalah ASCII 0 atau ASCII 10 (\ n, baris baru dengan carriage return di Windows.) Tampaknya tidak ada karakter di Windows yang bekerja di konsol, yang akan turun baris tanpa memberikan carriage return. Jika ada, saya tidak memerlukan tab c% pertama (ASCII 0, atau ASCII 9 sebelum karakter lintang 1. Tab terkenal tidak terdefinisi dalam perilakunya.) Ruang terdepan meningkatkan pemformatan (menempatkan karakter 3 & 2 lebih dekat dengan karakter lintang 1 lebih dekat dengan karakter 1 .) Rev 1 memiliki revisi garis ini yang menggunakan karakter formfeed dan karenanya tidak memerlukan karakter format pada awal printf. Ini membuatnya lebih pendek, tetapi \ f tidak berfungsi di Windows.sumber
scanf_s
denganscanf
dan sertakanstdio.h
jika saya kompilasi sebagai C ++ rater daripada C), tetapi tidak cukup berfungsi untuk saya. Misalnya, jika saya ke kiri, lalu kembali tepat di awal (15 35
), saya berada di ruangan yang berbeda dari yang saya mulai.i
memang masalahnya. The halaman manual mengatakan: " d Cocok integer desimal opsional ditandatangani; pointer berikutnya harus menjadi pointer ke int ." Mengubah jenis membuatnya berfungsi dengan baik.NULL
dengan0
danscanf_s
denganscanf
, Anda tidak perluint
sebelumnyamain
dan Anda dapat pindahi
dand
keluar dari main (mereka default keint
dan diinisialisasi ke0
). Juga, Anda dapat mendefinisikanp=19,h=rand()%p,w=rand()%p
, menggantim[]
dengan*m
dan itu harus mungkin untuk mendefinisikan makro untuk semua contohif(...==...)puts(...);
.GolfScript, 269 karakter
Perhatikan bahwa 163 dikurangkan dari jumlah karakter untuk string hard-coded. Jika Anda ingin men-debug output yang menunjukkan nomor kamar tambahkan baris berikut tepat setelah kejadian pertama
^
:Sesi contoh (dengan output debug tambahan):
sumber
{puts}:|;
, 5 karakter dengan menggantiR
danW
dengan-
dan>
(memungkinkan untuk menghilangkan spasi di sekitarnya) dan 9 karakter dengan menjatuhkan'> 'print
(tampaknya tidak diperlukan oleh pertanyaan).JavaScript (ECMAScript 6) -
21971759 -45% = 967,45 KarakterGolfnya hampir selesai ...
Termasuk GUI dengan Peta Icosahedral dan Mega-Bats untuk bonus penuh.
X
(lubang);B
(Mega-Bat);W
(Wumpus); danP
(Kamu).W
danP
tombol dapat diklik hanya di kamar yang berdekatan dengan lokasi Anda saat ini.Kode:
sumber
Bash, 365 (versi kerja pertama 726!)
MENCARI DENGAN GOLFSCRIPT?
@Dennis pada dasarnya telah melakukan semua golf untuk saya. Terima kasih!
Program mengasumsikan input yang valid. Input yang valid adalah arah yang Anda pilih (1 untuk kanan, 2 untuk kiri, 3 untuk belakang) diikuti oleh tindakan Anda (4 untuk menembak, 5 untuk berjalan).
Beberapa Penjelasan
Saya biasanya melakukan penjelasan verbose besar, tapi ini mungkin agak terlalu rumit bagi saya untuk diganggu.
Setiap simpul pada grafik dodecahedron dikodekan sebagai huruf (a = 1, b = 2, ... t = 20).
Posisi awal pemain selalu 20 (dan mereka berdiri dengan punggung ke 18), karena itu tidak masalah dalam dirinya sendiri, hanya posisi relatif pemain, lubang dan masalah wumpus.
Variabel
$p
menyimpan lokasi pemain.$r
menyimpan lokasi pemain sebelumnya.$w
adalah wumpus dan$h
(H untuk lubang) adalah lubang.Kode
Riwayat Versi
grep -oE
variabel. Disimpan 5 karakter.[a-z]{3}
variabel. Disimpan 3 karakter.echo
variabel. Disimpan 5 karakter.$m
.grep
dan menjadi sedikit lebih masuk akal.C
sebagai fungsi pencarian regexp untuk digunakan dalam pernyataan if, danE
sebagai fungsi mencetak "Anda membunuh wumpus" dan keluar.d
, dan menghapus tanda kurung yang tidak perlu.Contoh dijalankan
"In:" is input, "Out: is output".
Pemain berkeliaran sebentar, mencium wumpus dan menembak. Mereka rindu, dan wumpus masuk ke kamar mereka dan memakannya.
sumber
exit
hanya satu byte lebih panjang darig=1
itu dan menghilangkan kebutuhan untuk menguji non-nolg
dan beberapaelif
pernyataan. 2. Anda bisa menggunakan((i==35))
sebagai ganti[ $i = 35 ]
dan...&&...
bukanif ... then ... fi
. 3.q(){ L=({a..s});$j ${L[RANDOM%19]};}
dann=`$k $w$m<<<$d`;w=${n:RANDOM%2+1:1}
keduanya menghemat beberapa byte.while :;do
...done
denganfor((;;);{
...}
untuk penghematan 3 chard(){ x=npoemfgnshtoksblbtckpdpljqniorelgfhkbqraicadjaghimsmjtqecrdf;s=${x:3*30#$1-30:3};}
akan memungkinkan Anda untuk mengganti definisi daris
dann
dengand $p
dand $w
. Jika Anda selanjutnya mendefinisikanu=${s#*$r}$s
(dan menyesuaikan definisil
danf
sesuai), Anda tidak perlu$k
dan$m
lagi. Menghemat 83 byte, saya pikir. Juga, ruang dalamq ()
tidak diperlukan.c(){ [[ $1 =~ $2 ]];}
dan mengganti, misalnya, baris kedua hingga terakhirc $r $b||{ $j You missed;d $w;w=${s:RANDOM%2+1:1};}
.b=$p
dengand $p;u=u${s#*$r}$s
, garis setelahread i
dengan,y=${u:i/10:1};C $i 5&&{ p=$y;r=$b;}||{ d $w;C $y $w&&$j You killed the wumpus&&exit;$j You missed;w=${s:RANDOM%2:1};}
dan menghilangkanE()
.GolfScript (
206198)Akhirnya menyusul versi tabel pencarian Dennis, dari mana ia meminjam sedikit. Hal yang menarik tentang versi ini adalah tidak memiliki tabel pencarian untuk tata letak ruangan.
The 60 simetri rotasi dari icosahedron isomorfik ke grup alternating pada 5 huruf, A_5. Setelah mencoba semua jenis pendekatan untuk mewakili grup secara kompak, saya kembali ke yang paling sederhana: setiap elemen adalah permutasi dari paritas genap. Grup dapat dihasilkan dari dua generator dengan lebih dari satu cara: pendekatan yang saya gunakan menggunakan generator
3
dan3 1
. Ini memungkinkan kita untuk menghasilkan1 = 3 3 1
,2 = 3 3 1 3 1
dan3 = 3
.Perhatikan arah yang
3
sesuai dengan elemen orde 2, karena setelah melewati pintu di belakang Anda, pintu itu ada di belakang Anda lagi. Arah1
sesuai dengan elemen urutan 5, berjalan di sekitar puncak icosahedron. (Demikian pula elemen2
). Dan kombinasinya3 1
adalah orde 3, karena putaran mengelilingi kamar yang berdekatan dengan yang dimulai di belakang Anda.Jadi kami sedang mencari permutasi orde 2 untuk mewakili arah
3
dan permutasi orde 5 untuk mewakili arah1
sehingga3 1
orde 3.Ada 15 permutasi urutan 2 di A_5, dan untuk masing-masing ada 8 permutasi kandidat untuk
1
(dan karenanya untuk3 1
). Ada daya tarik yang jelas[4 3 2 1 0]
untuk3
: membalikkan array itu adil-1%
. Dari kemungkinan permutasi pendamping yang3 1
saya pilih[0 1 3 4 2]
, yang mengakui implementasi yang cukup singkat sebagai[~@]
.Tidak disatukan
sumber
10/@3%=
mencoba mengakses elemen keempat array dengan panjang 3 jika inputnya35
.9/3%@3%=
.9/
bukannya10/
masih berfungsi, jadi terima kasih.Wumpus , 384 - 129 (string) = 255 byte
Cobalah online! (Tentu saja, TIO tidak masuk akal, karena Anda tidak dapat menggunakan program secara interaktif di sana, dan begitu program kehabisan instruksi pada STDIN, ia akan membaca
0 0
, yang setara dengan3 4
, sehingga Anda akan berakhir menembakkan panah sampai Wumpus bergerak ke sana atau membunuhmu.)Ketika menjalankan ini secara lokal, pastikan bahwa linefeed setelah nomor kedua dari setiap input memerah (karena Wumpus membutuhkannya untuk menentukan bahwa nomor tersebut sudah lewat). Dalam Powershell, saya entah bagaimana harus memasukkan satu karakter lagi setelah linefeed untuk membuatnya berfungsi (tidak masalah karakter mana, tapi saya hanya menggunakan double linefeeds untuk pengujian).
Ada banyak ruang untuk bermain golf lebih jauh, tetapi mencoba tata letak yang sama sekali baru membutuhkan waktu. Skor akhir juga sangat tergantung pada string aktual yang saya gunakan, karena dalam bahasa 2D, string N byte cenderung lebih mahal daripada N byte kode sumber, karena itu menempatkan kendala signifikan pada tata letak kode, dan Anda sering perlu membaginya menjadi beberapa bagian (menimbulkan tanda kutip ganda tambahan). Pada akhirnya, jika saya mengurangi setiap string menjadi satu huruf (dan -129 menjadi -12), saya mungkin akan menghemat satu ton byte.
Penjelasan
Pertama, penafian: terlepas dari nama bahasa, itu tidak dirancang untuk membuat penerapan Hunt the Wumpus sangat mudah. Sebagai gantinya, saya pertama-tama merancang bahasa di sekitar tema segitiga, berakhir dengan struktur data icosahedral, dan memutuskan untuk menyebutnya Wumpus karena itu.
Jadi ya, sementara Wumpus terutama berbasis stack, ia juga memiliki 20 register yang disusun di sekitar wajah icosahedron. Itu artinya, kami mendapatkan struktur data untuk mewakili peta secara gratis. Satu-satunya hal yang tidak dapat kita lakukan dengan mudah adalah menemukan wajah tertentu pada icosahedron, jadi untuk mencarinya, kita perlu "menggulung d20" hingga kita berakhir pada wajah yang kita cari. (Dimungkinkan untuk melakukan ini dengan cara deterministik, tetapi itu akan membutuhkan lebih banyak byte.) Mencari wajah seperti ini berakhir hampir pasti (yaitu dengan probabilitas 1), sehingga pencarian yang berjalan selamanya tidak menjadi perhatian dalam praktiknya).
Kode di atas adalah versi golf dari implementasi pertama ini dengan tata letak yang lebih waras:
Karena golf sebagian besar melibatkan mengompresi tata letak, saya hanya akan menjelaskan versi ini untuk saat ini (sampai saya menambahkan trik golf yang melampaui restrukturisasi kode).
Mari kita mulai dengan kode pengaturan:
Awalnya, semua wajah diatur ke 0 . Kami akan menyandikan wumpus dengan mengatur 1-bit dari wajah yang sesuai, dan lubang dengan mengatur 2-bit. Dengan cara ini, keduanya bisa berada di ruangan yang sama. Posisi pemain tidak akan direkam pada icosahedron sama sekali, melainkan akan selalu berupa wajah aktif (hanya satu dari 20 register yang aktif pada satu waktu).
Sekarang kita perlu menemukan wajah kosong acak untuk memasukkan pemain.
Bagian selanjutnya ini memeriksa lingkungan pemain dan mencetak peringatan yang sesuai:
Ini adalah loop yang kami jalankan melalui 3 kali. Setiap kali, kita melihat tetangga sebelah kanan, mencetak string yang sesuai jika ada bahaya dan kemudian memutar icosahedron sebesar 120 °.
Bagian selanjutnya membaca dua angka dari pemain dan kemudian menggerakkan pemain atau menembakkan panah. Yang pertama sepele, yang terakhir kurang begitu. Masalah utama untuk menembak panah adalah kasus di mana ia meleset. Dalam hal ini kita a) perlu mencari wumpus untuk memindahkannya, dan kemudian b) kembali ke kamar pemain dan orientasi yang benar dari icosahedron (sehingga "kembali" tetap "kembali"). Ini adalah bagian paling mahal dari keseluruhan program.
Titik masuk ke bagian ini adalah
I
di sebelah kiri.Fiuh, itu bagian yang sulit. Sekarang kita hanya perlu memeriksa apakah pemain mati dan memulai dari loop utama:
Struktur bagian ini pada dasarnya identik dengan struktur yang kami gunakan ketika memeriksa lingkungan pemain: kami memeriksa 1-bit dari wajah saat ini (ruang pemain) dan jika diatur kami mencetak
The wumpus ate you.
dan menghentikan program. Kalau tidak, kita periksa 2-bit dan sudah diatur kita mencetakYou fell into the pit.
dan mengakhiri program. Kalau tidak, kita mencapai2.
yang melompat kembali ke awal loop utama (pada koordinat(0, 2)
).sumber
awk - besar
Ini tidak berjalan sesingkat yang saya harapkan, tetapi saya mengambil pendekatan yang sedikit berbeda untuk berurusan dengan grafik, jadi saya tetap memposting versi yang tidak diklik.
Saya mengambil keuntungan dari fakta bahwa icosahedron (20 sided polyhedron) di bawah rotasi menjaga orientasi isomorfik untuk kelompok bolak-balik derajat 5 (permutasi elemen 5 memiliki jumlah genap dari siklus panjang genap). Saya kemudian memilih dua permutasi dengan panjang siklus 5 sebagai "kiri" dan "kanan", dan saya memilih satu permutasi dengan panjang siklus 2 sebagai "kembali". Menggunakan ini, saya membangun grafik dari satu ruangan dengan berjalan di jalur Hamiltonian (2xRRRLLLRLRL, menggunakan 3xRB di setiap kamar untuk menangkap 3 kemungkinan arah).
sumber