Erziele eine Partie Laden, Verteidigen und Schießen

11

Als ich ein Kind war, habe ich dieses Spiel oft gespielt.

Regeln

Es gibt zwei Spieler (nennen wir sie A und B), und jeder Spieler benutzt seine Hände als Waffen. Es gibt drei mögliche Züge:

  1. Hände hoch, um Munition in Ihre Waffe zu laden.

    Jede Waffe beginnt leer. Das Laden erhöht die Munition um eins.

  2. Hände zeigen auf den anderen Spieler, um zu schießen.

    Dies verringert die Munition um eins. Sie müssen mindestens eine Munitionseinheit haben, um schießen zu können.

  3. Verschränkte Arme, um sich vor einem Schuss zu schützen.

Beide Spieler bewegen sich gleichzeitig. Wenn beide Spieler gleichzeitig schießen, treffen sich die Kugeln und das Spiel geht weiter. Das Spiel endet, wenn ein Spieler schießt, während der andere Munition lädt.

Schießen und leere Waffe gilt als Betrug . Wenn ein Spieler betrügt, während der andere eine rechtliche Handlung ausführt, verliert der Betrüger sofort. Wenn beide Spieler gleichzeitig schummeln, wird das Spiel fortgesetzt.

Betrugsversuche verringern die Munition nicht, daher kann sie niemals negativ sein.

Herausforderung

Geben Sie bei den Zügen der Spieler A und B an, welcher Spieler das Spiel gewonnen hat: 1für Spieler A, -1für Spieler B und 0für ein Unentschieden. Sie können jedes andere Dreifach der Rückgabewerte verwenden, müssen jedoch in Ihrer Antwort angeben, welche Sie verwenden.

Das Spiel kann:

  • enden, ohne alle Züge verarbeiten zu müssen;
  • nicht mit den gegebenen Zügen enden, und daher wird es als Unentschieden betrachtet.

Die Eingabe kann erfolgen:

  • als Saiten
  • als Arrays / Listen von ganzen Zahlen
  • auf andere Weise, die die Eingabe nicht vorverarbeitet

Vollständiges Programm oder Funktionen erlaubt. Da dies , gewinnt die kürzeste Antwort in Bytes!

Testfälle

A: "123331123"
B: "131122332"
    -----^                Player B shoots player A and wins.

Output: -1
A: "111322213312"
B: "131332221133"
    -------^              Player B cheats and loses.

Output: 1
A: "1333211232221"
B: "1213211322221"
    ----------^^          Both players cheat at the same time. The game continues.

Output: 0
A: "12333213112222212"
B: "13122213312232211"
         |       || ^---- Player A shoots player B and wins.
         ^-------^^------ Both players cheat at the same time. The game continues.

Output: 1
entfernt
quelle
1
Verwandte KotH (interessanterweise habe ich diese Variante des Spiels noch nie gespielt; ich denke, die verknüpfte Frage wurde von einem Freund inspiriert, der sie hatte, aber es ist lange genug her, dass ich mich nicht mehr erinnere).
Türknauf

Antworten:

6

Gelee, 33 32 24 Bytes

Zæ%1.»0$+¥\>-‘żZḅ3Ff5,7Ḣ

Dies gibt 5 anstelle von -1 und 7 anstelle von 1 aus . Probieren Sie es online aus! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

Zæ%1.»0$+¥\>-‘żZḅ3Ff5,7Ḣ  Main link. Argument: A (digit list array)

Z                         Zip; group corresponding digits.
 æ%1.                     Map the digits in (-1.5, 1.5].
                          This replaces [1, 2, 3] with [1, -1, 0].
          \               Cumulatively reduce the pairs by doing the following.
     »0$                    Take the maximum of the left value and 0, i.e., replace
                            a -1 with a 0.
        +¥                  Add the modified left value to the right value.
                          This computes the available ammo after each action. An
                          ammo of -1 indicates a cheating attempt.
           >-             Compare the results with -1.
             ‘            Increment. And unilateral cheating attempt is now [1, 2]
                          or [2, 1], where 1 signals the cheater and 2 the winner.
              żZ          Pair each result with the corr., original digits.
                ḅ3        Convert each pair from base 3 to integer.
                          This maps [1, 2] and [2, 1] to 5 and 7.
                  F       Flatten the resulting, nested list.
                   f5,7   Discard all but 5's and 7's.
                       Ḣ  Grab the first element (5 or 7).
                          If the list is empty, this returns 0.
Dennis
quelle
2

Pyth, 48 46 49 47 Bytes

.xhfT|M.e,-FmgF.b/<dhkY2S2Q?}b_BS2-FbZ.b,NYCQ)0

Probieren Sie es hier aus!

Vielen Dank an @isaacg für das Speichern von 2 4 Bytes!

Nimmt die Eingabe als 2-Tupel mit der Liste der Züge von Spieler A zuerst und den Zügen von Spieler B zweitens vor. Die Ausgabe ist die gleiche wie bei der Herausforderung.

Erläuterung

Kurzübersicht

  • Zuerst gruppieren wir die Züge beider Spieler, damit wir eine Liste mit 2 Tupeln erhalten.
  • Dann ordnen wir jedes dieser Tupel einem anderen 2-Tupel in der Form [cheating win, fair win]mit den möglichen Werten -1, 0, 1für jedes Tupel zu , um anzuzeigen, ob ein Spieler an diesem Punkt gewonnen hat ( -1, 1) oder ob das Spiel weitergeht ( 0)
  • Jetzt müssen wir nur noch das erste Tupel erhalten, das nicht ist [0,0], und das erste Nicht-Null-Element davon nehmen, das den Gewinner angibt

Code-Aufschlüsselung

.xhfT | Me, -FmgF.b / <dhkY2S2Q?} b_BS2-FbZ.b, NYCQ) 0 # Q = Liste der Verschiebungslisten

                                      .b, NYCQ # koppeln die Elemente beider Eingabelisten
       .e # Karte über die Liste der Paare mit 
                                                 # b ist das Paar und k ist der Index
            m Q # ordne jede Zugliste zu d
               .b 2S2 # map over [1,2], ich kann m nicht verwenden, weil es ist
                                                 # Lambda-Variable widerspricht der von .e
                  <dhk # d [: k + 1]
                 / Y # Anzahl Vorkommen von 1 oder 2 in dieser Liste
          -F # (Anzahl von 1s) - (Anzahl von 2s) zeigt den Betrugssieg an
                           ?} b_BS2 # wenn b (1,2) oder (2,1) ist
                                  -Fb # nimm den Unterschied, zeigt fairen Gewinn an
                                     Z # else 0, noch kein Gewinner
         , # kopple diese 2 Werte
     | M # Nimm für jedes resultierende Paar das erste wenn
                                                 # Es ist nicht Null, sonst die zweite
   fT # filtert alle Nullwerte heraus
.xh # versuche den ersten Wert zu nehmen, der den Gewinner angibt
                                             ) 0 # wenn das nicht möglich ist, weil die Liste leer ist
                                                 # Null ausgeben, um ein Unentschieden anzuzeigen
Denker
quelle
m|Fdist das gleiche wie |M.
isaacg
@isaacg Danke! Ich vergesse immer, dass Mdas auch Splatting macht. Übrigens: Das Problem mit widersprüchlichen Lambda-Variablen, das wir im Chat besprochen haben, kostet mich hier mehrere Bytes: P
Denker
,1 2ist das gleiche wieS2
isaacg
Ich habe eine anderen Testfall hinzugefügt;)
entfernt
@isaacg Nochmals vielen Dank! Ich weiß nicht, wie ich das verpasst habe.
Denker
1

Python, 217 Bytes

def f(A,B):
 x=y=0;c=[-1,1,0]
 for i in range(len(A)):
  a=A[i];b=B[i]
  for s in[0,1]:
   if(a,b)==(2,1):return c[s]*c[x<1]
   if(a,b)==(2,3)and x<1:return-c[s]
   x-=c[a-1];x+=x<0;a,b,x,y=b,a,y,x
 return 0

Erläuterung : Nimmt A und B als Listen von Ganzzahlen. Geht einfach jedes Zugpaar durch, addiert oder subtrahiert bei Bedarf 1 und kehrt zurück, wenn jemand betrügt oder gewinnt. Macht dasselbe zweimal mit einer anderen for-Schleife, einmal für die Bewegung von A und einmal für die Bewegung von B. Addiert 1, wenn x unter 0 bis -1 fällt.

Frikative Melone
quelle
1

Java, 226 212 200 196 194 Bytes

-14 Bytes durch Neuordnung der Logik

-12 Bytes dank Herrn Public , der darauf hinweist, wie eine ternäre Operation für die Aufnahmelogik verwendet werden kann

-4 Bytes durch Zusammendrücken der Lastlogik in einen Kurzschluss, wenn

-2 - Bytes , weil ==1=== <2Eingang , wenn nur sein 1, 2,3

(a,b)->{for(int m=0,n=0,w,v,r=0,i=0,x;i<a.length;){w=a[i];v=b[i++];x=w==2?m<1?r--:m--:0;x=v==2?n<1?r++:n--:0;if(r!=0)return r;if(w<2&&++m>0&v==2)return -1;if(v<2&&++n>0&w==2)return 1;}return 0;}

Verwendung und eingerückte Version:

static BiFunction<Integer[], Integer[], Integer> game = (a,b) -> {
    for(int m=0,n=0,w,v,r=0,i=0,x;i<a.length;) {
        w=a[i];v=b[i++];
        // shoot
        x=w==2?m<1?r--:m--:0;
        x=v==2?n<1?r++:n--:0;
        if(r!=0)return r;
        // load
        if(w<2&&++m>0&v==2)return -1;
        if(v<2&&++n>0&w==2)return 1;
    }
    return 0;
};

public static void main(String[] args) {
    System.out.println(game.apply(new Integer[] {1,2,3,3,3,1,1,2,3}, new Integer[] {1,3,1,1,2,2,3,3,2}));
    System.out.println(game.apply(new Integer[] {1,1,1,3,2,2,2,1,3,3,1,2}, new Integer[] {1,3,1,3,3,2,2,2,1,1,3,3}));
    System.out.println(game.apply(new Integer[] {1,3,3,3,2,1,1,2,3,2,2,2,1}, new Integer[] {1,2,1,3,2,1,1,3,2,2,2,2,1}));
}

Nicht mehr so ​​einfach, die Spielregeln umzusetzen, aber einfach. Jeder Zyklus führt diese Operationen aus:

  • Die Last wird in temporäre Variablen verschoben
  • Wenn der Spieler geschossen hat
    • ohne Munition: Bias Cheat rzum Verlieren
    • mit Munition: Munition dekrementieren
  • Wenn dies rnicht der Fall ist 0, geben Sie den Wert zurück, weil jemand betrogen hat
  • Wenn der Spieler neu geladen hat
    • Munition erhöhen
    • Wenn ein anderer Spieler geschossen hat, wird der Verlust zurückgegeben

x ist eine Dummy-Variable, mit der der Compiler einen ternären Ausdruck verwenden kann.

Warten Sie, Java ist kürzer als Python?

CAD97
quelle
Ich habe eine anderen Testfall hinzugefügt;)
entfernt
1
@WashingtonGuedes Und meins arbeitet an diesem Fall dank meiner logischen Neuordnung!
CAD97
Können die Wenns zu Ternären gemacht werden? zBw==2&&m<1?r--:m++
Downgoat
@Downgoat das andere geht mit dem Inneren, wenn so, wie Sie es geschrieben haben, das Tertiär nicht funktionieren würde. Allerdings kann ich das wahrscheinlich mit dem inneren if machen. Ich werde es testen, wenn ich eine Chance bekomme.
CAD97
1
@ CAD97 @Downgoat Sie können tatsächlich ternäre Operatoren für die if-Anweisungen verwenden. int x=w==2?m<1?r--:r:m--;Verwenden Sie für das erste Ternär weiterhin das x (da dies nur eine Dummy-Variable ist, damit das Ternär funktioniert) wiex=v==2?n<1?r++:r:n--;
Mr Public