Finde das Ergebnis eines Kriegsspiels
Als ich in der Grundschule war, gab es ein "Rock-Paper-Scissors" -Spiel, das wir während der Versammlungen spielten, wenn wir auf unseren Lehrer warteten, in der Pause usw. Wir nannten es "Krieg". Nach einigem Suchen stellt sich jedoch heraus, dass dies eine viel einfachere Variante des "Shotgun Game" ist (laut WikiHow) . Ich werde es "Krieg" nennen, da die Regeln etwas anders sind:
2 Personen sitzen sich gegenüber. Das Ziel des Spiels ist es, den anderen Spieler zu "töten". In jeder Runde kannst du einen von 3 Zügen spielen:
Nachladen : Sie haben eine Waffe, die einen einzigen Schuss hält. Es muss neu geladen werden, bevor es jedes Mal abgefeuert werden kann. Nachladen, wenn Sie bereits Munition haben, ist legal, tut aber nichts. Ein Nachladen wurde symbolisiert, indem man mit beiden Händen auf die Schläfen tippte. Jeder Spieler beginnt mit 0 Munition.
Wache : Der einzige sichere Zug. Wenn Sie während der Bewachung erschossen werden, sterben Sie nicht. Die Bewachung wurde durch das Kreuzen der Arme über der Brust symbolisiert.
Feuer : Feuer deine Waffe. Um erfolgreich zu feuern, müssen Sie seit dem letzten Schuss neu geladen haben. Wenn dein Gegner nachlädt, gewinnst du. Wenn sie auch schießen und Sie beide Munition haben, ist es ein Unentschieden. Wenn sie Wache halten, haben Sie die Munition verschwendet. Ohne Munition zu schießen ist zwar ein legaler Schritt, aber es macht nichts und macht Sie angreifbar wie das Nachladen. Das Feuern wurde symbolisiert, indem auf den anderen Spieler gezeigt wurde.
Es wurde ähnlich wie RPS gespielt, da jeder Spieler gleichzeitig seine Wahl fallen lässt (wir haben zwischen den Zügen zweimal mit den Beinen getippt, um im Rhythmus miteinander zu bleiben, aber das ist für die Herausforderung nicht wichtig).
Die Herausforderung:
Ihre Aufgabe ist es, das Ergebnis eines Kriegsspiels zu finden. Dies kann eine Funktion oder ein vollständiges Programm sein.
Eingang
Die Option, die jeder Spieler in jeder Runde gewählt hat, wird durch ein Zeichen / eine Zeichenkette dargestellt:
r : neu laden
g : Wache
f : Feuer
Die Eingabe ist eine Liste von Paaren, eine begrenzte / nicht begrenzte Zeichenfolge oder irgendetwas anderes in dieser Richtung.
Ein Beispiel für eine Eingabe in Python ist [("r", "g"), ("f", "r")]
, dass in der ersten Runde der erste Spieler neu geladen und der zweite Spieler bewacht wird. In der zweiten Runde schießt der erste Spieler, während der zweite Spieler nachlädt. Spieler eins gewinnt dieses Spiel. Das gleiche Eingangsgegebenenfalls wie dargestellt werden könnte "r g f r"
, "rgfr"
, "rg fr"
"rg-fr"
...
Sie können folgendes annehmen:
Die Eingabe entspricht dem von Ihnen gewählten Format und enthält nur gültige Zeichen.
Jemand wird innerhalb von 100 Runden sterben.
Sie können jedoch nicht davon ausgehen, dass die Züge enden, wenn jemand stirbt.
Ausgabe
Ein Wert, der angibt, wer gewonnen hat (oder wer zuerst gewonnen hat *
). Sie können für jedes Szenario auswählen, was ausgegeben werden soll, müssen jedoch Folgendes berücksichtigen:
Spieler 1 gewinnt
Spieler 2 gewinnt
Sie töten sich gegenseitig (Unentschieden)
Jedes Ergebnis muss einen Distriktwert haben und für jedes Szenario immer gleich sein.
Als Beispiel: Sie können ausgeben, 1
wann Spieler 1 gewinnt, 2
wann Spieler 2 gewinnt und 0
im Falle eines Unentschieden. Sie müssen dann immer dann ausgeben, 1
wenn Spieler 1 gewinnt, 2
wenn Spieler 2 gewinnt und 0
im Falle eines Unentschieden.
Es kann zurückgegeben oder auf die Standardausgabe gedruckt werden. Nachgestellte Leerzeichen sind in Ordnung.
Nur damit klar ist, ist das einzige Szenario, das zu einem Unentschieden führt, wenn beide Spieler schießen und beide Munition haben.
*
Da in dieser Herausforderung Züge fortgesetzt werden können, nachdem jemand gestorben ist, kann es sein, dass mehr als ein Spieler gewinnt. Sie müssen anhand der Eingabe herausfinden, wer zuerst gewonnen hat.
Testfälle (vorausgesetzt, 1
P1 gewinnt, 2
P2 gewinnt und 0
unentschieden):
"rg fr" => 1 (P1 shot P2 while they were reloading)
"rg ff" => 1 (They both shot, but only P1 had ammo)
"rr ff" => 0 (Both had ammo and shot each other)
"rr ff rr fg" => 0 (Both had ammo and shot each other. Everything after the first win is ignored)
"rr fg rf" => 2 (P2 shot P1 while they were reloading)
"rf gg rr fg rr fr" => 1
(P2 tried to shoot but didn't have any ammo, then they both guarded, then they both reloaded, then P2 blocked a shot, then they both reloaded again [but P2 still only has 1 ammo!], then P1 shoots P2 while they're reloading.
"rr gf fr rf gg rg ff" => 1
^ Player 1 wins here. The rest to the right has no effect on the output
Das ist Codegolf, also gewinnt die kleinste Anzahl von Bytes!
Beachten Sie, wie die Testfälle zeigen, dass Sie mit "dummen" Bewegungen umgehen müssen. Es ist durchaus zulässig, dass ein Spieler versucht, zu schießen, wenn er keine Munition hat, oder 2 Runden hintereinander nachlädt (und nur eine einzige Munition ansammelt).
{"rff","rgf"}
?Antworten:
Netzhaut , 36 Bytes
Das Eingabeformat sollte zeilenweise getrennt sein, z
Das Ergebnis ist, dass
!_
Spieler 1 gewinnt,_!
wenn Spieler 2 gewinnt und!!
es ein Unentschieden gibt.Probieren Sie es online! (Eine Testsuite, die der Einfachheit halber eine Trennung nach Leerzeichen verwendet.)
Ich muss diese Herausforderung völlig übersehen haben. Ich bin sicher, ich hätte das früher in Retina versucht, sonst. :)
Erläuterung
Wir beginnen damit, "gültige" Schüsse zu markieren, indem wir den ersten
f
nach jedemr
in drehen!
. Wir tun dies, indem wir jeweilsf
einenr
Spieler finden, ohne einen anderen zu überkreuzenf
. Die Suche aufr
s auf demselben Player zu beschränken, ist einfach, indem immer drei Zeichen gleichzeitig verwendet werden.Jetzt legen wir alle Runden ab, in denen sich jemand selbst bewacht hat, weil die letzte Runde keine von diesen sein kann.
Jetzt behalten wir nur den ersten Zug bei, der ein enthält
!
. Wenn ein gültiger Schuss fällt (und wir wissen, dass niemand bewacht wurde), endet das Spiel.Schließlich müssen wir den String konsolidieren, um konsistente Ausgaben zu erhalten, und wir tun dies einfach, indem wir die Nicht-
!
Zeichen (entwederr
oderf
) in umwandeln_
.quelle
Python, 139 Bytes
Übernimmt die Eingabe von stdin in Form einer Liste von Zeichenfolgen mit zwei Zeichen (z. B. ['rf', 'rr', 'rg', 'ff']). Gibt 1 aus, wenn Spieler 1 gewinnt, -1, wenn Spieler 2 gewinnt, und 0 für ein Unentschieden.
Erläuterung: Überprüft zuerst, ob jemand eine Kugel abgefeuert hat, wenn dies der Fall ist, endet das Spiel. Dann stellen wir fest, ob die Spieler entweder ihre Waffen nachgeladen oder ihre Munition verschwendet haben.
Dies ist mein erster Codegolf-Beitrag :)
quelle
JavaScript (ES6),
10810793918985 Byte4 Bytes mit Hilfe von Titus gespeichert
Nimmt Eingaben als Array von 2-Zeichen-Zeichenfolgen auf, die die von jedem Spieler gespielten Züge beschreiben.
Kehrt zurück:
1
wenn Spieler 1 gewinnt2
wenn Spieler 2 gewinnt3
für ein UnentschiedenWie es funktioniert
Wir pflegen eine Bitmaske
b
, die beschreibt, wer eine geladene Kugel hat:Wir verwenden die De Bruijn-Sequenz
'ffrfgrrggf'
, um alle 9 möglichen Kombinationen von Zügen zu identifizieren. Wir verwenden ODER- und UND-Bitmasken, umb
entsprechend der Verschiebungskombination zu aktualisieren . Wir verwenden einen dritten Satz von Bitmasken, die mit UND verknüpft sindb
, um den Gewinner zu bestimmenw
. (Die einzigen drei Gewinnkombinationen zu seinff
,fr
undrf
.)Es ist erwähnenswert, dass die ODER- und UND-Masken mit demselben Muster gespeichert werden können, das um zwei Positionen verschoben ist.
Testfälle
Code-Snippet anzeigen
quelle
0
(niemand wurde erschossen) oder3
(Spieler töten sich gegenseitig). Ich bin mir nicht sicher, ob dies zulässig ist. Wenn nicht, kann ichw%3
stattdessen zurückkehren.&
Maske kann für 0 seinfr,rf,ff
.'312'['0210231'[m='ffrfgrrggf'.search(c)]|'233331'[m-3]&b]
oder'123'['2100231'[m='frffgrrggf'.search(c)]|'233331'[m-3]&b]
ein Byte speichern; aber arbeiten sie?["rr","fg","fr","rf"]
&
hat eine höhere Priorität als|
, daher sollte die Änderung der Reihenfolge dort nichts ändern (außer das Byte zu speichern). Aber die Zuordnung fehlte in meinem Code. Versuchen Sie es...'123'[b='2100231'...
.Perl 6 ,
7162 BytesRegex-basierte Lösung.
Übernimmt die Eingabe als Zeichenfolge im Formular
"rg fr"
.Die drei möglichen Ausgänge sind die ENUM - Werte
More
(Spieler 1 gewonnen),Less
(Spieler 2 hat),Same
(ziehen) , - die in diesen Worten drehen , wenn gedruckt wird , oder in1
,-1
,0
wenn Zahlen zu gezwungen.Probieren Sie es online!
Wie es funktioniert
Führt zwei Regex-Übereinstimmungen für die Eingabe durch. Nach der Interpolation sind die beiden regulären Ausdrücke:
r[..[r|g]]*.[r|f]f
- Stimmt mit dem ersten erfolgreichen Schuss von Spieler 2 überein.r[..[r|g]]*..f[r|f]
- Stimmt mit dem ersten erfolgreichen Schuss von Spieler 1 überein.In jedem Fall wird die Endposition der Übereinstimmung (
.to
) oder unendlich zurückgegeben, wenn keine Übereinstimmung vorhanden war.Wendet den
<=>
Operator auf die beiden Übereinstimmungsendpositionen an. Es wird ein Wert aus derOrder
Aufzählung (More
,Less
oderSame
) zurückgegeben, je nachdem, ob das erste Argument größer, kleiner oder gleich dem zweiten ist.quelle
some number
? Und verwenden Sie solche Zeichen tatsächlich in gängigem Perl-Code oder nur zum Golfen?[Menu] i n f
(es wird als Kompositionssequenz bezeichnet ). Allerdings haben alle Perl 6 Symbole ASCII - Versionen - zBInf
und∞
sind Synonyme - so es nicht ist notwendig , Unicode - Zeichen in Perl 6 - Code zu verwenden. Ich mag es einfach ... :)Haskell ,
101 9187 BytesProbieren Sie es online! Die Infix-Funktion
#
nimmt zwei Zeichenfolgen, die die Aktionen der beiden Spieler darstellen, und kehrt zurück,(0,1)
wenn Spieler 1 gewinnt,(1,0)
für Spieler 2 und(0,0)
für ein Unentschieden.Anwendungsbeispiel:
Erläuterung:
Die Infix Funktion
!
übersetzt eine Folge von Aktionen'r'
(neu laden),'f'
(Feuer) und'g'
(Wache) zu einer Sequenz beobachtbarer Aktionen0
(tatsächliches Feuer),1
(keine Aktion) und2
(Wache), wo ein Feuer Aktion nur als gezählt tatsächliches Feuer Aktion wenn eine Kugel geladen ist, und da sonst keine Aktion . Um dies zu erreichen,n
lautet das erste Argument,0
ob eine Kugel geladen ist und1
ob die Waffe nicht geladen ist. Auf diese Weise'f'
kann jeder einfach durch den Strom ersetzt werdenn
. (n=0
-> geladen -> tatsächliches Feuer ->0
,n=1
-> entladen -> keine Aktion ->1
)Die neun resultierenden Möglichkeiten sind dann
(0,0)
: Beide Spieler schießen und sterben, das Spiel endet.(0,1)
oder(1,0)
: Ein Spieler schießt auf den anderen, das Spiel endet.(0,2)
oder(2,0)
: Ein Spieler schießt, der andere Wächter schießt, das Spiel geht weiter.(1,1)
,(1,2)
,(2,1)
Oder(2,2)
: Keine Spieler schießt, Spiel geht weiter.Die Summe der Optionen zum Beenden des Spiels ist konstruktionsbedingt kleiner als 2 und die Summe der Möglichkeiten zum Fortsetzen des Spiels ist größer oder gleich 2. Das Ergebnis des Spiels ist dann das erste Tupel mit einer Summe von weniger als 2.
quelle
Batch, 249 Bytes
Die Eingabe erfolgt in Form von Zeichenpaaren für jede Runde und erfolgt nach Fehlerstufe (0 = Unentschieden, 1 = Spieler 1, 2 = Spieler 2).
x
undy
verfolge, ob der Spieler Munition hat. Wenn also beide feuern, ist das Ergebnis3-x-x-y
, außer wenn dies 3 ist. In diesem Fall machen wir weiter. In Zeile 5 missbrauche ich Batchs Parser -%1
(das ist der aktuelle Zug) wird ersetzt, bevor dieshift
Anweisung ausgeführt und entfernt wird, sodass wir immer noch zum richtigen Label gehen.quelle
Clojure, 168 Bytes
Weniger Golf (wenn beide Personen am Leben sind
M
, aktualisieren wir ihre Munition und den Lebensstatus des Feindes, ansonsten geben wir den aktuellen Status zurück):Anwendungsbeispiel (erstes Element zeigt an, ob Spieler 1 am Ende des Spiels am Leben ist, zweites Element zeigt an, ob Spieler 2 am Leben ist, 3. und 4. zeigen den Munitionsstatus an, der bei der Ermittlung des Gewinners nicht relevant ist):
Update: Na schau dir das an, das
loop
hat identische Länge! Ich finde, dass diereduce
Version einfacher zu entwickeln ist, da Sie Zwischenzustände leicht untersuchen können, wenn Sie sie verwendenreductions
.quelle
[l1 l2 r1 r2]
(seine geänderten Werte beilet
und seine ursprünglichen Werte) und diesefn
Unterschriften wiederholen musste .loop
. Ich finde, es führt zu ordentlicherem Code. Sobald ich mit mehr als 1 Akku klappen muss, schalte ich um.PHP,
10710190 BytesVerwenden einer Bitmaske $ d für den Ladestatus und einer DeBruijn-Sequenz für die Schussbewegungen.
Nimmt Eingaben als 2-stellige Befehlszeilenargumente an und führt sie mit aus
-nr
.Nervenzusammenbruch
fr
Position = 1 = P1-Feuer;rf
= Position 2 = P2 feuert,ff
= Position 3 = beide feuerng<$m
<=>f<$m[0]
(f<$m
ist immer wahr, da es ein zweites Zeichen gibt).quelle
Python, 200 Bytes
quelle
turns
anstatt nurt
, was bedeutet, dass das Programm viel größer als nötig ist. Beginnen Sie Ihre Einreichung auch mit etwas wie#Python 2, 200 bytes
(vorausgesetzt, dies ist 2 und das Programm ist 200 Byte lang), damit die von Ihnen verwendete Sprache klar ist.Clojure,
180173 Bytes-7 Bytes, indem Sie die Funktion in eine vollständige Funktion ändern, anstatt ein Makro zu verwenden. Das ließ mich die inneren Funktionen zu Makros machen, was ein bisschen spart.
Dies ist eine sehr wörtliche Lösung. Ich bin ein bisschen verrückt, da ich gerade eine Vollversion des Spiels geschrieben habe, und dies ist im Grunde eine stark reduzierte Version des von mir verwendeten Algorithmus. Es gibt wahrscheinlich viele Optimierungen, die ich tun könnte, aber ich bin ziemlich zufrieden damit. Erklärungen finden Sie im Code vor dem Golf.
quelle