Temukan hasil permainan Perang


15

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 1kapan pemain 1 menang, 2ketika pemain 2 menang, dan 0dalam hal seri. Anda kemudian harus selalu menampilkan 1kapan pemain 1 menang, 2ketika pemain 2 menang, dan 0dalam 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 1ketika P1 menang, 2ketika P2 menang, dan 0untuk 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).


Apakah saya melewatkan sesuatu atau dapatkah output ditentukan hanya dari putaran terakhir?
xnor

@ Memperbarui pertanyaan. Dan tidak, karena Anda perlu tahu apakah seorang pemain memiliki amunisi atau tidak. Namun saya menyadari bahwa Anda dapat mengasumsikan pemain mana yang memiliki amunisi berdasarkan fakta bahwa inilah giliran terakhir. Saya benar-benar mengubah aturan cukup menit terakhir yang memungkinkan dengan asumsi input akan berakhir ketika seseorang meninggal. Saya menyesalinya sekarang.
Carcigenicate


3
Ini sangat mirip dengan Skor permainan Load, Defend dan Shoot . Satu-satunya perbedaan adalah bahwa tantangan lain memiliki senjata dengan lebih dari satu tembakan dan bahwa menembakkan senjata kosong dianggap menipu dan kehilangan permainan.
Dennis

Bisakah kita mengambil dua input terpisah untuk dua pemain, bukan putaran, misalnya {"rff","rgf"} ?
betseg

Jawaban:


2

Retina , 36 byte

s`(?<=r..([^f]..)*)f
!
A`g
G1`!
\w
_

Format input harus merupakan pasangan yang dipisahkan oleh linefeed, mis

rr
fr

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

s`(?<=r..([^f]..)*)f
!

Kami mulai dengan menandai bidikan "sah" dengan memutar bidikan pertama f setelah masing-masingr - menjadi !. Kami melakukan ini dengan mencocokkan masing-masing fdari yang dapat ditemukan rpada pemain yang sama tanpa melewati yang lain f. Membatasi pencarian rpada pemain yang sama itu mudah dengan selalu menggunakan tiga karakter sekaligus.

A`g

Sekarang kita membuang semua belokan di mana seseorang menjaga diri mereka sendiri, karena belokan terakhir tidak mungkin salah satunya.

G1`!

Sekarang kami hanya menyimpan belokan pertama yang berisi !. Jika tembakan yang valid terjadi (dan kami tahu bahwa tidak ada yang menjaga) permainan berakhir.

\w
_

Akhirnya, kita perlu mengkonsolidasikan string untuk memberikan output yang konsisten, dan kita cukup melakukan ini dengan memutar non- !karakter (baik ratauf ) menjadi_ .


5

Python, 139 Bytes

c=d=0
for i in input():
 b=(c&(i=='fr'))-(d&(i=='rf'));p,q=i
 if b|(i=='ff')&c&d:print b;break
 c,d=(p=='r',i!='fg')[c],(q=='r',i!='gf')[d]

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 :)


4

JavaScript (ES6), 108 107 93 91 89 85 byte

Disimpan 4 byte dengan bantuan Titus

Mengambil input sebagai array string 2 karakter yang menggambarkan gerakan yang dimainkan oleh setiap pemain.

b=>b.map(c=>w=w||b&'312'[b=(s='0210231')[m='ffrfgrrggf'.search(c)]|s[m-2]&b,m],w=0)|w

Pengembalian:

  • 1 jika pemain 1 menang
  • 2 jika pemain 2 menang
  • 3 untuk menggambar

Bagaimana itu bekerja

Kami mempertahankan bitmask yang bmenggambarkan siapa yang memiliki peluru dimuat:

  • bit # 0: pemain 1 memiliki peluru
  • bit # 1: pemain 2 memiliki peluru

Kami menggunakan urutan De Bruijn 'ffrfgrrggf' untuk mengidentifikasi semua 9 kemungkinan kombinasi gerakan. Kami menggunakan OR dan AND bitmasks untuk memperbarui bsesuai dengan kombinasi langkah. Kami menggunakan seperangkat bitmask bke -3 yang AND dengan untuk menentukan pemenang w. (Hanya tiga kombinasi yang menang ff, frdan rf.)

Perlu dicatat bahwa topeng OR dan AND dapat disimpan dengan pola yang sama, digeser oleh dua posisi.

 Index in | Combination | Bullet   | Bullet  | Winner
 sequence |             | AND mask | OR mask | mask
----------+-------------+----------+---------+--------
    0     |     ff      |    0     |    0    |   3
    1     |     fr      |    0     |    2    |   1
    2     |     rf      |    0     |    1    |   2
    3     |     fg      |    2     |    0    |   0
    4     |     gr      |    1     |    2    |   0
    5     |     rr      |    0     |    3    |   0
    6     |     rg      |    2     |    1    |   0
    7     |     gg      |    3     |    0    |   0
    8     |     gf      |    1     |    0    |   0

Uji kasus


@Carcigenicate Ini harus diperbaiki untuk kedua kasus yang gagal. Namun, saya sekarang kembali 0(tidak ada yang tertembak) atau 3(pemain saling bunuh) dalam kasus imbang. Tidak yakin apakah ini diizinkan. Jika tidak, saya bisa kembali w%3.
Arnauld

Saya ingin 1 output per skenario. Saya menjamin bahwa seseorang akan selalu ditembak, jadi menghitung untuk kasus itu tidak perlu. Satu-satunya kasus yang mengarah ke undian adalah ketika keduanya saling menembak, dan keduanya memiliki amunisi.
Carcigenicate

The &mask bisa 0 untuk fr,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?
Titus

@ Titus Menariknya, menerapkan topeng OR sebelum topeng AND akan bekerja untuk semua kasus uji yang ada. Tapi itu akan gagal untuk sesuatu seperti["rr","fg","fr","rf"]
Arnauld

&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'....
Titus

2

Perl 6 , 71 62 byte

{&[<=>](|map {m/r[..[r|g]]*.$^f/.to//∞},/[r|f]f/,/.f[r|f]/)}

Solusi 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 ke 1, -1,0 ketika dipaksa untuk nomor.

Cobalah online!

Bagaimana itu bekerja

  • map { m/r[..[r|g]]*.$^f/.to // ∞ }, /[r|f]f/, /.f[r|f]/

    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 dari Orderenum ( More,, Lessatau Same), tergantung pada apakah argumen pertama lebih besar, lebih sedikit, atau sama dengan yang kedua.


Rapi. Karena penasaran, bagaimana Anda mengetik simbol infinity? Keyboard khusus, atau Anda mengetik alt + some number? Dan apakah Anda benar-benar menggunakan karakter seperti itu dalam kode Perl yang umum, atau hanya untuk bermain golf?
Carcigenicate

@Carcigenicate: Skema keyboard khusus saya memungkinkan saya memasukkannya dengan menekan empat tombol [Menu] i n f(ini disebut urutan penulisan ). Namun, semua simbol Perl 6 memiliki versi ASCII - misalnya Infdan sinonim - sehingga tidak perlu menggunakan simbol Unicode dalam kode Perl 6. Saya hanya suka ... :)
smls

Ahh. Satu hal yang membuat saya tentang Perl adalah simbol infinity. Saya pikir itu adalah persyaratan, yang sepertinya tidak perlu rumit. Mungkin ketika saya bosan dengan Clojure saya akan mencoba Perl. Saya telah melihat banyak kode Perl belakangan ini.
Carcigenicate

@Carcigenicate: Ketahuilah bahwa Perl 6 pada dasarnya adalah bahasa baru yang tidak kompatibel dengan Perl, dan interpreternya masih lambat (dan untuk beberapa fitur, buggy). Perl, saat ini di versi v5.24, terus dipertahankan secara terpisah.
smls

Ok terima kasih. Senang mendengarnya.
Carcigenicate

2

Haskell , 101 91 87 byte

n!(c:r)|'g'>c=n:1!r|'g'<c=1:0!r|1<3=2:n!r
_!r=[]
a#b=[x|x@(y,z)<-zip(1!a)$1!b,2>y+z]!!0

Cobalah 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:

Prelude> "rgrfrf" # "fgrgrr"
(0,1)

Penjelasan:

Fungsi infix !menerjemahkan urutan tindakan 'r'(reload), 'f'(api) dan 'g'(penjaga) ke urutan tindakan yang dapat diamati 0(api yang sebenarnya), 1(tidak ada tindakan) dan 2(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 pertama nadalah 0jika peluru dimuat dan 1jika pistol tidak dimuat. Dengan cara ini masing 'f'- masing dapat dengan mudah diganti dengan yang sekarang n. ( n=0-> dimuat -> api aktual -> 0, n=1-> dibongkar -> tidak ada tindakan -> 1)

n ! (c:r)                -- n is 0 or 1, c is 'f', 'g' or 'r' and r the rest of the string
    |'g'>c = n : (1 ! r) -- c is smaller 'g', so it must be 'f'. append n to the list
                         --  and set load status to 1 (unloaded)
    |'g'<c = 1 : (0 ! r) -- c is larger 'g', so it must be 'r'. append 1 (no action)
                         --  and set load status to 0 (loaded)
    |1<3   = 2 : (n ! r) -- c must be equal to 'g'. append 2 (guard)
                         --  and leave the load status unchanged
_ ! r = []               -- base case for recursion

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.

a#b=[x|         -- build the list of all x
    x@(y,z) <-  -- where x is an alias for the tuple (y,z) which is drawn from the list
    zip (1!a)   -- of tuples where the first component is from 1!a = eg. [1,2,1,0,1,0] 
        (1!b)   -- and the second from 1!b = eg. [1,2,1,2,1,1]
    , 2 > y+z]  -- and y+z are smaller 2.
    !!0         -- return the first element of this list

1

Batch, 249 byte

@echo off
set g=goto gg
set/ax=y=0
:gg
shift&goto %1
:fg
set x=0
%g%
:gf
set y=0
%g%
:rr
set/ax=y=1
%g%
:fr
if %x%==1 exit/b1
:gr
set y=1
%g%
:rf
if %y%==1 exit/b2
:rg
set x=1
%g%
:ff
set/az=3-x-x-y
if %z%==3 %g%
exit/b%z%

Input berupa pasangan karakter untuk setiap belokan dan output berdasarkan tingkat kesalahan (0 = draw, 1 = pemain 1, 2 = pemain 2). xdan ymelacak apakah pemain memiliki amunisi, jadi ketika keduanya menembak, hasilnya adalah 3-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 sebelum shiftpernyataan dieksekusi dan dihapus, jadi kami masih pergi ke label yang benar.


1

Clojure, 168 byte

#(reduce(fn[[l L r R][a A]](if(and l L)(let[M(fn[r a A](if(and(= a \f)r)[nil(= A \g)][(or(= a \r)r)1]))[r L](M r a A)[R l](M R A a)][l L r R])[l L r R]))[1 1 nil nil]%)

Kurang bermain golf (jika kedua orang masih hidup, kami gunakan Muntuk memperbarui amunisi dan kondisi kehidupan musuh mereka, jika tidak, kami mengembalikan status saat ini):

(def f (fn[A] (reduce
                (fn [[l1 l2 r1 r2] [a1 a2]]
                  (if (and l1 l2)
                    (let[M (fn [r1 a1 a2]
                             (if (and(= a1 \f)r1)
                               [false (= a2 \g)]        ; we lost the ammo, a2 lives if he was guarding
                               [(or(= a1 \r)r1) true])) ; we might gain or keep ammo, a2 lives no matter what
                         [r1 l2] (M r1 a1 a2)
                         [r2 l1] (M r2 a2 a1)]
                      [l1 l2 r1 r2])
                    [l1 l2 r1 r2]))
                [true true false false] A)))

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):

(-> (for[[a b s] (partition 3 "rr fg rf fr ")][a b]) f (subvec 0 2))

Pembaruan: Lihat itu, looppanjangnya identik! Saya menemukan reduceversi lebih mudah untuk dikembangkan karena Anda dapat dengan mudah memeriksa kondisi perantara jika Anda menggunakannya reductions.

#(loop[l 1 L 1 r nil R nil[[a A]& I]%](if(and l L)(let[M(fn[r a A](if(and(= a \f)r)[nil(= A \g)][(or(= a \r)r)1]))[r L](M r a A)[R l](M R A a)](recur l L r R I))[l L]))

Saya sedang menunggu! Itu padat, wow.
Carcigenicate

Hehe terima kasih, masih mengganggu saya bahwa saya harus mengulangi [l1 l2 r1 r2](nilai yang dimodifikasi pada letdan nilai aslinya) dan fntanda tangan itu.
NikoNyrh

Setidaknya untuk yang terakhir, itu sebabnya saya mendukung loop. Saya menemukan itu mengarah pada kode yang lebih rapi. Segera setelah saya perlu melipat dengan lebih dari 1 akumulator, saya beralih.
Carcigenicate

1

PHP, 107 101 90 byte

menggunakan bit mask $ d untuk status pemuatan dan urutan DeBruijn untuk pemindahan tembakan.

for(;!$x=$d&strpos(_frff,$m=$argv[++$i]);)$d=$d&g<$m|h<$m|2*($d/2&f<$m[1]|g<$m[1]);echo$x;

mengambil input sebagai argumen baris perintah 2-karakter, jalankan dengan -nr.

1 = Pemain 1 menang
2 = Pemain 2 menang
3 = seri

kerusakan

for(;!$x=$d&strpos(_frff,       // 1. $x=someone dies, loop while not
    $m=$argv[++$i]          // loop throug moves
);)
    $d=
        $d&g<$m|h<$m            // 2. unload/reload Player 1 = bit 0
    |2*(
        $d/2&f<$m[1]|g<$m[1]    // 3. unload/reload Player 2 = bit 1
    );
echo$x;
  • DeBruijn Urutan:: frposition = 1 = P1 fires; rf= posisi 2 = P2 kebakaran,ff = posisi 3 = keduanya api
  • g<$m<=> f<$m[0]( f<$mselalu benar, karena ada karakter kedua).

0

Python, 200 byte

def war_game(turns):
    turn=0
    player1=True
    player2=True
    ammo1=False
    ammo2=False
    while turn<len(turns):
        if turns[turn][0]=='f' and ammo1==True and turns[turn][1]!='g':
            player2=False
        elif turns[turn][0]=='f' and turns[turn][1]=='g':
            ammo1=False
        elif turns[turn][0]=='r':
            ammo1=True
        if turns[turn][1]=='f' and ammo1==True and turns[turn][0]!='g':
            player1=False
        elif turns[turn][1]=='f' and turns[turn][0]=='g':
            ammo2=False            
        elif turns[turn][1]=='r':
            ammo2=True
        if player2==False or player1==False:
            break
        turn+=1
    if player1==True and player2==False:
        print('Player 1 wins')
        return 1
    elif player1==False and player2==True:
        print('Player 2 wins')
        return 2
    print('Draw')
    return 0

2
Selamat datang di situs ini. Kontes ini dicetak dalam jumlah byte sehingga saya akan merekomendasikan untuk memasukkan jumlah byte dalam judul Anda dan berusaha untuk menguranginya dengan mengurangi panjang nama-nama variabel. Anda juga harus memasukkan bahasa tempat Anda menulis ini (seperti Python3 bagi saya).
Posting Rock Garf Hunter

2
Seperti disebutkan di atas, ini adalah kompetisi yang dapat membuat program sekecil mungkin untuk menyelesaikan tugas. Anda menggunakan nama lengkap seperti turnsbukan hanya t, 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.
Carcigenicate

0

Clojure, 180 173 byte

(fn[t](loop[z nil x nil[[c v]& r]t](let[k #(and %3(= %\f)(not= %2\g))h #(and(not= %\f)(or %2(= %\r)))q(k v c x)w(k c v z)](cond(and q w)0 q 2 w 1 1(recur(h c z)(h v x)r)))))

-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.

(defn outcome [turns] ; Take input as ["rr" "ff"]
  (loop [p1-ammo? false ; Keep track of if each player has ammo
         p2-ammo? false
         [[p1-move p2-move] & rest-turns] turns] ; Deconstruct the turns out

    (let [killed? (fn [m m2 a] (and a (= m \f) (not= m2 \g))) ; Function that checks if one player killed the other
          has-ammo? (fn [m a] (and (not= m \f) (or a (= m \r)))) ; Function that decides if a player has ammo in the
                                                                 ;  next turn
          p1-killed? (killed? p2-move p1-move p2-ammo?) ; Check if each player was killed.
          p2-killed? (killed? p1-move p2-move p1-ammo?)]

      (cond ; Check who (if any) died. If no one died, recur to next turn.
        (and p1-killed? p2-killed?) 0
        p1-killed? 2
        p2-killed? 1
        :else (recur (has-ammo? p1-move p1-ammo?)
                     (has-ammo? p2-move p2-ammo?)
                     rest-turns)))))
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.