Explosionen auf einem Schachbrett

14

Atomschach ist eine (sehr unterhaltsame) Variante des Schachs, bei der jede Erfassung eine "Explosion" verursacht und die erfasste Figur, die erfassende Figur und alle Nicht-Bauern in einem Radius von 1 Quadratmeter zerstört. Ziel dieser Herausforderung ist es nicht, eine ganze Partie Atomschach zu spielen, sondern lediglich zu simulieren, was passiert, wenn ein bestimmter Zug ausgeführt wird.

Haftungsausschluss: Explosionseffekte nicht enthalten.

Eingang

Die Brettposition wird in der Forsyth-Edwards-Notation (allgemein als FEN bekannt) angegeben, jedoch nur mit dem ersten Feld. Zum Beispiel eine Eingabe von:

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

repräsentiert die Startposition:

Schach-Startposition.

Dies muss als Zeichenfolge oder als Entsprechung Ihrer Sprache verstanden werden. Es ist garantiert gültig; Zum Beispiel müssen Sie sich nicht darum kümmern, ob es zehn Könige gibt oder ob es überhaupt keinen König gibt.

Sie erhalten auch den Zug, den Sie simulieren möchten, der als zwei quadratische Namen dargestellt wird: das Quadrat, auf dem sich das zu bewegende Teil befindet, und das Quadrat, auf das es sich bewegt. Wenn Sie beispielsweise den Bauern des Königs auf dem obigen Bild um zwei Felder nach vorne bewegen, wird dies folgendermaßen dargestellt:

e2e4

Dies muss auch als String verstanden werden. Der Zug ist immer gültig und Sie müssen die Rochade nicht unterstützen . Sie müssen en passant unterstützen , was im nächsten Abschnitt näher erläutert wird.

Ausgabe

Die Ausgabe Ihres Programms sollte in derselben Partial-FEN-Notation wie die Eingabe erfolgen, wobei der angegebene Zug ausgeführt wird (und ggf. explodierte Teile).

Die genauen Regeln für Explosionen lauten:

  • Entfernen Sie das zu erfassende Stück (dies ist immer das Stück auf dem zweiten Feld, das in der Eingabe angegeben ist, außer wenn die Erfassung ein en passant ist ).

  • Entfernen Sie das Teil, das die Erfassung vornimmt (dies ist immer das Teil auf dem ersten Feld, das in der Eingabe angegeben ist).

  • Entfernen Sie jedes Stück, das ist:

    • Befindet sich auf einem der 8 Felder, die das Feld umgeben, auf dem die Eroberung stattgefunden hat (für en passant ist dies das Feld, auf dem sich die Eroberungsfigur befinden würde, wenn sie nicht explodieren würde).

    • kein Bauer.

Schneller Überblick über die en passant- Regeln für diejenigen, die nicht vertraut sind: Wenn ein Bauer zwei Felder vor seinem Startrang steht und es einen Bauern gibt, der ihn hätte erobern können, wenn er sich nur um ein Feld vorwärts bewegt hätte, kann er ihn trotzdem erobern, aber erst im nachhinein. Diese Erfassung soll " im Vorbeigehen " erfolgen (oder auf Französisch: " en passant ").

Testfälle

In den Bildern stellen die grünen Pfeile die bevorstehende Bewegung dar, und die grünen Kreise stellen explodierte Teile dar.

Input: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR, g1f3
Output:rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R
Testfall 1.


Input: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P1pP/2rP1P2/R1B3RK, f2g3
Output: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P2P/2rP4/R1B3RK
Testfall 2.
(gestohlene aus http://en.lichess.org/ocoSfS5I/white#36 )


Input: rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R, f3b7
Output: 3qk1nr/2p5/p2pp1pp/5p2/1bN5/2P1P2N/PP1P1PPP/R1B1KB1R
Testfall 3.
(gestohlene aus http://en.lichess.org/NCUnA6LV/white#14 )


Input: rnbqk2r/pp2p2p/2p3pb/3pP3/5P2/2N5/PPPP2P1/R1BQKB1R, e5d6
Output: rnbqk2r/pp2p2p/2p3pb/8/5P2/2N5/PPPP2P1/R1BQKB1R
Testfall 4.
(bestohlen http://en.lichess.org/AvgU4Skq/white#16 , das war nicht die eigentliche Bewegung, aber ich kann nicht gestört werden , um ein Atom Spiel zu finden , die tatsächlich hatte en passant: P)


Input: 5r2/2k5/p1B5/1pP1p3/1P4P1/3P4/P7/1K3R1q, c6h1
Output: 5r2/2k5/p7/1pP1p3/1P4P1/3P4/P7/1K3R2
Testfall 5.
(gestohlene aus http://en.lichess.org/l77efXEb/white#58 )

Wertung

Das ist , also gewinnt der kürzeste Code in Bytes.

Türknauf
quelle
Also ... ein Stück mit deinem König zu machen ist eine schlechte Idee?
mbomb007
@ mbomb007 Du darfst keine Teile mit deinem König nehmen. : P
Türklinke
Ich mag mich irren, aber wie sollen wir wissen, ob die en passant Erfassung möglich ist? In Ihrem Beispiel wird der letzte Zug durch das leere grüne Quadrat gekennzeichnet, sodass der schwarze Bauer en passant gefangen werden kann. Diese Informationen sind jedoch nicht in den Eingaben enthalten, die wir erhalten, sodass es möglich ist, dasselbe Board zu haben, bei dem jedoch die unbefristete Erfassung nicht möglich ist, da der letzte Zug kein Vorwärtszug um zwei Felder war.
Fatalize
1
@Fatalize " Die Verschiebung ist immer gültig " - aus dem Bereich "Eingabe".
Türklinke
Vollständiges Programm oder Funktion?
EDC65

Antworten:

5

JavaScript ( ES6 ) 305 310 321

Als eine Funktion mit 2 realen Parametern (und viel mehr mit Standardwerten, die als schnelle und schmutzige Methode zum Definieren von Einheimischen verwendet werden)

Teste das folgende Snippet (nur in EcmaScript 6, 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)
}
edc65
quelle
1
Wow, das sieht viel einfacher aus als meine Lösung ... Gute Arbeit!
cmxu
2

Java, ( 946 777 776 Zeichen)

1 Zeichen dank @ edc65

Hinweis: Zeichen werden ohne Testfälle gezählt.

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

Ich bin mir nicht sicher, ob diese Lösung optimal ist, aber ich arbeite daran, mehr Golf zu spielen. Vorschläge sind willkommen. Ich kann den gesamten Code auch kommentieren, wenn jemand möchte, aber ich denke, es ist größtenteils selbsterklärend, abgesehen von der verwirrenden Aufzählung der Variablen.

Erläuterung

  • Packen Sie den Board-String in eine Char-Matrix aus
  • Berechnen Sie den Effekt der Bewegung
  • Packe das Board wieder in eine Schnur

Erweitert

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

Alt

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
quelle
String m,i="";m="";char[]n=m.toCharArray()-> String i=a[0];char[]n=a[1].toCharArray()ist kürzer und so bekommt man die parameter von außen (wie man sowieso sollte )
edc65
Ahh, okay, das werde ich ändern, danke!
cmxu