Déterminer le vainqueur d'un jeu de guerre

19

Le jeu de cartes War est intéressant en ce que le résultat final est entièrement déterminé par l'arrangement initial du jeu, tant que certaines règles sont suivies pour l'ordre dans lequel les cartes sont ramassées sur le terrain de jeu et déplacées vers les jeux. Dans ce défi, il n'y aura que 2 joueurs, ce qui simplifie grandement les choses.

Le jeu

  1. Chaque joueur reçoit un jeu de 26 cartes.
  2. Chaque joueur place la carte du dessus dans son paquet face visible. Le joueur avec la carte de rang le plus élevé ( Ace > King > Queen > Jack > 10 > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2) remporte la manche et place sa carte au-dessus de la carte de son adversaire, la retourne et l'ajoute au bas de son deck (donc sa carte gagnante se trouve au bas du deck) , et la carte perdante de l'autre joueur est juste au-dessus). Cela se fait jusqu'à ce que l'un des joueurs manque de cartes.
    • Si les cartes sont de rang égal, alors chaque joueur place les 2 cartes du dessus de son paquet face visible au-dessus de sa carte précédente (de sorte que la carte qui était au-dessus du paquet est la deuxième carte de la pile, et le carte qui était en deuxième position est en haut). Ensuite, les rangs (de la carte du haut de chaque pile) sont à nouveau comparés, et le gagnant place sa pile entière au-dessus de la pile entière du perdant, retourne la pile à l'envers et la place au bas de son deck. S'il y a une autre égalité, plus de cartes sont jouées de la même manière, jusqu'à ce qu'un gagnant soit choisi ou qu'un joueur manque de cartes.

Si à tout moment l'un des joueurs a besoin de piocher une carte de son deck, mais que son deck est vide, il perd immédiatement la partie.

Le défi

Étant donné deux listes de cartes dans les decks des joueurs, dans n'importe quel format pratique, affichez une valeur véridique si le joueur 1 gagne et une valeur de falsey si le joueur 2 gagne.

Pour plus de commodité, une carte de 10 sera représentée par un T, et les cartes de visage seront abrégées ( Ace -> A, King -> K, Queen -> Q, Jack -> J), de sorte que toutes les cartes ont un caractère. Alternativement, les rangs peuvent être représentés par des nombres décimaux 2-14 ( Jack -> 11, Queen -> 12, King -> 13, Ace -> 14) ou des chiffres hexadécimaux 2-E ( 10 -> A, Jack -> B, Queen -> C, King -> D, Ace -> E). Étant donné que les costumes n'ont pas d'importance, les informations sur les costumes ne seront pas fournies.

  • Vous pouvez supposer que tous les jeux se termineront à un moment donné (bien que cela puisse prendre très longtemps), et un joueur sera toujours à court de cartes avant l'autre.
  • Chaque joueur place des cartes simultanément et une carte à la fois, il n'y a donc jamais d'ambiguïté sur le joueur qui a manqué de cartes en premier.

Cas de test

Les cas de test servent 23456789ABCDEà représenter les rangs (dans l'ordre croissant).

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

Implémentation de référence

Cette implémentation de référence est écrite en Python 3 et prend les entrées dans le même format que les cas de test (sauf séparées par une nouvelle ligne au lieu d'une virgule et d'un espace).

#!/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
la source
2
En relation
Bassdrop Cumberwubwubwub
1
Pour un jeu de cartes, 1, 2, 3le jeu n'a pas de fin car vous continuez à gagner celui de votre adversaire 1. Est-ce une bizarrerie d'avoir un nombre impair de cartes?
Neil
@Neil Quel jeu de cartes a- 1t -il ?
Suever
@Suever Désolé, je n'ai pas trop réfléchi, je viens de choisir les trois premiers numéros différents qui me sont venus à l'esprit. Choisissez simplement trois cartes où la première est la plus basse.
Neil
@Neil Je vous donne juste du fil à retordre :) Point pris!
Suever

Réponses:

3

JavaScript (ES6), 134 octets

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

Revenez undefinedsi le joueur 2 gagne, truesinon. Accepte des itérateurs comparables, généralement des tableaux d'entiers ou des chaînes de caractères hexadécimaux. La réponse est composée de plus de 22% de .caractères, ce qui, je pense, doit être un record pour moi.

Neil
la source
Je ne semble pas obtenir les bons résultats lorsque j'essaie ceci avec les cas de test. Voir jsfiddle.net/xbq5xzco
Chuck Morris
@ChuckMorris Désolé, j'avais négligé l'une des règles. Devrait être corrigé maintenant.
Neil
@Mego Réessayez, je viens de le mettre à jour.
Neil
Tout semble vérifier maintenant.
Mego
OK, maintenant je suis impressionné!
Chuck Morris
4

Python, 160 (155?) Octets

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)

Cette solution est théoriquement valide, mais elle nécessite que la profondeur de récursivité maximale par défaut de Python soit augmentée pour certains des cas de test.

La deuxième solution est plus longue de 5 octets, mais fonctionne pour tous les cas de test.

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: Solution non golfée 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
la source
Étant donné qu'IronPython exécutera la première solution correctement (la profondeur de récursivité par défaut est illimitée), je vais dire que la première solution est valide.
Mego
2

Python, 261 à 265 octets

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)

Tel que publié, cela fait 265 octets et cela fonctionne à la fois dans Python 2 et Python 3. Vous pouvez enregistrer 4 octets dans Python 2 en remplaçant les espaces par un seul onglet dans la boucle while.

Essayez-le en ligne

Chuck Morris
la source
2

Haskell, 372

Mon premier programme Haskell

(C'est aussi ma première programmation fonctionnelle ...)

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)

J'aimerais avoir des conseils sur la façon de s'améliorer.

Usage:

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 est rapide ... :)

real    0m0.039s
user    0m0.022s
sys     0m0.005s
Zylviij
la source