@@ -235,12 +235,14 @@ export class CubeoBoard {
235235 // don't do die checking; sometimes you need it for an empty space
236236 public moveGraphFor ( x : number , y : number ) : SquareGraph {
237237 const die = this . getDieAt ( x , y ) ;
238+ let startCell : string | undefined ;
238239 // start with the basic graph
239240 const g = this . graph ;
240241 const gOrth = this . graphOrth ;
241242 // If we started from a die, remove any spaces that are orthogonally adjacent *only*
242243 // to the moving die
243244 if ( die !== undefined ) {
245+ startCell = g . coords2algebraic ( ...this . abs2rel ( x , y ) ! ) ;
244246 const empties = g . graph . nodes ( ) . filter ( node => ! g . graph . hasNodeAttribute ( node , "contents" ) )
245247 for ( const node of empties ) {
246248 const ndice : CubeoDie [ ] = [ ] ;
@@ -254,6 +256,41 @@ export class CubeoBoard {
254256 }
255257 }
256258 }
259+ // To deal with "jumping the gap" scenarios, we have to delete edges where the destination
260+ // node is neither adjacent to one of the same dice it was before nor adjacent to one of
261+ // the source node's orthogonal neighbours.
262+ for ( const edge of g . graph . edges ( ) ) {
263+ const [ left , right ] = g . graph . extremities ( edge ) ;
264+ // ignore edges that include dice that are not the moving die
265+ if ( ( g . graph . hasNodeAttribute ( left , "contents" ) && left !== startCell ) || ( g . graph . hasNodeAttribute ( right , "contents" ) && right !== startCell ) ) {
266+ continue ;
267+ }
268+ const nLeft = new Set < string > ( gOrth . graph . neighbors ( left ) . filter ( node => node !== startCell && g . graph . hasNode ( node ) && g . graph . hasNodeAttribute ( node , "contents" ) ) ) ;
269+ const nRight = new Set < string > ( gOrth . graph . neighbors ( right ) . filter ( node => node !== startCell && g . graph . hasNode ( node ) && g . graph . hasNodeAttribute ( node , "contents" ) ) ) ;
270+ let shared = new Set < string > ( [ ...nLeft ] . filter ( n => nRight . has ( n ) ) ) ;
271+ // if both nodes are adjacent to a shared die, then this is a valid edge
272+ if ( shared . size > 0 ) {
273+ continue ;
274+ }
275+ // generate a list of dice orthogonally adjacent to each of the original neighbours
276+ const nnLeft = new Set < string > ( ) ;
277+ nLeft . forEach ( n => gOrth . graph . neighbors ( n ) . filter ( node => node !== startCell && g . graph . hasNode ( node ) && g . graph . hasNodeAttribute ( node , "contents" ) ) . forEach ( nn => nnLeft . add ( nn ) ) ) ;
278+ const nnRight = new Set < string > ( ) ;
279+ nRight . forEach ( n => gOrth . graph . neighbors ( n ) . filter ( node => node !== startCell && g . graph . hasNode ( node ) && g . graph . hasNodeAttribute ( node , "contents" ) ) . forEach ( nn => nnRight . add ( nn ) ) ) ;
280+ shared = new Set < string > ( [ ...nnLeft , ...nLeft ] . filter ( n => nnRight . has ( n ) || nRight . has ( n ) ) ) ;
281+ // if the two nodes share a neighbour, it's a valid edge
282+ if ( shared . size > 0 ) {
283+ continue ;
284+ }
285+ // otherwise, drop this edge
286+ // console.log(`Dropping the edge between ${left} and ${right} when developing the move graph for ${x},${y}`);
287+ // console.log(`nLeft: ${JSON.stringify([...nLeft])}`);
288+ // console.log(`nnLeft: ${JSON.stringify([...nnLeft])}`);
289+ // console.log(`nRight: ${JSON.stringify([...nRight])}`);
290+ // console.log(`nnRight: ${JSON.stringify([...nnRight])}`);
291+ g . graph . dropEdge ( edge ) ;
292+ }
293+
257294 // now drop all nodes occupied by dice except the moving die (if we started with a die)
258295 for ( const node of g . graph . nodes ( ) ) {
259296 if ( g . graph . hasNodeAttribute ( node , "contents" ) ) {
0 commit comments