Oyun kağıdı oyunu 'Oorlog'da bir' savaş 'simülasyonu yapın


15

Kart oyununda kişisel olarak Hollandalı 'Oorlog' adıyla bildiğim bir yön için bir simülasyon oluşturalım ('Savaş' anlamına gelir).

'Oorlog' nasıl çalışır?

İki deste kart (her biri iki Joker dahil) oynayan oyuncu sayısı arasında eşit olarak bölünür. Her oyuncu kendi stokunu karıştırır, önlerine baş aşağı koyar ve tüm oyuncular aynı anda stokun ilk kartını açar.
Bu 'savaşı' kazanan, aşağıdaki kurallara göre kartların değerleri ile belirlenir: Joker / Ace King'i yener; Kral Kraliçeyi yener; Kraliçe Jack'i yener; Jack 10'u yendi; 10 yenilgi 9; .... Buna ek olarak, hem 2 hem de 3 Ace / Joker'i yendi. Son kural, 2 veya 3'ün Ace veya Joker'i, Ace veya Joker'in başka bir kartı geçtiği ve bunun da 2 veya 3'ü geçtiği bir döngüye yol açabilir. Bu durumda, 2 veya 3 savaşı kazanır.
(Bu kart oyununda uygun değil.)

İki veya daha fazla oyuncu eşit en yüksek karta sahip olduğunda, bir 'savaş'a sahiptir. Bu, bir kartı baş aşağı yerleştirdikleri anlamına gelir ve her biri stoklarından yeni bir kart açar ve yine en yüksek karta sahip olanı görür. Bu, tek bir oyuncu tüm savaşı kazanana kadar devam eder.
(Bu savaşın tüm kartları savaşı kazanan oyuncunun atma yığınına gider. Sonra herkes yeni bir kart açar. Bir oyuncunun stoğu kartların dışında kaldığında, atma yığınlarını baş aşağı çevirir ve bu yeni stoğa devam ederler. Bu, bir oyuncu tüm kartlarından çıkana ve daha fazla kart alan oyuncu kazanana kadar devam eder.)

Üç oyuncu ile 'savaşlar' örneği:

  1. 4, 8, Jack:
    Jack kazanır.
  2. 7, As, Kraliçe:
    Ace kazanır.
  3. 10, 10, Kral:
    Kral kazanır.
  4. 3, Joker, 2:
    3 kazanır.
  5. Ace, Joker, 2:
    2 kazanır.
  6. 3, Kraliçe, As:
    3 galibiyet.
  7. Kraliçe, Kraliçe, 9:
    Kraliçe ve Kraliçe bir 'savaş' yaşıyor, bu yüzden iki yeni kartla devam ediyor: 4, 8;
    8 kazanç.
  8. 4, 4, 4:
    Herkesin bir 'savaşı' var, bu yüzden üç yeni kartla devam ediyor: 8, As, 2;
    2 galibiyet.
  9. Jack, 5, Jack:
    Jack ve Jack bir 'savaş' yaşıyor, bu yüzden iki yeni kartla devam ediyor: 5, 5;
    5 & ​​5 de eşittir, bu yüzden 'savaş' iki yeni kartla tekrar devam eder: 10, King;
    Kral kazanır.
  10. Joker, Joker, Ace:
    Hepsinde bir 'savaş' var, bu yüzden üç yeni kartla devam ediyor: 9, 7, 9;
    9 ve 9 da eşittir, bu yüzden 'savaş' iki yeni kartla devam eder: Jack, 3;
    Jack kazanır.

Kod meydan okuma üzerine:

Giriş:

Bir diziyle STDIN veya bir diziyi simüle eden bir dize (çağrınız - diliniz dizileri desteklese bile). Bu dizi, bir savaşın kartlarını kronolojik sırayla içerir (bunun daha iyi anlaşılması için test durumlarına bakın).

Çıktı:

STDOUT savaşı kazanan oyuncunun endeksidir.
İstediğin seçebilirsiniz sıfır endeksli (yani 0, 1ya 2) ya da tek endeksli çıktı (yani 1, 2,3 ).

Zorluk kuralları:

  • Giriş, bir diziyi temsil eden tek bir dizi / dize olacaktır. Yani basitleştirmek için bir dizi diziniz olamaz. Ayrıca savaşa katılmayan kartlar için vekil eşyalarınız olamaz.
  • Yüz kartları için harf gösterimi yerine sayı gösterimlerini kullanıyoruz. Yani Ace / Joker = 1; Jack = 11; Kraliçe = 12; ve Kral = 13.
  • Bu mücadelede her zaman 3 oyuncu ile oynadığımızı varsayabiliriz .
  • İlk üçü 'savaşın' başladığını gösterir. İki veya daha fazla oyuncu 'savaş' olduğunda dizideki devam eden kartlar savaşlarını gösterir (bunun daha iyi anlaşılması için test senaryolarına bakın).

Genel kurallar:

  • Bu etiketli , bayt en kısa cevap kazanır.
    Bu kodsuz golf dillerinin girmemesi gerektiği anlamına gelmez. 'Her' programlama dili için mümkün olduğunca kısa bir kod-golf cevabı bulmaya çalışın.
  • Lütfen çıktı için hangi dizin oluşturmayı (sıfır veya tek dizinli) kullandığınızı belirtin.

Test senaryoları:

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
İngilizce adı gerçekten de Savaş (eksi joker ve eksi 2-ve-3-beat-ace kuralı).
Martin Ender

@MartinEnder, berabere kaldığında, her iki oyuncu da 3 kart kapalı ve 4 kart açık olarak gelir. Dördüncü turun galibi karar verir ve yüzü aşağı dönük kartlar "savaş ganimetleri" dir. Ayrıca, 1 oyuncu tüm kartları alana kadar oyun devam etmiyor mu? Bunun yerel bir kural olup olmadığını bilmiyorum, bunu hatırlayan var mı? Bu şekilde oynadığımı hatırlıyorum.
Sihirli Ahtapot Urn

1
@MagicOctopusUrn Bir oyuncunun hepsine sahip olana kadar oynamaya devam etmek için ıskarta yığınlarını ters çevirdiğimi hatırlıyorum.
Kamil Drakari

1
@KamilDrakari evet! Ben de böyle oynadım. Louisiana'daydım bunu oynarken büyüyordum.
Sihirli Ahtapot Urn

@MagicOctopusUrn Deneyimlerim Minnesota'dan ve şimdi 2 veri noktamız olduğundan, tüm Amerika'nın aynı olduğunu söylemenin güvenli olduğunu düşünüyorum.
Kamil Drakari

Yanıtlar:


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}

Not: sıfır endeksli.

Q'da stdin okuma nosyonu yoktur, bu yüzden onu bir işlev olarak çağırmalısınız: {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]

Aslında oldukça uzun, ama birçok köşe vakası var. Aktif oyuncu listesini tutar ve bir döngüdeki kartların listesini tüketir. En sorunlu şey gibi elinde doğru galibi tespit etmektir [13, 2, 3], çünkü 3atım 2normal, ama köşe durumda konması için çoğaltılabilir gerekiyordu.


3

JavaScript (ES6), 146 bayt

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

Sıfır tabanlı bir dizin döndürür. Ayrı bir dizi olarak ilk anlaşmaya izin verirsem 127 bayt (bu da elbette keyfi sayıda el için çalışır):

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 bayt

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;}

Tamam, benim zorluğum böyle tek bir dizide her şey olacağını düşündüğümden daha zor. ;) Ama bu meydan okumayı yayınladığımdan bu yana bir yıldan uzun bir süre önce olduğundan, kendim bir denemeye karar verdim. Birden fazla çalışma ve tuhaflıklar ile oldukça uzun bir süre aldı .. Bu yüzden kesinlikle biraz daha golf olabilir, ama başka bir zaman içine bakacağım. Bu beklediğimden çok daha uzun sürdü.

Açıklama:

Burada deneyin.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.