Simule una 'batalla' en el juego de cartas 'Oorlog'

15

Construyamos una simulación para un aspecto del juego de cartas, que personalmente conozco por el nombre holandés 'Oorlog' (se traduce como 'Guerra').

¿Cómo funciona 'Oorlog'?

Dos barajas de cartas (cada una con dos comodines) se dividen en partes iguales entre la cantidad de jugadores que juegan. Cada jugador baraja su propio stock, lo pone boca abajo frente a ellos, y todos los jugadores abren la primera carta del stock al mismo tiempo.
El ganador de esa 'batalla' está determinado por los valores de las cartas siguiendo estas reglas: Joker / Ace derrota a King; King derrota a Queen; Queen derrota a Jack; Jack derrota a 10; 10 derrotas 9; .... Además, 2 y 3 derrotan a Ace / Joker. La última regla puede conducir a un ciclo donde 2 o 3 vence a As o Joker, Ace o Joker vence a otra carta, que a su vez vence a 2 o 3. En este caso, el 2 o 3 gana la batalla.
(El traje es irrelevante en este juego de cartas).

Cuando dos o más jugadores tienen las mismas cartas más altas, tienen una 'guerra'. Esto significa que ponen una carta al revés, y luego cada una abre una nueva carta de su stock, nuevamente buscando quién tiene la carta más alta. Esto continúa hasta que un solo jugador gana la batalla completa.
(Todas las cartas de esa batalla van a la pila de descarte del jugador que ganó la batalla. Luego, todos abren una nueva carta. Cuando las existencias de un jugador se quedan sin cartas, dan la vuelta a su pila de descarte y continúan con esta nueva cantidad. Esto continúa hasta que un jugador se quede sin todas sus cartas y luego gane el jugador con la mayor cantidad de cartas).

Ejemplo de 'batallas' con tres jugadores:

  1. 4, 8, Jack:
    Jack gana.
  2. 7, Ace, Reina:
    Ace gana.
  3. 10, 10, Rey: el
    Rey gana.
  4. 3, Joker, 2:
    3 victorias.
  5. Ace, Joker, 2:
    2 victorias.
  6. 3, Reina, As:
    3 victorias.
  7. Reina, Reina, 9:
    Reina y Reina están teniendo una 'guerra', por lo que continúa con dos cartas nuevas: 4, 8;
    8 victorias.
  8. 4, 4, 4:
    Todos están teniendo una 'guerra', por lo que continúa con tres cartas nuevas: 8, As, 2;
    2 victorias.
  9. Jack, 5, Jack:
    Jack y Jack están teniendo una 'guerra', por lo que continúa con dos cartas nuevas: 5, 5;
    5 y 5 también son iguales, por lo que la 'guerra' continúa nuevamente con dos cartas nuevas: 10, Rey;
    El rey gana.
  10. Joker, Joker, Ace:
    Todos están teniendo una 'guerra', por lo que continúa con tres cartas nuevas: 9, 7, 9;
    9 y 9 también son iguales, por lo que la 'guerra' continúa con dos cartas nuevas: Jack, 3;
    Jack gana.

Entonces, sobre el desafío del código:

Entrada:

STDIN con una matriz o una cadena que simula una matriz (su llamada, incluso si su idioma admite matrices). Este conjunto contiene las cartas de una batalla en orden cronológico (ver casos de prueba para una comprensión más clara de esto).

Salida:

STDOUT el índice del jugador que ganó la batalla.
Puede elegir si desea un indexados a cero (es decir 0, 1o 2) o uno indexada salida (es decir 1, 2, 3).

Reglas de desafío:

  • La entrada será una sola matriz / cadena que representa una matriz. Por lo tanto, no puede tener una matriz de matrices para simplificarlo. Tampoco puedes tener objetos sustitutos para cartas que no participan en la guerra.
  • Usamos anotaciones numéricas para las tarjetas de presentación en lugar de las letras. Entonces Ace / Joker = 1; Jack = 11; Reina = 12; y rey ​​= 13.
  • En este desafío, podemos asumir que siempre estamos jugando con 3 jugadores .
  • Los tres primeros indican el inicio de la 'batalla'. Cuando dos o más jugadores tienen una 'guerra', las cartas continuas en la matriz indican su batalla (ver casos de prueba para una comprensión más clara de esto).

Reglas generales:

  • Esto está etiquetado como , por lo que la respuesta más corta en bytes gana.
    Esto no significa que no deberían ingresar idiomas que no sean de código de golf. Trate de encontrar una respuesta de código de golf lo más breve posible para "cada" lenguaje de programación.
  • Mencione qué indexación (cero o uno indexado) ha utilizado para la salida.

Casos de prueba:

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
fuente
44
El nombre en inglés es de hecho Guerra (menos los comodines y menos la regla de 2 y 3 golpes).
Martin Ender
@MartinEnder también, cuando hay un empate, ambos jugadores voltean 3 cartas boca abajo y una cuarta boca arriba. El 4º decide el ganador de la ronda, y las cartas boca abajo son el "botín de guerra". Además, ¿el juego no continúa hasta que 1 jugador tenga todas las cartas? No sé si esto era una regla local o no, ¿alguien más recuerda esto? Así es como recuerdo haber jugado.
Urna mágica de pulpo
1
@MagicOctopusUrn Recuerdo que volteé las pilas de descartes para seguir jugando hasta que un jugador lo tuvo todo.
Kamil Drakari
1
@KamilDrakari, sí! Así jugué yo también. Estuve en Louisiana creciendo jugando esto.
Magic Octopus Urn
@MagicOctopusUrn Mi experiencia es de Minnesota, y dado que ahora tenemos 2 puntos de datos, creo que es seguro decir que todo Estados Unidos es igual.
Kamil Drakari

Respuestas:

4

q - 142 caracteres

{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: cero indexado.

No hay una noción de lectura de stdin en q, por lo que debe llamarlo como una función: {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]

Bastante largo, en realidad, pero hay muchos casos de esquina. Mantiene una lista de jugadores activos y consume la lista de cartas en un bucle. Lo más problemático es detectar al ganador correcto en manos como [13, 2, 3], desde 3latidos 2, como es normal, pero tuvo que duplicarse para colocarse en la esquina.

C. Quilley
fuente
3

JavaScript (ES6), 146 bytes

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

Devuelve un índice basado en cero. 127 bytes si se me permite el acuerdo inicial como una matriz separada (esto también funciona para un número arbitrario de manos, por supuesto):

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
fuente
0

Java 8, 257 bytes

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, mi desafío es más difícil de lo que pensé que sería con todo en una sola matriz como esa. ;) Pero como hace más de un año que publiqué este desafío, decidí probarlo yo mismo. Me tomó bastante tiempo con múltiples soluciones y caprichos ... Así que definitivamente se puede jugar un poco más, pero lo investigaré en otra ocasión. Esto ya tomó mucho más tiempo de lo que esperaba ...

Explicación:

Pruébalo aquí.

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
fuente