Explosiones en un tablero de ajedrez

14

Ajedrez atómico es una variante (muy divertida) del ajedrez en la que cada captura provoca una "explosión", destruyendo la pieza capturada, la pieza que captura y todos los no peones en un radio de 1 cuadrado. El objetivo de este desafío no es jugar un juego completo de ajedrez atómico, sino simplemente simular lo que sucede cuando se realiza un movimiento determinado.

Descargo de responsabilidad: efectos de sonido de explosión no incluidos.

Entrada

La posición del consejo se dará en notación Forsyth-Edwards (comúnmente conocida como FEN), pero solo con el primer campo. Por ejemplo, una entrada de:

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

representa la posición inicial:

Posición inicial del ajedrez.

Esto debe tomarse como una cadena o el equivalente de su idioma. Se garantiza que sea válido; por ejemplo, no tienes que preocuparte si hay diez reyes o si no hay ningún rey.

También se le dará el movimiento que debe simular, que se representa como dos nombres cuadrados: el cuadrado sobre el que se mueve la pieza y el cuadrado al que se mueve. Por ejemplo, mover el peón del rey dos espacios hacia adelante en la imagen de arriba se representaría como:

e2e4

Esto también debe tomarse como una cadena. El movimiento siempre será válido, y no necesitas soportar el enroque . Necesitas apoyo en passant , que se explicará con más detalle en la siguiente sección.

Salida

La salida de su programa debe estar en la misma notación FEN parcial que la entrada, con el movimiento especificado realizado (y cualquier pieza explotada si es necesario).

Las reglas exactas para las explosiones son: cuando se captura una pieza:

  • Elimine la pieza que se está capturando (esta siempre será la pieza en el segundo cuadrado nombrado en la entrada, excepto cuando la captura es pasante ).

  • Retire la pieza que está haciendo la captura (esta siempre será la pieza en el primer cuadrado nombrado en la entrada).

  • Retire cada pieza que sea:

    • ubicado en una de las 8 casillas que rodean al lugar donde tuvo lugar la captura (para pasar , esta es la casilla en la que estaría el peón de captura, si no explotara).

    • No es un peón.

Resumen rápido de las reglas pasantes , para aquellos que no están familiarizados: si un peón se mueve dos espacios hacia adelante desde su rango inicial, y hay un peón que podría haberlo capturado si solo se moviera una casilla hacia adelante, puede capturarlo de todos modos, pero solo en el movimiento posterior. Se dice que esta captura se realiza " de pasada " (o en francés: " en passant ").

Casos de prueba

En las imágenes, las flechas verdes reprimen el movimiento que se va a realizar, y los círculos verdes representan piezas que explotan.

Entrada: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR, g1f3
Salida:rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R
Caso de prueba 1.


Entrada: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P1pP/2rP1P2/R1B3RK, f2g3
salida: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P2P/2rP4/R1B3RK
Caso de prueba 2.
(robado de http://en.lichess.org/ocoSfS5I/white#36 )


Entrada: rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R , f3b7
salida: 3qk1nr/2p5/p2pp1pp/5p2/1bN5/2P1P2N/PP1P1PPP/R1B1KB1R
Caso de prueba 3.
(robado de http://en.lichess.org/NCUnA6LV/white#14 )


Entrada: rnbqk2r/pp2p2p/2p3pb/3pP3/5P2/2N5/PPPP2P1/R1BQKB1R,e5d6
Salida: rnbqk2r/pp2p2p/2p3pb/8/5P2/2N5/PPPP2P1/R1BQKB1R
Caso de prueba 4.
(robado de http://en.lichess.org/AvgU4Skq/white#16 , lo que no era el movimiento real, pero no podía ser molestado a encontrar un juego atómica que en realidad tenía en passant: PAG)


Entrada: 5r2/2k5/p1B5/1pP1p3/1P4P1/3P4/P7/1K3R1q , c6h1
salida: 5r2/2k5/p7/1pP1p3/1P4P1/3P4/P7/1K3R2
Caso de prueba 5.
(robado de http://en.lichess.org/l77efXEb/white#58 )

Puntuación

Este es el , por lo que gana el código más corto en bytes.

Pomo de la puerta
fuente
Entonces ... ¿tomar una pieza con tu rey es una mala idea?
mbomb007
@ mbomb007 No tienes permitido tomar piezas con tu rey. : P
Pomo de la puerta
Podría estar equivocado, pero ¿cómo se supone que debemos saber si la captura al paso es posible? En su ejemplo, el último movimiento se denota con el cuadrado verde vacío, por lo que el peón negro se puede capturar de pasada. Pero esta información no está contenida en las entradas que se nos dan, por lo que es posible tener exactamente la misma tabla pero donde la captura al paso no es posible, porque el último movimiento no fue un movimiento hacia adelante de dos espacios.
Fatalize
1
@Fatalize " El movimiento siempre será válido " - desde la sección "Entrada".
Pomo de la puerta
Programa completo o función?
edc65

Respuestas:

5

JavaScript ( ES6 ) 305 310 321

Como una función con 2 parámetros reales (y mucho más con valores predeterminados, utilizados como una forma rápida y sucia para definir locales)

Pruebe a ejecutar el fragmento a continuación (siendo EcmaScript 6, solo Firefox)

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>

Sin 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
fuente
1
Wow, eso parece mucho más simple que mi solución ... ¡Buen trabajo!
cmxu
2

Java, ( 946 777 776 caracteres)

1 char gracias a @ edc65

Nota: los caracteres contados sin poner los casos de prueba.

Código

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

No estoy seguro de si esta solución es óptima, pero estoy trabajando en jugar más al golf, cualquier sugerencia es bienvenida. También puedo comentar todo el código si alguien quisiera, pero creo que en su mayoría se explica por sí mismo, excepto por la confusa enumeración de variables.

Explicación

  • Desempaquete la cadena del tablero en una matriz de caracteres
  • Calcule el efecto del movimiento.
  • Vuelva a embalar el tablero en una cuerda

Expandido

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

Antiguo

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
fuente
String m,i="";m="";char[]n=m.toCharArray()-> String i=a[0];char[]n=a[1].toCharArray()es más corto, por lo que obtienes los parámetros desde el exterior (como deberías de todos modos)
edc65
Ahh, está bien, cambiaré eso, ¡gracias!
cmxu