Temukan hasil permainan Perang
Ketika saya masih di sekolah dasar, ada permainan "Rock-Paper-Scissors" yang akan kami mainkan saat kebaktian, ketika menunggu guru kami, saat istirahat dll. Kami menyebutnya "Perang". Namun setelah beberapa pencarian, ternyata ini adalah varian yang lebih sederhana dari "Shotgun Game" (menurut WikiHow) . Saya akan menyebutnya "Perang" karena aturannya sedikit berbeda:
2 orang duduk berhadapan. Tujuan permainan ini adalah untuk "membunuh" pemain lain. Setiap belokan, Anda dapat memainkan salah satu dari 3 gerakan:
Muat ulang : Anda memiliki senjata yang menahan satu tembakan. Itu harus dimuat ulang sebelum dapat dipecat setiap kali. Memuat ulang saat Anda sudah memiliki amunisi adalah legal, tetapi tidak melakukan apa-apa. Muat ulang dilambangkan dengan mengetuk pelipis Anda dengan kedua tangan. Setiap pemain mulai dengan 0 amunisi.
Penjaga : Satu-satunya langkah aman. Jika Anda ditembak saat menjaga, Anda tidak mati. Pelindung dilambangkan dengan menyilangkan tangan di dada.
Api : Menembakkan pistol Anda. Agar berhasil menembak, Anda harus memuat ulang sejak tembakan terakhir. Jika lawan Anda memuat ulang, Anda menang. Jika mereka juga menembak, dan Anda berdua memiliki amunisi, itu seri. Jika mereka menjaga, Anda membuang amunisi. Meskipun menembak tanpa amunisi adalah langkah legal, ia tidak melakukan apa-apa dan membuat Anda rentan seperti memuat ulang. Menembak dilambangkan dengan menunjuk pemain lain.
Itu dimainkan mirip dengan RPS, di mana setiap pemain secara bersamaan melempar pilihan mereka (kami mengetuk kaki kami dua kali di antara putaran untuk menjaga ritme satu sama lain, tapi itu tidak penting untuk tantangan).
Tantangan:
Tugas Anda adalah menemukan hasil permainan War. Ini bisa berupa fungsi atau program lengkap.
Memasukkan
Opsi setiap pemain memilih setiap belokan akan diwakili oleh karakter / string:
r : memuat ulang
g : penjaga
f : api
Input akan berupa daftar pasangan, string yang dibatasi / tidak didahului, atau apa pun di sepanjang baris ini.
Contoh input dengan Python bisa [("r", "g"), ("f", "r")]
, artinya pada giliran pertama pemain pertama dimuat ulang, dan pemain kedua dijaga. Pada belokan kedua, pemain pertama menembak, sementara pemain kedua memuat ulang. Pemain satu memenangkan permainan ini. Input yang sama bisa pilih dapat direpresentasikan sebagai "r g f r"
, "rgfr"
, "rg fr"
"rg-fr"
...
Anda dapat mengasumsikan sebagai berikut:
Input akan cocok dengan format yang Anda pilih, dan itu hanya akan berisi karakter yang valid.
Seseorang akan mati dalam 100 putaran.
Namun Anda tidak dapat mengasumsikan bahwa belokan berakhir ketika seseorang meninggal.
Keluaran
Nilai yang menunjukkan siapa yang menang (atau, siapa yang menang lebih dulu *
). Anda dapat memilih apa yang akan dihasilkan untuk setiap skenario, tetapi harus memperhitungkan yang berikut ini:
Pemain 1 menang
Pemain 2 menang
Mereka saling membunuh (menggambar)
Setiap hasil harus memiliki nilai distrik, dan harus selalu sama untuk setiap skenario.
Sebagai contoh: Anda bisa menampilkan 1
kapan pemain 1 menang, 2
ketika pemain 2 menang, dan 0
dalam hal seri. Anda kemudian harus selalu menampilkan 1
kapan pemain 1 menang, 2
ketika pemain 2 menang, dan 0
dalam hal imbang.
Itu dapat dikembalikan, atau dicetak ke stdout. Trailing whitespace baik-baik saja.
Sedemikian jelasnya, satu-satunya skenario yang mengarah pada hasil imbang adalah jika kedua pemain menembak, dan keduanya memiliki amunisi.
*
Karena dalam tantangan ini, belokan dapat berlanjut setelah seseorang meninggal, mungkin lebih dari 1 pemain akhirnya bisa menang. Anda perlu menemukan siapa yang menang terlebih dahulu sesuai dengan input.
Uji Kasus (dengan asumsi 1
ketika P1 menang, 2
ketika P2 menang, dan 0
untuk seri):
"rg fr" => 1 (P1 shot P2 while they were reloading)
"rg ff" => 1 (They both shot, but only P1 had ammo)
"rr ff" => 0 (Both had ammo and shot each other)
"rr ff rr fg" => 0 (Both had ammo and shot each other. Everything after the first win is ignored)
"rr fg rf" => 2 (P2 shot P1 while they were reloading)
"rf gg rr fg rr fr" => 1
(P2 tried to shoot but didn't have any ammo, then they both guarded, then they both reloaded, then P2 blocked a shot, then they both reloaded again [but P2 still only has 1 ammo!], then P1 shoots P2 while they're reloading.
"rr gf fr rf gg rg ff" => 1
^ Player 1 wins here. The rest to the right has no effect on the output
Ini adalah kode golf, sehingga jumlah byte terkecil menang!
Catatan, seperti yang ditunjukkan oleh kasus uji, Anda harus menangani gerakan "bodoh". Ini benar-benar berlaku bagi seorang pemain untuk mencoba menembak ketika mereka tidak memiliki amunisi, atau memuat ulang 2 putaran berturut-turut (dan hanya mengumpulkan satu amunisi tunggal).
{"rff","rgf"}
?Jawaban:
Retina , 36 byte
Format input harus merupakan pasangan yang dipisahkan oleh linefeed, mis
Output adalah
!_
pemain 1 menang,_!
jika pemain 2 menang dan!!
jika ada hasil seri.Cobalah online!(Ruang uji yang menggunakan pemisahan ruang untuk kenyamanan.)
Saya pasti benar-benar mengabaikan tantangan ini. Saya yakin saya akan mencoba ini di Retina sebelumnya. :)
Penjelasan
Kami mulai dengan menandai bidikan "sah" dengan memutar bidikan pertama
f
setelah masing-masingr
- menjadi!
. Kami melakukan ini dengan mencocokkan masing-masingf
dari yang dapat ditemukanr
pada pemain yang sama tanpa melewati yang lainf
. Membatasi pencarianr
pada pemain yang sama itu mudah dengan selalu menggunakan tiga karakter sekaligus.Sekarang kita membuang semua belokan di mana seseorang menjaga diri mereka sendiri, karena belokan terakhir tidak mungkin salah satunya.
Sekarang kami hanya menyimpan belokan pertama yang berisi
!
. Jika tembakan yang valid terjadi (dan kami tahu bahwa tidak ada yang menjaga) permainan berakhir.Akhirnya, kita perlu mengkonsolidasikan string untuk memberikan output yang konsisten, dan kita cukup melakukan ini dengan memutar non-
!
karakter (baikr
atauf
) menjadi_
.sumber
Python, 139 Bytes
Mengambil input pada stdin dalam bentuk daftar string 2-karakter (mis. ['Rf', 'rr', 'rg', 'ff']). Output 1 jika pemain 1 menang, -1 jika pemain 2 menang, dan 0 untuk seri.
Penjelasan: Pertama-tama memeriksa apakah ada yang menembakkan peluru, jika demikian permainan berakhir. Kemudian kami menentukan apakah para pemain telah mengisi ulang senjata mereka atau membuang amunisi mereka.
Ini adalah posting codegolf pertama saya :)
sumber
JavaScript (ES6),
10810793918985 byteDisimpan 4 byte dengan bantuan Titus
Mengambil input sebagai array string 2 karakter yang menggambarkan gerakan yang dimainkan oleh setiap pemain.
Pengembalian:
1
jika pemain 1 menang2
jika pemain 2 menang3
untuk menggambarBagaimana itu bekerja
Kami mempertahankan bitmask yang
b
menggambarkan siapa yang memiliki peluru dimuat:Kami menggunakan urutan De Bruijn
'ffrfgrrggf'
untuk mengidentifikasi semua 9 kemungkinan kombinasi gerakan. Kami menggunakan OR dan AND bitmasks untuk memperbaruib
sesuai dengan kombinasi langkah. Kami menggunakan seperangkat bitmaskb
ke -3 yang AND dengan untuk menentukan pemenangw
. (Hanya tiga kombinasi yang menangff
,fr
danrf
.)Perlu dicatat bahwa topeng OR dan AND dapat disimpan dengan pola yang sama, digeser oleh dua posisi.
Uji kasus
Tampilkan cuplikan kode
sumber
0
(tidak ada yang tertembak) atau3
(pemain saling bunuh) dalam kasus imbang. Tidak yakin apakah ini diizinkan. Jika tidak, saya bisa kembaliw%3
.&
mask bisa 0 untukfr,rf,ff
.'312'['0210231'[m='ffrfgrrggf'.search(c)]|'233331'[m-3]&b]
atau'123'['2100231'[m='frffgrrggf'.search(c)]|'233331'[m-3]&b]
simpan satu byte; tetapi apakah mereka bekerja?["rr","fg","fr","rf"]
&
memiliki prioritas lebih tinggi daripada|
, jadi mengubah urutan tidak boleh mengubah apa pun di sana (selain menyimpan byte). Tapi tugas itu hilang dalam kode saya. Coba...'123'[b='2100231'...
.Perl 6 ,
7162 byteSolusi berbasis Regex.
Mengambil input sebagai string dalam formulir
"rg fr"
.Tiga kemungkinan output adalah nilai-nilai enum
More
(pemain 1 won),Less
(pemain 2 won),Same
(menarik) - yang berubah menjadi kata-kata ketika dicetak, atau ke1
,-1
,0
ketika dipaksa untuk nomor.Cobalah online!
Bagaimana itu bekerja
Melakukan dua pertandingan regex pada input. Setelah interpolasi, kedua regex tersebut adalah:
r[..[r|g]]*.[r|f]f
- Mencocokkan tembakan berhasil pertama oleh pemain 2.r[..[r|g]]*..f[r|f]
- Mencocokkan tembakan berhasil pertama oleh pemain 1.Dalam setiap kasus, ia mengembalikan posisi akhir pertandingan (
.to
), atau tak terbatas jika tidak ada kecocokan.Terapkan
<=>
operator ke dua posisi ujung yang cocok. Ini mengembalikan nilai dariOrder
enum (More
,,Less
atauSame
), tergantung pada apakah argumen pertama lebih besar, lebih sedikit, atau sama dengan yang kedua.sumber
some number
? Dan apakah Anda benar-benar menggunakan karakter seperti itu dalam kode Perl yang umum, atau hanya untuk bermain golf?[Menu] i n f
(ini disebut urutan penulisan ). Namun, semua simbol Perl 6 memiliki versi ASCII - misalnyaInf
dan∞
sinonim - sehingga tidak perlu menggunakan simbol Unicode dalam kode Perl 6. Saya hanya suka ... :)Haskell ,
101 9187 byteCobalah online! Fungsi infix
#
mengambil dua string yang mewakili tindakan masing-masing dari dua pemain dan kembali(0,1)
jika pemain 1 menang,(1,0)
untuk pemain 2 dan(0,0)
untuk hasil seri.Contoh penggunaan:
Penjelasan:
Fungsi infix
!
menerjemahkan urutan tindakan'r'
(reload),'f'
(api) dan'g'
(penjaga) ke urutan tindakan yang dapat diamati0
(api yang sebenarnya),1
(tidak ada tindakan) dan2
(penjaga), di mana aksi api hanya dihitung sebagai aksi api yang sebenarnya jika peluru dimuat, dan karena tidak ada tindakan sebaliknya. Untuk mencapai ini, argumen pertaman
adalah0
jika peluru dimuat dan1
jika pistol tidak dimuat. Dengan cara ini masing'f'
- masing dapat dengan mudah diganti dengan yang sekarangn
. (n=0
-> dimuat -> api aktual ->0
,n=1
-> dibongkar -> tidak ada tindakan ->1
)Sembilan kemungkinan yang dihasilkan saat itu
(0,0)
: Kedua pemain menembak dan mati, pertandingan berakhir.(0,1)
atau(1,0)
: Satu pemain menembak yang lain, permainan berakhir.(0,2)
atau(2,0)
: Satu pemain menembak tetapi penjaga lainnya, permainan berlanjut.(1,1)
,(1,2)
,(2,1)
Atau(2,2)
: Tidak ada pemain tunas, permainan berlanjut.Dengan mendesain jumlah dari opsi akhir permainan lebih kecil dari 2 dan jumlah setiap kemungkinan melanjutkan game lebih besar atau sama 2. Hasil dari permainan adalah tuple pertama dengan jumlah kurang dari 2.
sumber
Batch, 249 byte
Input berupa pasangan karakter untuk setiap belokan dan output berdasarkan tingkat kesalahan (0 = draw, 1 = pemain 1, 2 = pemain 2).
x
dany
melacak apakah pemain memiliki amunisi, jadi ketika keduanya menembak, hasilnya adalah3-x-x-y
, kecuali jika itu adalah 3, dalam hal ini kita terus berjalan. Pada baris 5 saya menyalahgunakan parser Batch -%1
(yang merupakan langkah saat ini) diganti sebelumshift
pernyataan dieksekusi dan dihapus, jadi kami masih pergi ke label yang benar.sumber
Clojure, 168 byte
Kurang bermain golf (jika kedua orang masih hidup, kami gunakan
M
untuk memperbarui amunisi dan kondisi kehidupan musuh mereka, jika tidak, kami mengembalikan status saat ini):Contoh penggunaan (elemen pertama memberi tahu jika Pemain 1 masih hidup di akhir pertandingan, elemen kedua memberi tahu jika Pemain 2 masih hidup, 3 dan 4 memberi tahu status amunisi yang tidak relevan saat menentukan pemenang):
Pembaruan: Lihat itu,
loop
panjangnya identik! Saya menemukanreduce
versi lebih mudah untuk dikembangkan karena Anda dapat dengan mudah memeriksa kondisi perantara jika Anda menggunakannyareductions
.sumber
[l1 l2 r1 r2]
(nilai yang dimodifikasi padalet
dan nilai aslinya) danfn
tanda tangan itu.loop
. Saya menemukan itu mengarah pada kode yang lebih rapi. Segera setelah saya perlu melipat dengan lebih dari 1 akumulator, saya beralih.PHP,
10710190 bytemenggunakan bit mask $ d untuk status pemuatan dan urutan DeBruijn untuk pemindahan tembakan.
mengambil input sebagai argumen baris perintah 2-karakter, jalankan dengan
-nr
.kerusakan
fr
position = 1 = P1 fires;rf
= posisi 2 = P2 kebakaran,ff
= posisi 3 = keduanya apig<$m
<=>f<$m[0]
(f<$m
selalu benar, karena ada karakter kedua).sumber
Python, 200 byte
sumber
turns
bukan hanyat
, yang berarti programnya jauh lebih besar dari yang diperlukan. Juga silakan mulai kiriman Anda dengan sesuatu seperti#Python 2, 200 bytes
(dengan asumsi ini adalah 2, dan panjang programnya adalah 200 byte) sehingga bahasa yang Anda gunakan jelas.Clojure,
180173 byte-7 byte dengan mengubah fungsi menjadi fungsi penuh alih-alih menggunakan makro. Itu biarkan saya membuat fungsi makro, yang menghemat sedikit.
Ini adalah solusi yang sangat literal. Saya agak bingung karena saya baru saja menulis versi lengkap dari gim ini, dan ini pada dasarnya adalah versi algoritma yang saya gunakan. Mungkin ada banyak optimasi yang bisa saya lakukan, tetapi saya cukup senang dengannya. Lihat kode pregolfed untuk penjelasan.
sumber