Simulasikan 'pertempuran' di permainan kartu permainan 'Oorlog'


15

Mari kita membangun simulasi untuk aspek dalam permainan kartu, yang secara pribadi saya kenal dengan nama Belanda 'Oorlog' (diterjemahkan menjadi 'Perang').

Bagaimana cara kerja 'Oorlog'?

Dua deck kartu (masing-masing termasuk dua Jokers) dibagi rata antara jumlah pemain yang bermain. Setiap pemain mengocok stok mereka sendiri, meletakkannya terbalik di depan mereka, dan semua pemain membuka kartu stok pertama secara bersamaan.
Pemenang dari 'pertempuran' itu ditentukan oleh nilai-nilai kartu yang mengikuti aturan-aturan ini: Joker / Ace mengalahkan King; Raja mengalahkan Ratu; Ratu mengalahkan Jack; Jack mengalahkan 10; 10 kekalahan 9; .... Selain itu, kedua 2 dan 3 mengalahkan Ace / Joker. Aturan terakhir dapat menyebabkan siklus di mana 2 atau 3 mengalahkan Ace atau Joker, Ace atau Joker mengalahkan beberapa kartu lain, yang pada akhirnya mengalahkan 2 atau 3. Dalam hal ini, 2 atau 3 memenangkan pertempuran.
(Suit tidak relevan dalam permainan kartu ini.)

Ketika dua atau lebih pemain memiliki kartu tertinggi yang sama, mereka memiliki 'perang'. Ini berarti mereka meletakkan satu kartu secara terbalik, dan kemudian masing-masing membuka kartu baru dari stok mereka, lagi-lagi mencari siapa yang memiliki kartu tertinggi. Ini berlanjut sampai satu pemain memenangkan seluruh pertempuran.
(Semua kartu dari pertarungan itu pergi ke tumpukan kartu pemain yang memenangkan pertarungan. Lalu semua orang membuka kartu baru. Ketika stok pemain kehabisan kartu, mereka membalik tumpukan kartu buangan mereka terbalik dan melanjutkan dengan stok baru ini. Ini berlanjut sampai seorang pemain keluar dari semua kartunya dan kemudian pemain dengan jumlah kartu terbanyak menang.)

Contoh 'pertempuran' dengan tiga pemain:

  1. 4, 8, Jack:
    Jack menang.
  2. 7, Ace, Queen:
    Ace menang.
  3. 10, 10, Raja:
    Raja menang.
  4. 3, Joker, 2:
    3 menang.
  5. Ace, Joker, 2:
    2 menang.
  6. 3, Queen, Ace:
    3 menang.
  7. Ratu, Ratu, 9:
    Ratu & Ratu sedang mengalami 'perang', jadi itu berlanjut dengan dua kartu baru: 4, 8;
    8 menang.
  8. 4, 4, 4:
    Semua mengalami 'perang', jadi itu berlanjut dengan tiga kartu baru: 8, Ace, 2;
    2 menang.
  9. Jack, 5, Jack:
    Jack & Jack mengalami 'perang', jadi ia melanjutkan dengan dua kartu baru: 5, 5;
    5 & ​​5 juga sama, sehingga 'perang' berlanjut lagi dengan dua kartu baru: 10, King;
    Raja menang.
  10. Joker, Joker, Ace:
    Semua mengalami 'perang', jadi ia melanjutkan dengan tiga kartu baru: 9, 7, 9;
    9 & 9 juga sama, sehingga 'perang' berlanjut dengan dua kartu baru: Jack, 3;
    Jack menang.

Jadi, ke tantangan kode:

Memasukkan:

STDIN dengan array, atau string yang mensimulasikan array (panggilan Anda - bahkan jika bahasa Anda mendukung array). Larik ini berisi kartu pertempuran dalam urutan kronologis (lihat kasus uji untuk pemahaman yang lebih jelas tentang ini).

Keluaran:

STDOUT indeks pemain yang memenangkan pertempuran.
Anda dapat memilih apakah Anda ingin nol-diindeks (yaitu 0, 1, atau 2) atau satu-diindeks keluaran (yaitu 1, 2, 3).

Aturan tantangan:

  • Input akan berupa array / string tunggal yang mewakili array. Jadi, Anda tidak dapat memiliki array array untuk menyederhanakannya. Anda juga tidak dapat memiliki barang pengganti untuk kartu yang tidak berpartisipasi dalam perang.
  • Kami menggunakan notasi angka untuk kartu wajah alih-alih notasi huruf. Jadi Ace / Joker = 1; Jack = 11; Ratu = 12; dan Raja = 13.
  • Dalam tantangan ini kita dapat menganggap kita selalu bermain dengan 3 pemain .
  • Tiga yang pertama menunjukkan awal dari 'pertempuran'. Ketika dua atau lebih pemain memiliki 'perang', kartu yang berlanjut dalam array menunjukkan pertempuran mereka (lihat uji kasus untuk pemahaman yang lebih jelas tentang ini).

Aturan umum:

  • Ini ditandai dengan , jadi jawaban tersingkat dalam byte menang.
    Ini tidak berarti bahasa bukan kode golf tidak boleh dimasukkan. Cobalah untuk memberikan jawaban kode-golf sesingkat mungkin untuk bahasa pemrograman 'setiap'.
  • Harap sebutkan pengindeksan mana (nol atau satu indeks) yang Anda gunakan untuk output.

Kasus uji:

Test case 1:  [4, 8, 11]                 ->  2 (or 3)
Test case 2:  [7, 1, 12]                 ->  1 (or 2)
Test case 3:  [10, 10, 13]               ->  2 (or 3)
Test case 4:  [3, 1, 2]                  ->  0 (or 1)
Test case 5:  [1, 1, 2]                  ->  2 (or 3)
Test case 6:  [3, 12, 1]                 ->  0 (or 1)
Test case 7:  [12, 12, 9, 4, 8]          ->  1 (or 2)
Test case 8:  [4, 4, 4, 8, 1, 2]         ->  2 (or 3)
Test case 9:  [11, 5, 11, 5, 5, 10, 13]  ->  2 (or 3)
Test case 10: [1, 1, 1, 9, 7, 9, 11, 3]  ->  0 (or 1)
Test case 11: [13, 13, 4, 1, 3]          ->  1 (or 2)
Test case 12: [13, 4, 13, 2, 3]          ->  2 (or 3)

4
Nama Inggris memang Perang (minus pelawak dan minus aturan 2-dan-3-beat-ace).
Martin Ender

@ Martin juga, ketika ada dasi, kedua pemain membalik 3 kartu menghadap ke bawah, dan ke-4 menghadap ke atas. Yang ke-4 menentukan pemenang putaran, dan kartu tertutup adalah "rampasan perang". Juga, bukankah permainan terus berjalan sampai 1 pemain memiliki semua kartu? Saya tidak tahu apakah ini peraturan lokal atau tidak, ada yang ingat ini? Begitulah cara saya ingat bermain.
Magic Octopus Mm

1
@MagicOctopusUrn Saya ingat membalik tumpukan yang dibuang untuk terus bermain sampai satu pemain memiliki semuanya.
Kamil Drakari

1
@ KamilDrakari ya! Itulah cara saya bermain juga. Saya berada di Louisiana tumbuh dengan memainkan ini.
Magic Octopus Mm

@ MagicOctopusUrn Pengalaman saya dari Minnesota, dan karena sekarang kita memiliki 2 titik data, saya pikir aman untuk mengatakan bahwa semua Amerika adalah sama.
Kamil Drakari

Jawaban:


4

q - 142 karakter

{p:til 3;while[1<(#:)p;h:(n:(#:)p)#x;x:n _x;$[1~min h;p:$[max a:h in(2;3);$[1<(#:)(?:)h(&:)a;p(&:)h=3;p(&:)a];p(&:)h=1];p:p(&:)h=max h]];(*:)p}

Catatan: nol diindeks.

Tidak ada gagasan membaca stdin di q, jadi Anda harus menyebutnya sebagai fungsi: {p:til 3;while[1<(#:)p;h:(n:(#:)p)#x;x:n _x;$[1~min h;p:$[max a:h in(2;3);$[1<(#:)(?:)h(&:)a;p(&:)h=3;p(&:)a];p(&:)h=1];p:p(&:)h=max h]];(*:)p}[1,2,3]

Sebenarnya cukup panjang, tetapi ada banyak kotak sudut. Itu membuat daftar pemain aktif, dan mengkonsumsi daftar kartu dalam satu lingkaran. Yang paling bermasalah adalah mendeteksi pemenang yang tepat di tangan seperti [13, 2, 3], karena 3ketukan 2, seperti biasa, tetapi harus diduplikasi untuk dimasukkan ke dalam kasing sudut.


3

JavaScript (ES6), 146 byte

f=a=>(b=a.splice(0,3)).filter(m=>m-n,n=Math.max(...b.includes(1)?b.filter(m=>m<4):b)).length>1?b.indexOf(n):f([...b.map(m=>m-n?0:a.shift()),...a])

Mengembalikan indeks berbasis nol. 127 byte jika saya mengizinkan transaksi awal sebagai array terpisah (ini juga berfungsi untuk sejumlah tangan yang sewenang-wenang):

f=(b,a)=>b.filter(m=>m==n,n=Math.max(...b.includes(1)?b.filter(m=>m<4):b)).length<2?b.indexOf(n):f(b.map(m=>m-n?0:a.shift()),a)

0

Java 8, 257 byte

int c(int[]a){int t=0,f=0,q,r=0,i=-1,l=a.length,x[];for(;++i<3;t=a[i]>t?a[r=i]:t)a[i]+=a[i]==1?f++*0+13:0;for(;i-->0;t=f>0&a[i]<4?t!=3?a[r=i]:t>a[i]?a[r=i]:t:t);for(f=-1,x=new int[q=l<7?3:l>7?l-3:5];l>3&++i<q;)x[i]=t==a[i]|i>2?a[++f+3]:0;return l>3?c(x):r;}

Ok, tantangan saya lebih sulit daripada yang saya kira dengan segala sesuatu dalam satu array seperti itu. ;) Tapi karena sudah lebih dari saya setahun yang lalu sejak saya memposting tantangan ini, saya memutuskan untuk mencobanya sendiri. Butuh waktu cukup lama untuk saya dengan beberapa work-arounds dan quirks .. Jadi pasti bisa bermain golf lagi, tapi saya akan melihat ke lain waktu. Ini sudah memakan waktu lebih lama dari yang saya harapkan ..

Penjelasan:

Coba di sini.

int c(int[]a){      // Method with integer-array parameter and integer return-type
  int t=0,f=0,q,    //  Temp integers
      r=0,          //  Result-integer
      i=-1,         //  Index-integer
      l=a.length,   //  Length of the input-array
      x[];          //  Temp array we use when there is a war
  for(;++i<3;       //  Loop (1) from 0 to 3 (exclusive)
      t=            //    After every iteration, change `t` to:
        a[i]>t?     //     If the current item is larger than `t`:
         a[r=i]     //      Use the current item (and save its index in `r`)
        :           //     Else:
         t)         //      Leave `t` the same
    a[i]+=a[i]==1?  //   If the current item is a 1 (Ace/Joker):
         f++*0      //    Increase `f` by 1,
         +13        //    and change the 1 to 14 (by increasing with 13)
        :           //   Else:
         0;         //    Leave the current item the same (by increasing with 0)
                    //  End of loop (1) (implicit / single-line body)
  for(;i-->0;       //  Loop from 2 down to 0 (inclusive)
    t=f>0&a[i]<4?   //   If a Joker/Ace was present, and the current item is 2 or 3:
       t!=3?        //    And if it's not a 3 (so either 2 or 14)
        a[r=i]      //     Change `t` to the current item (and save its index in `r`)
       :t>a[i]?     //    Else-if the current item is 2, and `t` is a Joker/Ace:
        a[r=i]      //     Change `t` to the current item (and save its index in `r`
       :            //    Else:
        t           //     Leave `t` the same
      :             //   Else:
       t            //    Leave `t` the same
  );                //  End of loop (2)
  for(f=-1,         //  Reset `f` to -1
      x=new int[    //  Create the temp array `x` with length:
       q=l<7?       //   If the current length is 6 or lower:
          3         //    New length after war is 3
         :l>7?      //   Else-if the current length is 8 or higher:
          l-3       //    New length after war is current length - 3
         :          //   Else(-if current length is 7)
          5];       //    New length after war is 5
      l>3&          //  If there is a war:
          ++i<q;)   //   Loop (3) from 0 to the new length (exclusive)
    x[i]=t==a[i]    //    If the current item is at war,
         |i>2?      //    or the current item is after the first 3 items:
          a[++f+3]  //     Fill the new array with the correct next item
         :          //    Else:
          0;        //     Fill the item of the new array with 0
                    //     (since it won't participate in the next round)
                    //   End of loop (3)
  return l>3?       //  If there was a war:
          c(x)      //   Recursive-call with the new array
         :          //  Else:
          r;        //   Return the index of the card that won
}                   // End of method
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.