Esplosioni su una scacchiera


14

Gli scacchi atomici sono una variante (molto divertente) di scacchi in cui ogni cattura provoca una "esplosione", distruggendo il pezzo catturato, il pezzo che cattura e tutti i non pedoni in un raggio di 1 quadrato. L'obiettivo di questa sfida non è giocare un'intera partita di scacchi atomici, ma semplicemente simulare ciò che accade quando viene effettuata una determinata mossa.

Dichiarazione di non responsabilità: effetti sonori di esplosione non inclusi.

Ingresso

La posizione del consiglio sarà data nella notazione Forsyth-Edwards (comunemente nota come FEN), ma con solo il primo campo. Ad esempio, un input di:

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

rappresenta la posizione iniziale:

Posizione di partenza degli scacchi.

Questo deve essere preso come una stringa o l'equivalente della tua lingua. È garantito per essere valido; per esempio, non devi preoccuparti se ci sono dieci re o se non c'è nessun re.

Ti verrà anche data la mossa che devi simulare, che è rappresentata da due nomi quadrati: il quadrato su cui si trova il pezzo da spostare e il quadrato su cui si sta muovendo. Ad esempio, spostare la pedina del re di due spazi in avanti sull'immagine sopra sarebbe rappresentata come:

e2e4

Anche questo deve essere considerato come una stringa. La mossa sarà sempre valida e non è necessario supportare il castling . È necessario supportare en passant , che verrà spiegato in maggior dettaglio nella sezione successiva.

Produzione

L'output del tuo programma dovrebbe essere nella stessa notazione FEN parziale dell'input, con la mossa specificata fatta (ed eventuali pezzi esplosi se necessario).

Le regole esatte per le esplosioni sono — quando un pezzo viene catturato:

  • Rimuovi il pezzo da catturare (questo sarà sempre il pezzo sul secondo quadrato indicato nell'input, tranne quando la cattura è un en passant ).

  • Rimuovi il pezzo che sta catturando (questo sarà sempre il pezzo sul primo quadrato indicato nell'input).

  • Rimuovi ogni pezzo che sia:

    • situato su uno degli 8 quadrati che circondano quello in cui è avvenuta la cattura (per en passant , questo è il quadrato su cui si troverebbe il pedone di cattura, se non esplodesse).

    • non una pedina.

Panoramica rapida delle regole en passant , per coloro che non hanno familiarità: se una pedina si sposta di due spazi in avanti dal suo rango iniziale, e c'è una pedina che avrebbe potuto catturarla se si fosse spostata di un solo quadrato in avanti, potrebbe catturarla comunque, ma solo sulla mossa successiva. Si dice che questa cattura sia fatta " di passaggio " (o in francese: " en passant ").

Casi test

Nelle immagini, le frecce verdi rappresentano la mossa che sta per essere eseguita, mentre i cerchi verdi rappresentano i pezzi esplosi.

Ingresso: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR, g1f3
Uscita:rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R
Caso di prova 1.


Ingresso: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P1pP/2rP1P2/R1B3RK, f2g3
Uscita: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P2P/2rP4/R1B3RK
Caso di prova 2.
(rubato da http://en.lichess.org/ocoSfS5I/white#36 )


Ingresso: rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R, f3b7
Uscita: 3qk1nr/2p5/p2pp1pp/5p2/1bN5/2P1P2N/PP1P1PPP/R1B1KB1R
Caso di prova 3.
(rubato da http://en.lichess.org/NCUnA6LV/white#14 )


Ingresso: rnbqk2r/pp2p2p/2p3pb/3pP3/5P2/2N5/PPPP2P1/R1BQKB1R, e5d6
Uscita: rnbqk2r/pp2p2p/2p3pb/8/5P2/2N5/PPPP2P1/R1BQKB1R
Caso di prova 4.
(rubata da http://en.lichess.org/AvgU4Skq/white#16 , questo non era il movimento reale, ma non ho potuto essere disturbati per trovare un gioco atomica che effettivamente avuto en passant: P)


Ingresso: 5r2/2k5/p1B5/1pP1p3/1P4P1/3P4/P7/1K3R1q, c6h1
Uscita: 5r2/2k5/p7/1pP1p3/1P4P1/3P4/P7/1K3R2
Caso di prova 5.
(rubato da http://en.lichess.org/l77efXEb/white#58 )

punteggio

Questo è , quindi vince il codice più breve in byte.


Quindi ... prendere un pezzo con il tuo re è una cattiva idea?
mbomb007,

@ mbomb007 Non ti è permesso prendere pezzi con il tuo re. : P
Maniglia della porta

Potrei sbagliarmi, ma come possiamo sapere se la cattura en passant è possibile? Nel tuo esempio l'ultima mossa è indicata dal quadrato verde vuoto, quindi il pedone nero può essere catturato en passant. Ma queste informazioni non sono contenute negli input che ci vengono dati, quindi è possibile avere esattamente la stessa scheda ma dove non è possibile la cattura en passant, perché l'ultima mossa non era una mossa in avanti di due spazi.
Fatalizza il

1
@Fatalize " Lo spostamento sarà sempre valido " - dalla sezione "Input".
Maniglia della porta

Programma o funzione completi?
edc65

Risposte:


5

JavaScript ( ES6 ) 305 310 321

Come funzione con 2 parametri reali (e molto altro con valori predefiniti, utilizzato come modo rapido e sporco per definire i locali)

Prova a eseguire lo snippet di seguito (essendo 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>

Ungolfed

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

1
Wow, sembra molto più semplice della mia soluzione ... Bel lavoro!
cmxu,

2

Java, ( 946 777 776 caratteri)

1 carattere grazie a @ edc65

Nota: i caratteri vengono conteggiati senza l'inserimento di casi di test.

Codice

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

Non sono sicuro che questa soluzione sia ottimale, ma sto lavorando di più sul golf, qualsiasi suggerimento è il benvenuto. Posso commentare tutto il codice anche se qualcuno lo desidera, ma penso che sia per lo più autoesplicativo, ad eccezione dell'enumerazione delle variabili confusa.

Spiegazione

  • Disimballare la stringa della scheda in una matrice di caratteri
  • Calcola l'effetto della mossa
  • Reimballare la scheda in una stringa

allargato

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

Vecchio

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

String m,i="";m="";char[]n=m.toCharArray()-> String i=a[0];char[]n=a[1].toCharArray()è più breve e quindi ottieni i parametri dall'esterno (come dovresti comunque)
edc65

Ah, ok, lo cambierò, grazie!
cmxu,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.