Simula una "battaglia" nel gioco di carte da gioco "Oorlog"


15

Costruiamo una simulazione per un aspetto del gioco di carte, che conosco personalmente con il nome olandese "Oorlog" (tradotto in "Guerra").

Come funziona 'Oorlog'?

Due mazzi di carte (ciascuno con due jolly) sono equamente divisi tra il numero di giocatori che giocano. Ogni giocatore mescola il proprio mazzo, lo mette a testa in giù davanti a sé e tutti i giocatori aprono contemporaneamente la prima carta del mazzo.
Il vincitore di quella "battaglia" è determinato dai valori delle carte che seguono queste regole: Joker / Ace sconfigge King; Il re sconfigge la regina; La regina sconfigge Jack; Jack sconfigge 10; 10 sconfitte 9; .... Inoltre, sia 2 che 3 sconfiggono Ace / Joker. L'ultima regola può portare a un ciclo in cui 2 o 3 battiti Asso o Joker, Asso o Joker batte un'altra carta, che a sua volta batte il 2 o 3. In questo caso, il 2 o 3 vince la battaglia.
(Il seme è irrilevante in questo gioco di carte.)

Quando due o più giocatori hanno le stesse carte più alte, hanno una "guerra". Ciò significa che mettono una carta a testa in giù, e ognuna apre una nuova carta dal proprio mazzo, cercando di nuovo chi ha la carta più alta. Questo continua fino a quando un singolo giocatore vince l'intera battaglia.
(Tutte le carte di quella battaglia vanno nella pila degli scarti del giocatore che ha vinto la battaglia. Quindi tutti aprono una nuova carta. Quando il mazzo di un giocatore ha esaurito le carte, capovolgono la pila degli scarti e continuano con questo nuovo mazzo. Questo continua fino a quando un giocatore ha esaurito tutte le sue carte e poi vince il giocatore con il maggior numero di carte.)

Esempio di "battaglie" con tre giocatori:

  1. 4, 8, Jack:
    Jack vince.
  2. 7, Ace, Queen:
    Ace vince.
  3. 10, 10, re:
    vince il re.
  4. 3, Joker,
    vince 2: 3.
  5. Asso, Joker,
    vince 2: 2.
  6. 3, regina, asso:
    3 vittorie.
  7. Queen, Queen, 9:
    Queen & Queen stanno avendo una "guerra", quindi continua con due nuove carte: 4, 8;
    8 vittorie.
  8. 4, 4, 4:
    tutti hanno una "guerra", quindi continua con tre nuove carte: 8, Asso, 2;
    2 vittorie.
  9. Jack, 5, Jack:
    Jack e Jack hanno una "guerra", quindi continua con due nuove carte: 5, 5;
    Anche 5 e 5 sono uguali, quindi la 'guerra' continua ancora con due nuove carte: 10, Re;
    Il re vince.
  10. Joker, Joker, Ace:
    tutti hanno una "guerra", quindi continua con tre nuove carte: 9, 7, 9;
    Anche 9 e 9 sono uguali, quindi la "guerra" continua con due nuove carte: Jack, 3;
    Jack vince.

Quindi, sulla sfida del codice:

Ingresso:

STDIN con un array o una stringa che simula un array (la tua chiamata, anche se la tua lingua supporta gli array). Questa matrice contiene le carte di una battaglia in ordine cronologico (vedere i casi di prova per una comprensione più chiara di ciò).

Produzione:

STDOUT l'indice del giocatore che ha vinto la battaglia.
È possibile scegliere se si desidera uno zero-indicizzato (cioè 0, 1o 2) o uno-indicizzato uscita (cioè 1, 2, 3).

Regole della sfida:

  • L'input sarà un singolo array / stringa che rappresenta un array. Quindi non è possibile disporre di una serie di array per semplificarlo. Inoltre non puoi avere oggetti surrogati per le carte che non partecipano alla guerra.
  • Usiamo le notazioni numeriche per le figure invece delle lettere. Quindi Ace / Joker = 1; Jack = 11; Regina = 12; e re = 13.
  • In questa sfida possiamo presumere che stiamo sempre giocando con 3 giocatori .
  • I primi tre indicano l'inizio della "battaglia". Quando due o più giocatori hanno una "guerra", le carte continue nell'array indicano la loro battaglia (vedi i casi di prova per una comprensione più chiara di ciò).

Regole generali:

  • Questo è contrassegnato come , quindi vince la risposta più breve in byte.
    Ciò non significa che le lingue non di golf non debbano entrare. Prova a trovare una risposta il più breve possibile al code-golf per "ogni" linguaggio di programmazione.
  • Indica quale indicizzazione (zero o uno indicizzato) hai utilizzato per l'output.

Casi test:

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
Il nome inglese è davvero War (meno i jolly e meno la regola del 2 e 3 battito-asso).
Martin Ender,

@MartinEnder inoltre, quando c'è un pareggio, entrambi i giocatori lanciano 3 carte coperte e una 4 a faccia in su. Il 4 ° decide il vincitore del round e le carte coperte sono il "bottino di guerra". Inoltre, il gioco continua fino a quando 1 giocatore non ha tutte le carte? Non so se questa era una regola locale o no, qualcun altro lo ricorda? È così che mi ricordo di aver giocato.
Magic Octopus Urn,

1
@MagicOctopusUrn Ricordo di aver girato le pile degli scarti per continuare a giocare fino a quando un giocatore non avesse avuto tutto.
Kamil Drakari,

1
@KamilDrakari yeah! È così che ho giocato anche io. Ero in Louisiana da grande.
Magic Octopus Urn,

@MagicOctopusUrn La mia esperienza è del Minnesota, e dato che ora abbiamo 2 punti dati, penso che sia sicuro dire che tutta l'America è la stessa.
Kamil Drakari,

Risposte:


4

q - 142 caratteri

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

Nota: zero indicizzato.

Non c'è idea di leggere lo stdin in q, quindi dovresti chiamarlo come una funzione: {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]

Abbastanza lungo, in realtà, ma ci sono molti casi angolari. Mantiene un elenco di giocatori attivi e consuma l'elenco delle carte in un ciclo. La cosa più problematica è individuare il vincitore corretto nelle mani come [13, 2, 3], dal momento che i 3battiti 2, come di consueto, ma ha dovuto essere duplicato per essere messo nella custodia ad angolo.


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

Restituisce un indice in base zero. 127 byte se mi è concesso il contratto iniziale come un array separato (questo funziona anche per un numero arbitrario di mani ovviamente):

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, la mia sfida è più difficile di quanto pensassi sarebbe con tutto in un singolo array come quello. ;) Ma dato che è stato più di me un anno fa da quando ho pubblicato questa sfida, ho deciso di provarlo io stesso. Mi ci è voluto un bel po 'con più soluzioni e stranezze. Quindi si può sicuramente giocare ancora un po' a golf, ma lo esaminerò un'altra volta. Questo ha già richiesto molto più tempo di quanto mi aspettassi ...

Spiegazione:

Provalo qui.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.