Let's play Peg Solitaire Peg solitaire is a popular game usually played alone. The game consists of some number of pegs and a board which is divided into a grid - usually the board is not rectangular but for this challenge we will assume so.

Each valid move allows one to remove a single peg and the goal is to play in a way, such that there is a single peg left. Now, a valid move has to be in a single direction (north, east, south or east) and jump over one peg which can be removed.

Examples

Let . be empty spaces on the board and numbers are pegs, the following move will move 1 one to the right and remove 2 from the board:

.....     .....
.12..  -&gt; ...1.
.....     .....


A move will always have to jump over a single peg, so the following is not valid:

......    ......
.123.. -&gt; ....1.
......    ......


Here are some valid configurations after one move each:

...1...        ...1...        ..71...        ..71...
.2.34.5  ---&gt;  .24...5  ---&gt;  .2....5  ---&gt;  ......5
.678...  (4W)  .678...  (7N)  .6.8...  (2S)  ...8...
.......        .......        .......        .2.....


Challenge

Given an initial board configuration and some other configuration, output whether the other configuration can be reached by successively moving pegs around as described above.

Rules


Input will be a \$n \times m\$ matrix/list of lists/... of values indicating an empty space (eg. zero or false) or pegs (eg. non-zero or true)


you may assume \$n \geq 3\$ and \$m \geq 3\$
you may use true/non-zero to indicate empty spaces and vice-versa if it helps

Output will be two distinct (one of the values might differ) values indicating whether the end-configuration can be reached (eg. falsy/truthy, []/[list of moves] ..)


Test cases

initial  goal -&gt; output
[[1,0,0],[1,1,0],[0,1,0]]  [[0,0,0],[0,1,0],[1,1,0]] -&gt; True
[[1,0,0],[1,1,0],[0,1,0]]  [[0,0,1],[0,1,1],[0,0,0]] -&gt; False
[[0,0,0],[1,0,0],[0,0,0]]  [[0,0,0],[0,0,1],[0,0,0]] -&gt; False
[[0,0,0],[1,1,0],[0,0,0]]  [[0,0,0],[0,1,1],[0,0,0]] -&gt; False
[[0,0,0,0],[1,1,1,0],[0,0,0,0]]  [[0,0,0,0],[0,0,0,1],[0,0,0,0]] -&gt; False
[[1,0,0],[1,1,0],[1,1,1],[1,1,1]]  [[0,0,1],[0,1,0],[1,0,0],[0,0,1]] -&gt; True
[[1,0,0],[1,1,0],[1,1,1],[1,1,1]]  [[1,0,0],[0,0,0],[0,0,0],[0,0,0]] -&gt; False
[[1,0,1,1],[1,1,0,0],[1,1,1,0],[1,0,1,0]]  [[0,0,1,0],[1,0,0,0],[1,0,1,0],[1,0,0,1]] -&gt; True
[[1,0,1,1],[1,1,0,0],[1,1,1,0],[1,0,1,0]]  [[0,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,0]] -&gt; False
[[1,0,0,0],[1,1,0,0],[1,1,1,0],[1,0,1,0]]  [[0,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,0]] -&gt; True
[[0,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,0]]  [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]] -&gt; False
[[0,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,0]]  [[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] -&gt; False
[[0,0,0,1,0,0,0],[0,1,0,1,1,0,1],[0,1,1,1,0,0,0],[0,0,0,0,0,0,0]]  [[0,0,0,1,0,0,0],[0,1,0,1,1,0,1],[0,1,1,1,0,0,0],[0,0,0,0,0,0,0]] -&gt; True
[[0,0,0,1,0,0,0],[0,1,0,1,1,0,1],[0,1,1,1,0,0,0],[0,0,0,0,0,0,0]]  [[0,0,0,1,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]] -&gt; True
[[0,0,1,1,1,0,0],[0,0,1,1,1,0,0],[1,1,1,1,1,1,1],[1,1,1,0,1,1,1],[1,1,1,1,1,1,1],[0,0,1,1,1,0,0],[0,0,1,1,1,0,0]]  [[0,0,1,1,1,0,0],[0,0,1,1,1,0,0],[1,1,1,1,1,1,1],[1,1,1,1,0,0,1],[1,1,1,1,1,1,1],[0,0,1,1,1,0,0],[0,0,1,1,1,0,0]] -&gt; True
[[0,0,1,1,1,0,0],[0,0,1,1,1,0,0],[1,1,1,1,1,1,1],[1,1,1,0,1,1,1],[1,1,1,1,1,1,1],[0,0,1,1,1,0,0],[0,0,1,1,1,0,0]]  [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,1,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]] -&gt; True
JavaScript (ES6),  184 178  173 bytes
Takes input as (initial_board)(target_board). Returns \$0\$ or \$1\$.

a=&gt;g=b=&gt;a+''==b|a.some((r,y)=&gt;r.some((v,x,A,X,R)=&gt;[-1,0,1,2].some(h=&gt;(A=a[y+(R=~-h%2)]||0)[X=x+(h%=2)]&amp;v&gt;(R=a[y+R*2]||0)[h+=x+h]&amp;&amp;g(b,A[X]=r[x]=R[h]++)&amp;(A[X]=r[x]=R[h]--))))

Try it online!
(removed the last two test cases that take too much time for TIO)
Commented
a =&gt;                             // main function taking the initial board a[]
  g = b =&gt;                       // g = recursive function taking the target board b[]
    a + '' == b |                // yield a truthy result if a[] is matching b[]
    a.some((r, y) =&gt;             // for each row r[] at position y in a[]:
      r.some((v, x, A, X, R) =&gt;  //   for each value v at position x in r[]:
        [-1, 0, 1, 2]            //     list of directions (West, North, East, South)
        .some(h =&gt;               //     for each direction h:
          ( A =                  //       A = a[y + dy]
            a[y + (R = ~-h % 2)] //       R = dy
            || 0                 //       use a dummy row if we're out of the board
          )[X = x + (h %= 2)]    //       h = dx, X = x + dx
          &amp;                      //       yield 1 if there's a peg on the skipped cell
          ( R =                  //       R = target row
            a[y + R * 2]         //         = a[y + 2 * dy]
            || 0                 //       use a dummy row if we're out of the board
          )[h += x + h]          //       h = x + 2 * dx = target column
          &lt; v                    //       yield 1 if there's no peg on the target cell
          &amp;&amp;                     //       and there's a peg on the source cell (0 &lt; 1)
          g(                     //       if the above result is true, do a recursive call:
            b,                   //         pass b[] unchanged
            A[X] = r[x] =        //         clear the source and skipped cells
            R[h]++               //         set the target cell
          ) &amp; (                  //       and then restore the board to its initial state:
            A[X] = r[x] =        //         set the source and skipped cells
            R[h]--               //         clear the target cell
          )                      //
        )                        //     end of some() over directions
      )                          //   end of some() over columns
    )                            // end of some() over rows