Gagnez une partie de Load, Defend et Shoot

11

Quand j'étais enfant, je jouais beaucoup à ce jeu.

Règles

Il y a deux joueurs (appelons-les A et B), et chaque joueur utilise ses mains comme des fusils. Il y a trois mouvements possibles:

  1. Levez la main pour charger des munitions dans votre arme.

    Chaque pistolet démarre vide. Le chargement augmente les munitions d'une unité.

  2. Mains pointant vers l'autre joueur pour tirer.

    Cela diminue les munitions d'une unité. Vous devez avoir au moins une unité de munitions pour tirer.

  3. Bras croisés pour vous protéger d'un coup de feu.

Les deux joueurs se déplacent simultanément. Si les deux joueurs tirent en même temps, les balles se touchent et le jeu continue. Le jeu se termine lorsqu'un joueur tire pendant que l'autre charge des munitions.

Le tir et l'arme vide sont considérés comme de la tricherie . Si un joueur triche alors que l'autre exécute une action en justice, le tricheur perd immédiatement. Si les deux joueurs trichent en même temps, le jeu continue.

Les tentatives de tricherie ne diminuent pas les munitions, elles ne peuvent donc jamais être négatives.

Défi

Compte tenu des mouvements effectués par les joueurs A et B, sortez quel joueur a gagné la partie: 1pour le joueur A, -1pour le joueur B et 0pour un match nul. Vous pouvez utiliser tout autre triple de valeur de retour, mais vous devez indiquer dans votre réponse celles que vous utilisez.

Le jeu peut:

  • terminer sans avoir à traiter tous les mouvements;
  • ne se termine pas avec les mouvements donnés, et il est donc considéré comme un match nul.

L'entrée peut être prise:

  • sous forme de chaînes
  • sous forme de tableaux / listes d'entiers
  • de toute autre manière qui ne pré-traite pas l'entrée

Programme complet ou fonctions autorisées. Puisqu'il s'agit de , la réponse la plus courte en octets gagne!

Cas de test

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
supprimé
la source
1
KotH connexe (intéressant, je n'ai jamais joué à cette variante du jeu; je pense que la question liée a été inspirée par un ami qui l'a fait, mais il y a assez longtemps que je ne m'en souviens plus).
Poignée de porte

Réponses:

6

Gelée, 33 32 24 octets

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

Cela imprime 5 au lieu de -1 et 7 au lieu de 1 . Essayez-le en ligne! ou vérifiez tous les cas de test .

Comment ça fonctionne

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
la source
2

Pyth, 48 46 49 47 octets

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

Essayez-le ici!

Merci à @isaacg pour avoir économisé 2 4 octets!

Prend l'entrée en 2-tuple avec la liste des mouvements du joueur A en premier et les mouvements du joueur B en second. La sortie est la même que dans le défi.

Explication

Bref aperçu

  • Nous regroupons d'abord les mouvements des deux joueurs, nous obtenons donc une liste de 2 tuples.
  • Ensuite, nous mappons chacun de ces tuples sur un autre 2-tuple sous la forme [cheating win, fair win]avec les valeurs possibles -1, 0, 1pour chacun d'eux, pour indiquer si un joueur a gagné à ce point ( -1, 1) ou si le jeu continue ( 0)
  • Maintenant, nous avons juste besoin d'obtenir le premier tuple qui ne l'est pas [0,0], et de prendre le premier élément non nul qui indique le gagnant

Répartition du code

.xhfT | Me, -FmgF.b / <dhkY2S2Q?} b_BS2-FbZ.b, NYCQ) 0 # Q = liste des listes de déplacements

                                      .b, NYCQ # associe les éléments des deux listes d'entrée
       .e # mappe la liste des paires avec 
                                                 # b étant la paire et k son index
            m Q # mappe chaque liste de coups d
               .b Carte 2S2 # sur [1,2], je ne peux pas utiliser m car c'est
                                                 # La variable lambda est en conflit avec celle de .e
                  <dhk # d [: k + 1]
                 / Y # nombre d'occurrences de 1 ou 2 dans cette liste
          -F # (compte de 1s) - (compte de 2s), indique la victoire de triche
                           ?} b_BS2 # si b est (1,2) ou (2,1)
                                  -Fb # faire la différence, indique une victoire équitable
                                     Z # else 0, pas encore de gagnant
         , # associez ces 2 valeurs
     | M # Pour chaque paire résultante, prenez la première si
                                                 # ce n'est pas zéro, sinon le second
   fT # filtre toutes les valeurs nulles
.xh # essayez de prendre la première valeur qui indique le gagnant
                                             ) 0 # si ce n'est pas possible car la liste est vide
                                                 # sortie zéro pour indiquer un tirage
Denker
la source
m|Fdest le même que |M.
isaacg
@isaacg Merci! J'oublie toujours que Mça éclabousse aussi. Btw: Le problème des variables lambda conflictuelles dont nous avons discuté dans le chat me coûte plusieurs octets ici: P
Denker
,1 2est le même queS2
isaacg
J'ai ajouté un autre testcase;)
supprimé
@isaacg Merci encore! Je ne sais pas comment j'ai raté ça.
Denker
1

Python, 217 octets

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

Explication : prend A et B comme listes d'entiers. Exécute simplement chaque paire de mouvements, ajoute ou soustrait 1 si nécessaire et revient lorsque quelqu'un triche ou gagne. Fait la même chose deux fois en utilisant une autre pour la boucle, une fois pour le mouvement de A et une fois pour le mouvement de B. Ajoute 1 si x passe en dessous de 0 à -1.

Melon fricatif
la source
1

Java, 226 212 200 196 194 octets

-14 octets par logique de réorganisation

-12 octets grâce à Mr Public expliquant comment utiliser une opération ternaire pour la logique de prise de vue

-4 octets en entassant la logique de charge en un court-circuit si

-2 octets car ==1=== <2lorsque l' entrée ne peut être 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;}

Utilisation et version en retrait:

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}));
}

La mise en œuvre des règles du jeu n'est plus aussi simple, mais simple. A chaque cycle, ces opérations:

  • La charge se déplace dans les variables temporaires
  • Si le joueur a tiré
    • sans munitions: les préjugés trichent rpour perdre
    • avec des munitions: décrémenter les munitions
  • Si ce rn'est pas le cas 0, renvoyez la valeur car quelqu'un a triché
  • Si le joueur a rechargé
    • incrémenter les munitions
    • si un autre joueur tire, perdez le retour

x est une variable fictive utilisée pour que le compilateur me permette d'utiliser une expression ternaire.

Attendez, Java est plus court que Python?

CAD97
la source
J'ai ajouté un autre testcase;)
supprimé
1
@WashingtonGuedes Et le mien travaille sur ce cas grâce à ma logique de réorganisation!
CAD97
Les ifs peuvent-ils être transformés en ternaires? par exemplew==2&&m<1?r--:m++
Downgoat
@Downgoat le reste va avec l'intérieur si tel que vous l'avez écrit, le tertiaire ne fonctionnerait pas. Cependant, je peux probablement le faire avec l'intérieur si. Je le testerai quand j'aurai une chance.
CAD97
1
@ CAD97 @Downgoat Vous pouvez réellement utiliser des opérateurs ternaires pour les instructions if. Pour le premier ternaire, int x=w==2?m<1?r--:r:m--;continuez à utiliser le x (car ce n'est qu'une variable fictive pour faire fonctionner le ternaire) commex=v==2?n<1?r++:r:n--;
Mr Public