Simulez une «bataille» dans le jeu de cartes à jouer «Oorlog»

15

Construisons une simulation pour un aspect du jeu de cartes, que je connais personnellement sous le nom néerlandais 'Oorlog' (qui se traduit par 'War').

Comment fonctionne 'Oorlog'?

Deux jeux de cartes (comprenant chacun deux Jokers) sont également répartis entre le nombre de joueurs jouant. Chaque joueur mélange son propre stock, le place à l'envers devant lui, et tous les joueurs ouvrent la première carte du stock en même temps.
Le vainqueur de cette «bataille» est déterminé par les valeurs des cartes suivant ces règles: Joker / Ace bat King; Le roi bat la reine; La reine bat Jack; Jack bat 10; 10 défaites 9; .... De plus, les 2 et 3 battent Ace / Joker. La dernière règle peut conduire à un cycle où 2 ou 3 bat Ace ou Joker, Ace ou Joker bat une autre carte, qui à son tour bat 2 ou 3. Dans ce cas, le 2 ou 3 gagne la bataille.
(Le costume n'est pas pertinent dans ce jeu de cartes.)

Lorsque deux joueurs ou plus ont les cartes les plus élevées égales, ils ont une «guerre». Cela signifie qu'ils mettent une carte à l'envers, puis chacun ouvre une nouvelle carte de leur stock, recherchant à nouveau qui a la carte la plus élevée. Cela continue jusqu'à ce qu'un seul joueur remporte la bataille entière.
(Toutes les cartes de cette bataille vont dans la pile de défausse du joueur qui a gagné la bataille. Ensuite, tout le monde ouvre une nouvelle carte. Lorsque le stock d'un joueur n'a plus de cartes, il retourne sa pile de défausse et continue avec ce nouveau stock. Cela continue jusqu'à ce qu'un joueur ait épuisé toutes ses cartes, puis le joueur avec le plus grand nombre de cartes gagne.)

Exemple de «batailles» avec trois joueurs:

  1. 4, 8, Jack:
    Jack gagne.
  2. 7, Ace, Queen:
    Ace gagne.
  3. 10, 10, King:
    King gagne.
  4. 3, Joker, 2:
    3 victoires.
  5. Ace, Joker, 2:
    2 gagne.
  6. 3, Queen, Ace:
    3 victoires.
  7. Queen, Queen, 9:
    Queen & Queen ont une «guerre», elle continue donc avec deux nouvelles cartes: 4, 8;
    8 victoires.
  8. 4, 4, 4:
    Tous mènent une «guerre», donc cela continue avec trois nouvelles cartes: 8, Ace, 2;
    2 victoires.
  9. Jack, 5, Jack:
    Jack et Jack ont ​​une «guerre», donc ça continue avec deux nouvelles cartes: 5, 5;
    5 et 5 sont également égaux, la «guerre» continue donc avec deux nouvelles cartes: 10, King;
    Le roi gagne.
  10. Joker, Joker, Ace:
    Tous ont une «guerre», donc ça continue avec trois nouvelles cartes: 9, 7, 9;
    9 et 9 sont également égaux, donc la «guerre» continue avec deux nouvelles cartes: Jack, 3;
    Jack gagne.

Alors, sur le défi du code:

Contribution:

STDIN avec un tableau ou une chaîne simulant un tableau (votre appel - même si votre langue prend en charge les tableaux). Ce tableau contient les cartes d'une bataille dans l'ordre chronologique (voir les cas de test pour une meilleure compréhension de cela).

Production:

STDOUT l'index du joueur qui a gagné la bataille.
Vous pouvez choisir si vous voulez un (c. -à -indexé zéro 0, 1ou 2) ou une sortie indexée ( par exemple 1, 2, 3).

Règles du défi:

  • L'entrée sera un seul tableau / chaîne représentant un tableau. Vous ne pouvez donc pas avoir un tableau de tableaux pour le simplifier. Vous ne pouvez pas non plus avoir d'objets de substitution pour les cartes ne participant pas à la guerre.
  • Nous utilisons des notations numériques pour les faces-cartes au lieu de la notation des lettres. Donc Ace / Joker = 1; Jack = 11; Reine = 12; et King = 13.
  • Dans ce défi, nous pouvons supposer que nous jouons toujours avec 3 joueurs .
  • Les trois premiers indiquent le début de la «bataille». Lorsque deux joueurs ou plus ont une «guerre», les cartes continues dans le tableau indiquent leur bataille (voir les cas de test pour une meilleure compréhension de cela).

Règles générales:

  • Il s'agit du , donc la réponse la plus courte en octets l'emporte.
    Cela ne signifie pas que les langues qui ne jouent pas au golf ne devraient pas entrer. Essayez de trouver une réponse code-golf aussi courte que possible pour «chaque» langage de programmation.
  • Veuillez indiquer quelle indexation (zéro ou un indexé) vous avez utilisée pour la sortie.

Cas de 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)
Kevin Cruijssen
la source
4
Le nom anglais est en effet War (moins les jokers et moins la règle des 2 et 3 temps).
Martin Ender
@MartinEnder également, en cas d'égalité, les deux joueurs retournent 3 cartes face cachée et une 4ème face visible. Le 4 décide du vainqueur de la manche, et les cartes face cachée sont le "butin de guerre". De plus, le jeu ne continue-t-il pas tant qu'un joueur n'a pas toutes les cartes? Je ne sais pas si c'était une règle locale ou non, quelqu'un d'autre s'en souvient? C'est comme ça que je me souviens avoir joué.
Magic Octopus Urn
1
@MagicOctopusUrn Je me souviens avoir retourné les piles de défausse pour continuer à jouer jusqu'à ce qu'un joueur ait tout.
Kamil Drakari
1
@KamilDrakari ouais! C'est comme ça que je jouais aussi. J'étais en Louisiane en grandissant en jouant à ça.
Urne de poulpe magique
@MagicOctopusUrn Mon expérience vient du Minnesota, et puisque nous avons maintenant 2 points de données, je pense qu'il est sûr de dire que toute l'Amérique est la même.
Kamil Drakari

Réponses:

4

q - 142 caractères

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

Remarque: zéro indexé.

Il n'y a aucune notion de lecture de stdin dans q, vous devriez donc l'appeler comme une fonction: {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]

Assez long, en fait, mais il y a beaucoup de cas d'angle. Il conserve une liste de joueurs actifs et consomme la liste des cartes en boucle. La chose la plus problématique est de détecter le bon gagnant dans les mains [13, 2, 3], comme les 3battements 2, comme d'habitude, mais il a dû être dupliqué pour être placé dans le boîtier du coin.

C. Quilley
la source
3

JavaScript (ES6), 146 octets

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

Renvoie un index de base zéro. 127 octets si on me permet l'accord initial en tant que tableau séparé (cela fonctionne aussi pour un nombre arbitraire de mains bien sû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)
Neil
la source
0

Java 8, 257 octets

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, mon défi est plus difficile que je ne le pensais avec tout dans un seul tableau comme ça. ;) Mais comme cela fait plus d'un an que j'ai posté ce challenge, j'ai décidé de l'essayer moi-même. Cela m'a pris un bon moment avec plusieurs solutions de rechange et bizarreries .. Donc, il peut certainement être joué au golf encore plus, mais j'examinerai cela une autre fois. Cela a déjà pris beaucoup plus de temps que prévu.

Explication:

Essayez-le ici.

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
la source