Symuluj „bitwę” w grze w karty do gry „Oorlog”

15

Zbudujmy symulację dla aspektu gry karcianej, którą osobiście znam pod holenderską nazwą „Oorlog” (tłumaczy się na „Wojna”).

Jak działa „Oorlog”?

Dwie talie kart (każda zawiera dwa Jokery) są równo podzielone między liczbę graczy. Każdy gracz tasuje swoje zasoby, kładzie je do góry nogami przed sobą, a wszyscy gracze otwierają jednocześnie pierwszą kartę zasobów.
Zwycięzca tej „bitwy” zależy od wartości kart według następujących zasad: Joker / As pokonuje króla; Król pokonuje królową; Królowa pokonuje Jacka; Jack pokonuje 10; 10 porażek 9; .... Ponadto 2 i 3 pokonują Asa / Jokera. Ostatnia reguła może prowadzić do cyklu, w którym 2 lub 3 bije Asa lub Jokera, Asa lub Jokera bije inną kartę, która z kolei bije 2 lub 3. W takim przypadku 2 lub 3 wygrywa bitwę.
(Kolor nie ma znaczenia w tej grze karcianej.)

Kiedy dwóch lub więcej graczy ma równe najwyższe karty, ma „wojnę”. Oznacza to, że kładą jedną kartę do góry nogami, a następnie każda z nich otwiera nową kartę ze swojego zasobu, ponownie szukając, kto ma najwyższą kartę. Trwa to dopóki jeden gracz nie wygra całej bitwy.
(Wszystkie karty z tej bitwy trafiają na stos kart odrzuconych gracza, który wygrał bitwę. Następnie wszyscy otwierają nową kartę. Gdy w zasobach gracza brakuje kart, odwracają stos kart odrzuconych do góry nogami i kontynuują grę z tym nowym zapasem. Trwa to do momentu, gdy graczowi zabraknie wszystkich swoich kart, a następnie gracz z największą liczbą kart wygrywa.)

Przykład „bitew” z trzema graczami:

  1. 4, 8, Jack:
    Jack wygrywa.
  2. 7, Ace, Queen:
    Ace wygrywa.
  3. 10, 10, King:
    King wygrywa.
  4. 3, Joker,
    wygrywa 2: 3.
  5. Ace, Joker,
    wygrywa 2: 2.
  6. 3, królowa, as:
    3 wygrane.
  7. Queen, Queen, 9:
    Queen & Queen prowadzą „wojnę”, dlatego kontynuują dwie nowe karty: 4, 8;
    8 wygranych.
  8. 4, 4, 4:
    Wszyscy mają „wojnę”, więc kontynuuje się z trzema nowymi kartami: 8, as, 2;
    2 wygrane.
  9. Jack, 5, Jack:
    Jack i Jack toczą „wojnę”, więc kontynuują dwie nowe karty: 5, 5;
    5 i 5 są również równe, więc „wojna” trwa ponownie z dwiema nowymi kartami: 10, król;
    Król wygrywa.
  10. Joker, Joker, Ace:
    Wszyscy mają „wojnę”, więc kontynuują z trzema nowymi kartami: 9, 7, 9;
    9 i 9 są równe, więc „wojna” trwa z dwiema nowymi kartami: Jack, 3;
    Jack wygrywa.

Przejdźmy więc do wyzwania kodu:

Wejście:

STDIN z tablicą lub ciągiem symulującym tablicę (twoje wywołanie - nawet jeśli twój język obsługuje tablice). Ta tablica zawiera karty bitwy w porządku chronologicznym (zobacz przypadki testowe, aby lepiej to zrozumieć).

Wynik:

STDOUT indeks gracza, który wygrał bitwę.
Można wybrać, czy chcesz indeksowane od zera (czyli 0, 1czy 2) lub jednej indeksowane wyjścia (czyli 1, 2, 3).

Zasady konkursu:

  • Wejście będzie pojedynczą tablicą / ciągiem reprezentującym tablicę. Więc nie możesz mieć tablicy tablic, aby to uprościć. Nie możesz też mieć przedmiotów zastępczych dla kart nieuczestniczących w wojnie.
  • W przypadku kart twarzy używamy notacji liczbowych zamiast notacji literowych. Ace / Joker = 1; Jack = 11; Królowa = 12; a król =13 .
  • W tym wyzwaniu możemy założyć, że zawsze gramy z 3 graczami .
  • Pierwsze trzy wskazują początek „bitwy”. Kiedy dwóch lub więcej graczy ma „wojnę”, kolejne karty w szeregu wskazują ich bitwę (zobacz przypadki testowe dla lepszego zrozumienia tego).

Główne zasady:

  • Jest to oznaczone , więc wygrywa najkrótsza odpowiedź w bajtach.
    Nie oznacza to, że języki nie-golfowe nie powinny wchodzić. Spróbuj znaleźć możliwie najkrótszą odpowiedź na kod-golf dla „każdego” języka programowania.
  • Proszę wspomnieć, które indeksowanie (zero lub jeden indeks) zostało użyte dla wyniku.

Przypadki testowe:

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)
Kevin Cruijssen
źródło
4
Angielska nazwa to rzeczywiście Wojna (minus jokery i minus zasada 2-i-3-beat-as).
Martin Ender
@MartinEnder również, gdy jest remis, obaj gracze odwracają 3 karty zakryte i 4 odkrytą. Czwarty decyduje o zwycięstwie w rundzie, a zakryte karty to „łupy wojenne”. Ponadto, czy gra nie trwa, dopóki jeden gracz nie ma wszystkich kart? Nie wiem, czy to była lokalna zasada, czy nie, ktoś jeszcze to pamięta? Tak pamiętam grę.
Magic Octopus Urn
1
@MagicOctopusUrn Pamiętam, że przewracałem stosy kart odrzuconych, aby kontynuować grę, dopóki jeden gracz nie będzie miał wszystkiego.
Kamil Drakari,
1
@KamilDrakari yeah! Tak też grałem. Dorastałem w tym stanie w Luizjanie.
Magic Octopus Urn
@MagicOctopusUrn Moje doświadczenie pochodzi z Minnesoty, a ponieważ mamy teraz 2 punkty danych, myślę, że można bezpiecznie powiedzieć, że cała Ameryka jest taka sama.
Kamil Drakari,

Odpowiedzi:

4

q - 142 znaki

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

Uwaga: zero indeksowane.

Nie ma pojęcia czytania stdin w q, więc powinieneś to nazwać jako funkcję: {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]

Właściwie to dość długo, ale jest wiele skrzynek narożnych. Utrzymuje listę aktywnych graczy i zużywa listę kart w pętli. Najbardziej problematyczną rzeczą jest wykrycie właściwego zwycięzcy w rękach, takich jak [13, 2, 3], ponieważ 3bije 2, jak zwykle, ale musiał zostać zduplikowany, aby umieścić go w skrzynce narożnej.

C. Quilley
źródło
3

JavaScript (ES6), 146 bajtów

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

Zwraca indeks zerowy. 127 bajtów, jeśli wolno mi zawrzeć wstępną ofertę jako osobną tablicę (działa to również dla dowolnej liczby rąk):

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)
Neil
źródło
0

Java 8, 257 bajtów

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, moje wyzwanie jest trudniejsze niż myślałem, że byłoby ze wszystkim w jednej takiej tablicy. ;) Ale ponieważ minęło więcej niż rok temu, odkąd opublikowałem to wyzwanie, sam postanowiłem spróbować. Zajęło mi to sporo czasu z wieloma obejściami i dziwactwami. Więc na pewno można trochę pograć w golfa, ale przyjrzę się temu innym razem. Trwało to już dłużej niż się spodziewałem.

Wyjaśnienie:

Wypróbuj tutaj.

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
Kevin Cruijssen
źródło