Simulieren Sie eine "Schlacht" im Kartenspiel "Oorlog"


15

Lassen Sie uns eine Simulation für einen Aspekt des Kartenspiels erstellen, den ich persönlich unter dem niederländischen Namen 'Oorlog' (übersetzt 'Krieg') kenne.

Wie funktioniert 'Oorlog'?

Zwei Kartenspiele (jeweils mit zwei Jokern) werden gleichmäßig auf die Anzahl der spielenden Spieler aufgeteilt. Jeder Spieler mischt seine eigenen Aktien, legt sie verkehrt herum vor sich auf und alle Spieler öffnen gleichzeitig die erste Karte der Aktie.
Der Gewinner dieses Kampfes wird durch die Werte der Karten bestimmt, die diesen Regeln folgen: Joker / Ass besiegt König; König besiegt Königin; Königin besiegt Jack; Jack besiegt 10; 10 Niederlagen 9; .... Außerdem besiegen 2 und 3 Ace / Joker. Die letzte Regel kann zu einem Zyklus führen, in dem 2 oder 3 Ass oder Joker, Ass oder Joker eine andere Karte schlagen, die wiederum die 2 oder 3 schlägt. In diesem Fall gewinnt die 2 oder 3 den Kampf.
(Anzug ist in diesem Kartenspiel irrelevant.)

Wenn zwei oder mehr Spieler die gleichen höchsten Karten haben, haben sie einen "Krieg". Dies bedeutet, dass sie eine Karte verkehrt herum ablegen und dann jeweils eine neue Karte aus ihrem Vorrat aufschlagen, um erneut zu ermitteln, wer die höchste Karte hat. Dies wird fortgesetzt, bis ein einzelner Spieler die gesamte Schlacht gewonnen hat.
(Alle Karten dieses Kampfes werden auf den Ablagestapel des Spielers gelegt, der den Kampf gewonnen hat. Dann öffnet jeder eine neue Karte. Wenn die Karten eines Spielers aufgebraucht sind, dreht er seinen Ablagestapel um und setzt diesen neuen Stapel fort. Dies wird fortgesetzt, bis ein Spieler keine Karten mehr hat und der Spieler mit der höchsten Anzahl an Karten gewinnt.)

Beispiel 'Schlachten' mit drei Spielern:

  1. 4, 8, Jack:
    Jack gewinnt.
  2. 7, Ass, Dame:
    Ass gewinnt.
  3. 10, 10, König:
    König gewinnt.
  4. 3, Joker, 2:
    3 gewinnt.
  5. Ass, Joker, 2:
    2 gewinnt.
  6. 3, Dame, Ass:
    3 Siege.
  7. Königin, Königin, 9:
    Königin & Königin haben einen 'Krieg', also geht es weiter mit zwei neuen Karten: 4, 8;
    8 gewinnt.
  8. 4, 4, 4:
    Alle haben einen "Krieg", also geht es mit drei neuen Karten weiter: 8, Ass, 2;
    2 gewinnt.
  9. Jack, 5, Jack:
    Jack & Jack haben einen "Krieg", also geht es mit zwei neuen Karten weiter: 5, 5;
    5 & ​​5 sind auch gleich, so dass der 'Krieg' mit zwei neuen Karten fortgesetzt wird: 10, König;
    König gewinnt.
  10. Joker, Joker, Ass:
    Alle haben einen "Krieg", also geht es mit drei neuen Karten weiter: 9, 7, 9;
    9 & 9 sind auch gleich, so dass der "Krieg" mit zwei neuen Karten fortgesetzt wird: Jack, 3;
    Jack gewinnt.

Also, auf die Code-Herausforderung:

Eingang:

STDIN mit einem Array oder einer Zeichenfolge, die ein Array simuliert (Ihr Aufruf - auch wenn Ihre Sprache Arrays unterstützt). Dieses Array enthält die Karten eines Kampfes in chronologischer Reihenfolge (zum besseren Verständnis siehe Testfälle).

Ausgabe:

STDOUT der Index des Spielers, der den Kampf gewonnen hat.
Sie können wählen , ob Sie eine Null-Index (dh wollen 0, 1oder 2) oder ein indiziertes Ausgang (dh 1, 2, 3).

Herausforderungsregeln:

  • Die Eingabe ist ein einzelnes Array / eine einzelne Zeichenfolge, die ein Array darstellt. Sie können also kein Array von Arrays haben, um es zu vereinfachen. Sie können auch keine Ersatzgegenstände für Karten haben, die nicht am Krieg teilnehmen.
  • Wir verwenden Nummernnotationen für die Bildkarten anstelle der Buchstabennotation. Also Ass / Joker = 1; Jack = 11; Königin = 12; und König = 13.
  • Bei dieser Herausforderung können wir davon ausgehen, dass wir immer mit 3 Spielern spielen .
  • Die ersten drei zeigen den Beginn der Schlacht an. Wenn zwei oder mehr Spieler einen "Krieg" haben, geben die fortlaufenden Karten im Array ihren Kampf an (siehe Testfälle für ein klareres Verständnis).

Allgemeine Regeln:

  • Dies ist , so dass die kürzeste Antwort in Bytes gewinnt.
    Dies bedeutet nicht, dass Sprachen, die nicht Code-Golf sind, nicht eingegeben werden sollten. Versuchen Sie, für jede Programmiersprache eine möglichst kurze Code-Golf-Antwort zu finden.
  • Bitte geben Sie an, welche Indizierung (null- oder einsindiziert) Sie für die Ausgabe verwendet haben.

Testfälle:

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
Der englische Name ist in der Tat War (abzüglich der Joker und abzüglich der 2-und-3-Schlag-As-Regel).
Martin Ender

@MartinEnder auch, wenn es ein Unentschieden gibt, drehen beide Spieler 3 Karten verdeckt und eine 4. offen. Der vierte entscheidet über den Gewinner der Runde, und die verdeckten Karten sind die "Kriegsbeute". Geht das Spiel nicht weiter, bis 1 Spieler alle Karten hat? Ich weiß nicht, ob dies eine örtliche Regel war oder nicht, erinnert sich noch jemand daran? So erinnere ich mich an das Spielen.
Magic Octopus Urn

1
@MagicOctopusUrn Ich erinnere mich, dass ich die Ablagestapel umgedreht habe, um weiterzuspielen, bis ein Spieler alles hatte.
Kamil Drakari

1
@KamilDrakari ja! So habe ich auch gespielt. Ich bin in Louisiana aufgewachsen und habe das gespielt.
Magic Octopus Urn

@MagicOctopusUrn Meine Erfahrung stammt aus Minnesota, und da wir jetzt 2 Datenpunkte haben, kann ich mit Sicherheit sagen, dass ganz Amerika gleich ist.
Kamil Drakari

Antworten:


4

q - 142 Zeichen

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

Anmerkung: Null indiziert.

Es gibt keine Idee, stdin in q zu lesen, deshalb sollten Sie es als Funktion aufrufen: {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]

Eigentlich ziemlich lang, aber es gibt viele Eckfälle. Es enthält eine Liste der aktiven Spieler und verbraucht die Liste der Karten in einer Schleife. Am problematischsten ist es, den richtigen Sieger in Händen zu finden, wie es [13, 2, 3]seit 3Beats üblich 2ist, aber er musste dupliziert werden, um in den Eckkoffer zu gelangen.


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

Gibt einen nullbasierten Index zurück. 127 Bytes, wenn ich den ersten Deal als separates Array ausführen darf (dies funktioniert natürlich auch für eine beliebige Anzahl von Händen):

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 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, meine Herausforderung ist schwieriger, als ich gedacht habe, mit allem in einem einzigen Array. ;) Aber da es schon mehr als ein Jahr her ist, dass ich diese Herausforderung gestellt habe, habe ich beschlossen, es selbst zu versuchen. Es hat eine ganze Weile gedauert, bis ich mehrere Workarounds und Macken hatte. Also kann man definitiv noch mehr Golf spielen, aber ich werde das ein anderes Mal untersuchen. Das hat schon viel länger gedauert als ich erwartet hatte.

Erläuterung:

Probieren Sie es hier aus.

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.