Bestimmen Sie den Gewinner eines Kriegsspiels

19

Das Kartenspiel Krieg ist insofern interessant, als das endgültige Ergebnis vollständig von der ursprünglichen Anordnung des Kartenspiels abhängt, solange bestimmte Regeln für die Reihenfolge eingehalten werden, in der die Karten vom Spielfeld genommen und in die Kartenspiele verschoben werden. In dieser Herausforderung gibt es nur 2 Spieler, was die Dinge stark vereinfacht.

Das Spiel

  1. Jeder Spieler erhält ein Kartenspiel mit 26 Karten.
  2. Jeder Spieler legt die oberste Karte offen in sein Deck. Der Spieler mit der höherrangigen Karte ( Ace > King > Queen > Jack > 10 > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2) gewinnt die Runde und legt seine Karte auf die Karte seines Gegners, dreht sie um und legt sie auf den unteren Rand seines Decks (sodass sich seine Gewinnkarte auf dem unteren Rand des Decks befindet) und die verlorene Karte des anderen Spielers liegt direkt darüber). Dies geschieht so lange, bis einer der Spieler keine Karten mehr hat.
    • Wenn die Karten den gleichen Rang haben, legt jeder Spieler die obersten 2 Karten seines Stapels offen auf die oberste seiner vorherigen Karten (so dass die Karte, die sich oben auf dem Stapel befand, die zweite Karte im Stapel ist, und die Karte, die von oben nach unten war, liegt oben). Dann werden die Ränge (der obersten Karte jedes Stapels) erneut verglichen, und der Gewinner legt seinen gesamten Stapel auf den gesamten Stapel des Verlierers, dreht den Stapel um und legt ihn auf den Boden seines Stapels. Wenn es ein anderes Unentschieden gibt, werden mehr Karten auf die gleiche Weise gespielt, bis ein Gewinner ausgewählt wird oder einem Spieler die Karten ausgehen.

Wenn einer der Spieler irgendwann eine Karte von seinem Deck ziehen muss, aber sein Deck leer ist, verliert er das Spiel sofort.

Die Herausforderung

Wenn Sie zwei Kartenlisten in den Decks der Spieler in einem beliebigen geeigneten Format haben, geben Sie einen Wahrheitswert aus, wenn Spieler 1 gewinnt, und einen Falschwert, wenn Spieler 2 gewinnt.

Der Einfachheit halber wird eine 10-Karte mit einem dargestellt T, und Bildkarten werden abgekürzt ( Ace -> A, King -> K, Queen -> Q, Jack -> J), sodass alle Karten ein Zeichen lang sind. Alternativ können Ränge mit Dezimalzahlen von 2 bis 14 ( Jack -> 11, Queen -> 12, King -> 13, Ace -> 14) oder Hexadezimalzahlen von 2 bis E ( 10 -> A, Jack -> B, Queen -> C, King -> D, Ace -> E) dargestellt werden. Da Anzüge keine Rolle spielen, werden Anzuginformationen nicht gegeben.

  • Sie können davon ausgehen, dass alle Spiele irgendwann enden (obwohl dies sehr lange dauern kann) und einem Spieler immer die Karten vor dem anderen ausgehen.
  • Jeder Spieler legt Karten gleichzeitig und jeweils eine Karte nach der anderen ab, sodass es keine Unklarheit darüber gibt, welchem ​​Spieler zuerst die Karten ausgegangen sind.

Testfälle

In den Testfällen werden 23456789ABCDEdie Ränge (in aufsteigender Reihenfolge) dargestellt.

D58B35926B92C7C4C7E8D3DAA2, 8E47C38A2DEA43467EB9566B95 -> False
669D9D846D4B3BA52452C2EDEB, E747CA988CC76723935A3B8EA5 -> False
5744B95ECDC6D325B28A782A72, 68394D9DA96EBBA8533EE7C6C4 -> True
87DB6C7EBC6C8D722389923DC6, E28435DBEBEA543AA47956594A -> False
589EAB9DCD43E9EC264A5726A8, 48DC2577BD68AB9335263B7EC4 -> True
E3698D7C46A739AE5BE2C49286, BB54B7D78954ED526A83C3CDA2 -> True
32298B5E785DC394467D5C9CB2, 5ED6AAD93E873EA628B6A4BC47 -> True
B4AB985B34756C624C92DE5E97, 3EDD5BA2A68397C26CE837AD48 -> False
9A6D9A5457BB6ACBC5E8D7D4A9, 73E658CE2C3E289B837422D463 -> True
96E64D226BC8B7D6C5974BAE32, 58DC7A8C543E35978AEBA34D29 -> True
C2978A35E74D7652BA9762C458, 9A9BB332BE8C8DD44CE3DE66A5 -> False
BEDB44E947693CD284923CEA82, 8CC3B75756255A683A6AB9E7DD -> False
EEDDCCBBAA8877665544332299, EEDDCCBBAA9988776655443322 -> False
EEDDCCBBAA9988776655443322, DDCCBBAA9988776655443E3E22 -> True

Referenzimplementierung

Diese Referenzimplementierung ist in Python 3 geschrieben und nimmt Eingaben im gleichen Format vor wie die Testfälle (außer durch ein Komma und ein Leerzeichen getrennt).

#!/usr/bin/env python3

from collections import deque

p1, p2 = [deque(s) for s in (input(),input())]
print(''.join(p1))
print(''.join(p2))

try:
    while p1 and p2:
        p1s = [p1.popleft()]
        p2s = [p2.popleft()]
        while p1s[-1] == p2s[-1]:
            p1s.append(p1.popleft())
            p2s.append(p2.popleft())
            p1s.append(p1.popleft())
            p2s.append(p2.popleft())
        if p1s[-1] > p2s[-1]:
            p1.extend(p2s+p1s)
        else:
            p2.extend(p1s+p2s)
except IndexError:
    pass
finally:
    print(len(p1) > 0)
Mego
quelle
2
Related
Bassdrop Cumberwubwubwub
1
Für ein Kartenspiel hat 1, 2, 3das Spiel kein Ende, da Sie immer wieder die Karten Ihres Gegners gewinnen 1. Ist das eine Eigenheit, eine ungerade Anzahl von Karten zu haben?
Neil
@Neil Welches Kartenspiel hat eine 1?
Suever
@Tut mir leid, ich habe nicht zu viel nachgedacht, ich habe nur die ersten drei verschiedenen Zahlen ausgewählt, die mir in den Kopf kamen. Wähle einfach drei Karten aus, wobei die erste die niedrigste ist.
Neil
@Neil Ich gebe dir nur eine harte Zeit :) Punkt genommen!
Suever

Antworten:

3

JavaScript (ES6), 134 Byte

f=([p,...r],[q,...s],t=[],u=[],v)=>!q||p&&(v|p==q?f(r,s,[...t,p],[...u,q],!v):p>q?f([...r,...u,q,...t,p],s):f(r,[...s,...t,p,...u,q]))
<div oninput=o.checked=f(p.value,q.value)>
Player 1's cards: <input id=p><br>
Player 2's cards: <input id=q><br>
<input id=o type="checkbox"> Player 2 loses

Kehre zurück, undefinedwenn Spieler 2 gewinnt, trueansonsten. Akzeptiert vergleichbare Iteratoren, normalerweise Arrays aus ganzen Zahlen oder hexadezimalen Zeichenfolgen. Die Antwort besteht aus über 22% der .Zeichen, was meiner Meinung nach ein Rekord für mich sein muss.

Neil
quelle
Ich scheine nicht die richtigen Ergebnisse zu erzielen, wenn ich dies mit den Testfällen versuche. Siehe jsfiddle.net/xbq5xzco
Chuck Morris
@ChuckMorris Tut mir leid, ich hatte eine der Regeln übersehen. Sollte jetzt behoben sein.
Neil
@Mego Versuch es nochmal, ich habe es gerade aktualisiert.
Neil
Alles scheint jetzt zu überprüfen.
Mego
OK, jetzt bin ich beeindruckt!
Chuck Morris
4

Python, 160 (155?) Bytes

f=lambda x,y,z=1:f(*((x,y,z+2),(x[z:]+y[:z]+x[:z],y[z:]),(x[z:],y[z:]+x[:z]+y[:z]))[(x[z-1]>y[z-1])+(x[z-1]<y[z-1])*2])if len(y)>z<len(x)else len(x)>len(y)

Diese Lösung ist theoretisch gültig, erfordert jedoch, dass die maximale Standard-Python-Rekursionstiefe für einige der Testfälle erhöht wird.

Die zweite Lösung ist 5 Byte länger, funktioniert aber für alle Testfälle.

f=lambda x,y,z=1:(f(x,y,z+2)if x[z-1]==y[z-1]else f(x[z:]+y[:z]+x[:z],y[z:])if x[z-1]>y[z-1]else f(x[z:],y[z:]+x[:z]+y[:z]))if len(y)>z<len(x)else len(x)>len(y)

Edit: Ungolfed Lösung 1:

def f(x,y,z=1):
    if len(y)<z>len(x):
        return len(x)>len(y)
    else:
        return f(*(
            (x,y,z+2),
            (x[z:],y[z:]+x[:z]+y[:z]),
            (x[z:]+y[:z]+x[:z],y[z:])
        )[(x[z-1]>y[z-1])+(x[z-1]<y[z-1])*2])
Lulhum
quelle
Da IronPython die erste Lösung in Ordnung bringt (die Standard-Rekursionstiefe ist unbegrenzt), werde ich sagen, dass die erste Lösung gültig ist.
Mego
2

Python, 261 bis 265 Bytes

def f(a,b):
 if a==""or b=="":return b==""
 p=a[0];q=b[0];a=a[1:];b=b[1:]
 if p>q:a+=q+p
 if p<q:b+=p+q
 while p[-1]==q[-1]:
  if len(a)<2 or len(b)<2:return len(b)<2
  v=a[1];w=b[1];p+=a[0:2];q+=b[0:2];a=a[2:];b=b[2:]
  if v>w:a+=q+p
  if v<w:b+=p+q
 return f(a,b)

Wie angegeben sind dies 265 Bytes, und dies funktioniert sowohl in Python 2 als auch in Python 3. Sie können in Python 2 4 Bytes speichern, indem Sie die Leerzeichen durch einen einzelnen Tabulator in der while-Schleife ersetzen.

Probieren Sie es online aus

Chuck Morris
quelle
2

Haskell, 372

Mein erstes Haskell-Programm

(Es ist auch meine erste funktionale Programmierung ...)

w[]_=False
w _[]=True
w a b=if length j==0 then a>b else w (drop(d$head j)a++fst(head j))(drop(d$head j)b++snd(head j))where j=p a b
d(a,b)=quot(maximum[length a,length b])2
f (Just a)=a
p a b=map f$filter(/=Nothing)[t(a!!x,take(x+1)a,b!!x,take(x+1)b)|x<-[0,2..minimum[length a,length b]-1]]
t(a,b,c,d)=if a==c then Nothing else if a>c then Just(d++b,[])else Just([],b++d)

Ich hätte gerne Tipps zur Verbesserung.

Verwendung:

w "D58B35926B92C7C4C7E8D3DAA2" "8E47C38A2DEA43467EB9566B95"
w "669D9D846D4B3BA52452C2EDEB" "E747CA988CC76723935A3B8EA5"
w "5744B95ECDC6D325B28A782A72" "68394D9DA96EBBA8533EE7C6C4"
w "87DB6C7EBC6C8D722389923DC6" "E28435DBEBEA543AA47956594A"
w "589EAB9DCD43E9EC264A5726A8" "48DC2577BD68AB9335263B7EC4"
w "E3698D7C46A739AE5BE2C49286" "BB54B7D78954ED526A83C3CDA2"
w "32298B5E785DC394467D5C9CB2" "5ED6AAD93E873EA628B6A4BC47"
w "B4AB985B34756C624C92DE5E97" "3EDD5BA2A68397C26CE837AD48"
w "9A6D9A5457BB6ACBC5E8D7D4A9" "73E658CE2C3E289B837422D463"
w "96E64D226BC8B7D6C5974BAE32" "58DC7A8C543E35978AEBA34D29"
w "C2978A35E74D7652BA9762C458" "9A9BB332BE8C8DD44CE3DE66A5"
w "BEDB44E947693CD284923CEA82" "8CC3B75756255A683A6AB9E7DD"
w "EEDDCCBBAA8877665544332299" "EEDDCCBBAA9988776655443322"
w "EEDDCCBBAA9988776655443322" "DDCCBBAA9988776655443E3E22"

Haskell ist schnell ... :)

real    0m0.039s
user    0m0.022s
sys     0m0.005s
Zylviij
quelle