Explosions on a chessboard Atomic chess is a (very fun)
variant of chess in which every capture causes an "explosion," destroying the
captured piece, the piece doing the capturing, and all non-pawns in a 1-square
radius. The goal of this challenge is not to play an entire game of atomic
chess, but simply to simulate what happens when a certain move is made.

Disclaimer: Explosion sound effects not included.

Input

Board position will be given in Forsyth-Edwards
Notation
(commonly known as FEN), but with only the first field. For example, an input
of:

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


represents the starting position:



This must be taken as a string or your language's equivalent. It is guaranteed
to be valid; for example, you don't have to care if there are ten kings, or if
there is no king at all.

You will also be given the move that you are to simulate, which is represented
as two square names: the square on which the piece to be moved is, and the
square it is moving to. For example, moving the king's pawn two spaces forwards
on the above picture would be represented as:

e2e4


This must also be taken as a string. The move will always be valid, and you do
not need to support castling. You do
need to support en passant, which
will be explained in further detail in the next section.

Output

The output of your program should be in the same partial-FEN notation as the
input, with the specified move made (and any pieces exploded if necessary).

The exact rules for explosions are—when a piece is captured:


Remove the piece being captured (this will always be the piece on the second
square named in the input, except for when the capture is an en passant).
Remove the piece that is doing the capturing (this will always be the piece
on the first square named in the input).
Remove every piece that is:


located on one of the 8 squares surrounding the one where the capture took
place (for en passant, this is the square that the capturing pawn would
be on, if it didn't explode).
not a pawn.



Quick overview of en passant rules, for those who are unfamiliar: if a pawn
moves two spaces forwards from its starting rank, and there is a pawn that
could have captured it if it only moved one square forward, it may capture it
anyway, but only on the subsequent move. This capture is said to be done "in
passing" (or in French: "en passant").

Test cases

In the pictures, the green arrows represet the move about to be made, and the
green circles represents pieces that are exploded.

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




Input: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P1pP/2rP1P2/R1B3RK, f2g3
Output: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P2P/2rP4/R1B3RK

(stolen from 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

(stolen from 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

(stolen from http://en.lichess.org/AvgU4Skq/white#16; this wasn't the actual
move, but I couldn't be bothered to find an atomic game that actually had en
passant :P)



Input: 5r2/2k5/p1B5/1pP1p3/1P4P1/3P4/P7/1K3R1q, c6h1
Output: 5r2/2k5/p7/1pP1p3/1P4P1/3P4/P7/1K3R2

(stolen from http://en.lichess.org/l77efXEb/white#58)

Scoring

This is code-golf, so the shortest code in bytes wins.
JavaScript (ES6) 305 310 321

As a function with 2 real parameters (and a lot more with default values, used as a quick and dirty way to define locals)

Test running the snippet below (being EcmaScript 6, Firefox only)



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

//TEST
out=x=&gt;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=&gt;( 
  r=F(t[0],t[1]), 
  out('Test '+(r==t[2]?'Ok':'Fail!')+'  '+t[0]+' move '+t[1]
     +'\nResult   '+r+'\nExpected '+t[2]+'\n')))
&lt;pre id=O&gt;&lt;/pre&gt;




Ungolfed

B=(b,m)=&gt;{
  P=p=&gt;p=='p'|p=='P'
  m=parseInt(m,32) 
  r=m&amp;31 // arrival row
  s=(m/32&amp;31)-10 // arrival column
  z=s+(8-r)*9 // arrival position
  t=m/32/32&amp;31 // start row
  u=(m/32/32/32&amp;31)-10 // start column
  y=u+(8-t)*9 // start position
  b=[...b.replace(/\d/g,c=&gt;'0'.repeat(c))] // board to array, empty squares as 0
  x=b[y] // moving piece
  b[y]=0 
  C=s!=u&amp;P(x) // pawn capture
  if (b[z]&lt;1 &amp;&amp; !C)
  {  // no capture
    b[z]=x
  }
  else
  {
    // capture and boom!
    if (b[z]&lt;1) // arrival empty: en passant
      b[z&gt;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=&gt;b[i+=z]&gt;'/'&amp;&amp;!P(b[i])?b[i]=0:0)
  }
  return b.join('').replace(/0+/g,x=&gt;x.length)
}