Explosions sur un échiquier

14

Échecs atomiques sont une variante (très amusante) des échecs dans laquelle chaque capture provoque une "explosion", détruisant la pièce capturée, la pièce faisant la capture et tous les non-pions dans un rayon de 1 carré. Le but de ce défi n'est pas de jouer une partie entière d'échecs atomiques, mais simplement de simuler ce qui se passe lorsqu'un certain mouvement est effectué.

Avertissement: Effets sonores d'explosion non inclus.

Contribution

La position du conseil sera donnée dans la notation Forsyth-Edwards (communément appelée FEN), mais avec seulement le premier champ. Par exemple, une entrée de:

rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR

représente la position de départ:

Position de départ des échecs.

Cela doit être considéré comme une chaîne ou l'équivalent de votre langue. Il est garanti d'être valide; par exemple, vous n'avez pas à vous soucier s'il y a dix rois, ou s'il n'y a pas de roi du tout.

Vous recevrez également le mouvement que vous devez simuler, qui est représenté par deux noms de carré: le carré sur lequel se trouve la pièce à déplacer et le carré vers lequel elle se déplace. Par exemple, déplacer le pion du roi de deux cases vers l'avant sur l'image ci-dessus serait représenté comme suit:

e2e4

Cela doit également être considéré comme une chaîne. Le mouvement sera toujours valide et vous n'avez pas besoin de prendre en charge le roque . Vous devez prendre en charge en passant , ce qui sera expliqué plus en détail dans la section suivante.

Production

La sortie de votre programme doit être dans la même notation FEN partielle que l'entrée, avec le mouvement spécifié effectué (et toutes les pièces explosées si nécessaire).

Les règles exactes pour les explosions sont - quand un morceau est capturé:

  • Retirez la pièce en cours de capture (ce sera toujours la pièce sur le deuxième carré nommé dans l'entrée, sauf lorsque la capture est en passant ).

  • Supprimez la pièce qui effectue la capture (ce sera toujours la pièce sur le premier carré nommé dans l'entrée).

  • Retirez chaque pièce qui est:

    • situé sur l'un des 8 carrés entourant celui où la capture a eu lieu (pour en passant , c'est le carré sur lequel le pion capturant serait, s'il n'explosait pas).

    • pas un pion.

Aperçu rapide des règles en passant , pour ceux qui ne sont pas familiers: si un pion se déplace de deux cases vers l'avant depuis son rang de départ, et qu'il y a un pion qui aurait pu le capturer s'il n'avait avancé que d'un carré, il peut le capturer de toute façon, mais uniquement lors du déménagement suivant. Cette capture se ferait " en passant " (ou en français: " en passant ").

Cas de test

Dans les images, les flèches vertes reprennent le mouvement sur le point d'être réalisé et les cercles verts représentent les pièces qui explosent.

Entrée: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR, g1f3
sortie:rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R
Cas de test 1.


Entrée: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P1pP/2rP1P2/R1B3RK, f2g3
sortie: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P2P/2rP4/R1B3RK
Cas de test 2.
(volée à http://en.lichess.org/ocoSfS5I/white#36 )


Entrée: rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R, f3b7
sortie: 3qk1nr/2p5/p2pp1pp/5p2/1bN5/2P1P2N/PP1P1PPP/R1B1KB1R
Cas de test 3.
(volée à http://en.lichess.org/NCUnA6LV/white#14 )


Entrée: rnbqk2r/pp2p2p/2p3pb/3pP3/5P2/2N5/PPPP2P1/R1BQKB1R, e5d6
sortie: rnbqk2r/pp2p2p/2p3pb/8/5P2/2N5/PPPP2P1/R1BQKB1R
Cas de test 4.
(volée http://en.lichess.org/AvgU4Skq/white#16 , ce ne fut pas le mouvement réel, mais je ne pouvais pas être pris la peine de trouver un jeu atomique qui avait fait en passant: P)


Entrée: 5r2/2k5/p1B5/1pP1p3/1P4P1/3P4/P7/1K3R1q, c6h1
sortie: 5r2/2k5/p7/1pP1p3/1P4P1/3P4/P7/1K3R2
Cas de test 5.
(volée à http://en.lichess.org/l77efXEb/white#58 )

Notation

Il s'agit de , donc le code le plus court en octets l'emporte.

Poignée de porte
la source
Alors ... prendre un morceau avec votre roi est une mauvaise idée?
mbomb007
@ mbomb007 Vous n'êtes pas autorisé à prendre des morceaux avec votre roi. : P
Poignée de porte
Je me trompe peut-être, mais comment est-on censé savoir si la capture en passant est possible? Dans votre exemple, le dernier coup est indiqué par le carré vert vide, donc le pion noir peut être capturé en passant. Mais cette information n'est pas contenue dans les entrées qui nous sont données, il est donc possible d'avoir exactement la même planche mais où la capture en passant n'est pas possible, car le dernier mouvement n'était pas un mouvement vers l'avant de deux espaces.
Fatalize
1
@Fatalize " Le déplacement sera toujours valide " - depuis la section "Entrée".
Poignée de porte
Programme ou fonction complet?
edc65

Réponses:

5

JavaScript ( ES6 ) 305 310 321

En tant que fonction avec 2 paramètres réels (et beaucoup plus avec des valeurs par défaut, utilisée comme un moyen rapide et sale de définir les locaux)

Testez l'exécution de l'extrait ci-dessous (étant EcmaScript 6, Firefox uniquement)

F=(g,m,b=[...g.replace(/\d/g,c=>'0'.repeat(c))],P=p=>p=='p'|p=='P',n=parseInt(m,32),
  s=n>>5&31,u=n>>15,x=b[y=u+62-(n>>10&31)*9])=>(
  b[b[y]=0,z=s+62-(n&31)*9]<1&!(s!=u&P(x))?b[z]=x:
  [-1,1,8,9,10,-8,-9,-10].map(i=>b[i+=z]>'/'&&!P(b[i])?b[i]=0:0,b[b[z]<1?z>y?z-9:z+9:z]=0),
  b.join('').replace(/0+/g,x=>x.length)
)

//TEST
out=x=>O.innerHTML+=x+'\n'

test=[
 ['rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR', 'g1f3'
  ,'rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R']
,['3kBb1r/pp5p/3p4/4pn2/P7/1P2P1pP/2rP1P2/R1B3RK', 'f2g3'
  ,'3kBb1r/pp5p/3p4/4pn2/P7/1P2P2P/2rP4/R1B3RK']  
,['rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R', 'f3b7'
  ,'3qk1nr/2p5/p2pp1pp/5p2/1bN5/2P1P2N/PP1P1PPP/R1B1KB1R']
,['rnbqk2r/pp2p2p/2p3pb/3pP3/5P2/2N5/PPPP2P1/R1BQKB1R', 'e5d6'
  ,'rnbqk2r/pp2p2p/2p3pb/8/5P2/2N5/PPPP2P1/R1BQKB1R']
,['5r2/2k5/p1B5/1pP1p3/1P4P1/3P4/P7/1K3R1q', 'c6h1'
  ,'5r2/2k5/p7/1pP1p3/1P4P1/3P4/P7/1K3R2']
]

test.forEach(t=>( 
  r=F(t[0],t[1]), 
  out('Test '+(r==t[2]?'Ok':'Fail!')+'  '+t[0]+' move '+t[1]
     +'\nResult   '+r+'\nExpected '+t[2]+'\n')))
<pre id=O></pre>

Non golfé

B=(b,m)=>{
  P=p=>p=='p'|p=='P'
  m=parseInt(m,32) 
  r=m&31 // arrival row
  s=(m/32&31)-10 // arrival column
  z=s+(8-r)*9 // arrival position
  t=m/32/32&31 // start row
  u=(m/32/32/32&31)-10 // start column
  y=u+(8-t)*9 // start position
  b=[...b.replace(/\d/g,c=>'0'.repeat(c))] // board to array, empty squares as 0
  x=b[y] // moving piece
  b[y]=0 
  C=s!=u&P(x) // pawn capture
  if (b[z]<1 && !C)
  {  // no capture
    b[z]=x
  }
  else
  {
    // capture and boom!
    if (b[z]<1) // arrival empty: en passant
      b[z>y?z-9:z+9]=0;
    else
      b[z]=0;
    // zero to nearest 8 squares
    [-1,1,8,9,10,-8,-9,-10].forEach(i=>b[i+=z]>'/'&&!P(b[i])?b[i]=0:0)
  }
  return b.join('').replace(/0+/g,x=>x.length)
}
edc65
la source
1
Wow, cela semble beaucoup plus simple que ma solution ... Beau travail!
cmxu
2

Java, ( 946 777 776 caractères)

1 caractère grâce à @ edc65

Remarque: les caractères sont comptés sans les cas de test insérés.

Code

class E{public static void main(String[]a){String i=a[0];char[]n=a[1].toCharArray();int j,k,z,w,y,u=56-n[3];char q,p,e ='e';char[][]b=new char[8][8];String[]r=i.split("/");for(j=0;j<8;j++){z=0;for(k=0;k<r[j].length();k++){p=r[j].charAt(k);if(Character.isDigit(p)){for(int l=k+z;l<k+z+p-48;l++)b[j][l]=e;z+=p-49;}else b[j][k+z]=p;}}z=n[0]-97;w=56-n[1];y=n[2]-97;p=b[w][z];q=b[u][y];b[w][z]=e;if(q!=e||((p|32)=='p'&&(w-u<0?u-w:w-u)==1&&(z-y<0?y-z:z-y)==1)){if(q!=e)b[u][y]=e;else b[w][y]=e;for(j=y-(y==0?0:1);j<y+(y==8?0:y==7?1:2);j++){for(k=u-(u==0?0:1);k<u+(u==8?0:u==7?1:2);k++)if((b[k][j]|32)!='p')b[k][j]=e;}}else b[u][y]=p;i="";for(j=0;j<8;j++){z=0;for(k=0;k<8;k++){if(b[j][k]==e)z++;else {if(z>0){i+=z;z=0;}i+=b[j][k];}}if(z>0)i+=z;i+=j!=7?"/":"";}System.out.print(i);}}

Je ne sais pas si cette solution est optimale, mais je travaille plus sur le golf, toutes les suggestions sont les bienvenues. Je peux également commenter tout le code si quelqu'un le souhaite, mais je pense qu'il est principalement explicite, à l'exception de l'énumération des variables déroutante.

Explication

  • Déballez la chaîne du conseil d'administration dans une matrice de caractères
  • Calculez l'effet du mouvement
  • Remballez le tableau en une chaîne

Étendu

class ExplosionChess{
    public static void main(String[]a){
        String i=a[0];
        //"rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R";
        //"f3b7";
        char[]n=a[1].toCharArray();
        int j,k,z,w,y,u=56-n[3];
        char q,p,e ='e';
        char[][]b=new char[8][8];
        String[]r=i.split("/");
        for(j=0;j<8;j++){
            z=0;
            for(k=0;k<r[j].length();k++){
                p=r[j].charAt(k);
                if(Character.isDigit(p)){
                    for(int l=k+z;l<k+z+p-48;l++)
                        b[j][l]=e;
                    z+=p-49;
                }else 
                    b[j][k+z]=p;
            }
        }
        z=n[0]-97;
        w=56-n[1];
        y=n[2]-97;
        p=b[w][z];
        q=b[u][y];
        b[w][z]=e;
        if(q!=e||((p|32)=='p'&&(w-u<0?u-w:w-u)==1&&(z-y<0?y-z:z-y)==1)){
            if(q!=e)
                b[u][y]=e;
            else
                b[w][y]=e;
            for(j=y-(y==0?0:1);j<y+(y==8?0:y==7?1:2);j++){
                for(k=u-(u==0?0:1);k<u+(u==8?0:u==7?1:2);k++)
                    if((b[k][j]|32)!='p')
                        b[k][j]=e;
            }
        }else 
            b[u][y]=p;
        i="";
        for(j=0;j<8;j++){
            z=0;
            for(k=0;k<8;k++){
                if(b[j][k]==e)
                    z++;
                else {
                    if(z>0){
                        i+=z;
                        z=0;
                    }
                    i+=b[j][k];
                }
            }
            if(z>0)
                i+=z;
            i+=j!=7?"/":"";
        }
        System.out.print(i);
    }
}

Vieux

class E{public static void main(String[]a){String m,i="rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R";m="f3b7";char[]n=m.toCharArray();int z,w,y,u=56-n[3];z=n[0]-97;w=56-n[1];y=n[2]-97;char e='e';char[][]b=new char[8][8];String[]r=i.split("/");for(int j=0;j<8;j++){int o=0;for(int k=0;k<r[j].length();k++){char q=r[j].charAt(k);if(Character.isDigit(q)){for(int l=k+o;l<k+o+q-48;l++){b[j][l]=e;}o+=q-49;}else b[j][k+o]=q;}}char q,p=b[w][z];q=b[u][y];b[w][z]=e;if(q==e){if((p|32)=='p'&&(w-u<0?u-w:w-u)==1&&(z-y<0?y-z:z-y)==1){b[w][y]=e;for(int j=y-(y==0?0:1);j<y+(y==8?0:y==7?1:2);j++){for(int k=u-(u==0?0:1);k<u+(u==8?0:u==7?1:2);k++){if((b[k][j]|32)!='p')b[k][j]=e;}}}else{b[u][y]=p;}}else{b[u][y]=e;for(int j=y-(y==0?0:1);j<y+(y==8?0:y==7?1:2);j++){for(int k=u-(u==0?0:1);k<u+(u==8?0:u==7?1:2);k++){if((b[k][j]|32)!='p')b[k][j]=e;}}}i="";for(int j=0;j<8;j++){int x=0;for(int k=0;k<8;k++){if(b[j][k]==e)x++;else{if(x>0){i+=x;x=0;}i+=b[j][k];}}if(x>0)i+=x;i+=j!=7?"/":"";}System.out.println(i);}}
cmxu
la source
String m,i="";m="";char[]n=m.toCharArray()-> String i=a[0];char[]n=a[1].toCharArray()est plus court et vous obtenez donc les paramètres de l'extérieur (comme vous devriez quand même)
edc65
Ahh, ok je vais changer ça, merci!
cmxu