private static GridPos jumpLoop(JumpPointParam iParam, int iX, int iY, int iPx, int iPy) { GridPos retVal = null; Stack <JumpSnapshot> stack = new Stack <JumpSnapshot>(); JumpSnapshot currentSnapshot = new JumpSnapshot(); JumpSnapshot newSnapshot = null; currentSnapshot.iX = iX; currentSnapshot.iY = iY; currentSnapshot.iPx = iPx; currentSnapshot.iPy = iPy; currentSnapshot.stage = 0; stack.Push(currentSnapshot); while (stack.Count != 0) { currentSnapshot = stack.Pop(); switch (currentSnapshot.stage) { case 0: if (!iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY)) { retVal = null; continue; } else if (iParam.SearchGrid.GetNodeAt(currentSnapshot.iX, currentSnapshot.iY).Equals(iParam.EndNode)) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } currentSnapshot.tDx = currentSnapshot.iX - currentSnapshot.iPx; currentSnapshot.tDy = currentSnapshot.iY - currentSnapshot.iPy; currentSnapshot.jx = null; currentSnapshot.jy = null; if (iParam.CrossCorner) { // check for forced neighbors // along the diagonal if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY - currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } // horizontally/vertically else { if (currentSnapshot.tDx != 0) { // moving along x if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + 1)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY - 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - 1))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } else { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } } // when moving diagonally, must check for vertical/horizontal jump points if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { currentSnapshot.stage = 1; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) || iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } else if (iParam.CrossAdjacentPoint) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } } else //if (!iParam.CrossCorner) { // check for forced neighbors // along the diagonal if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } // horizontally/vertically else { if (currentSnapshot.tDx != 0) { // moving along x if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY + 1)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY - 1))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } else { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY - currentSnapshot.tDy)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY - currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } } // when moving diagonally, must check for vertical/horizontal jump points if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { currentSnapshot.stage = 3; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } } retVal = null; break; case 1: currentSnapshot.jx = retVal; currentSnapshot.stage = 2; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); break; case 2: currentSnapshot.jy = retVal; if (currentSnapshot.jx != null || currentSnapshot.jy != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) || iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } else if (iParam.CrossAdjacentPoint) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } retVal = null; break; case 3: currentSnapshot.jx = retVal; currentSnapshot.stage = 4; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); break; case 4: currentSnapshot.jy = retVal; if (currentSnapshot.jx != null || currentSnapshot.jy != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } retVal = null; break; } } return(retVal); }
private static GridPos JumpLoop(JumpPointParam jpParam, int x, int y, int px, int py) { var stack = new Stack <JumpSnapshot>(); var currentSnapshot = new JumpSnapshot { X = x, Y = y, Px = px, Py = py, Stage = 0 }; stack.Push(currentSnapshot); GridPos retVal = null; while (stack.Count != 0) { currentSnapshot = stack.Pop(); JumpSnapshot newSnapshot; switch (currentSnapshot.Stage) { case 0: if (!jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y)) { retVal = null; continue; } else if (jpParam.SearchGrid.GetNodeAt(currentSnapshot.X, currentSnapshot.Y).Equals(jpParam.EndNode)) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } currentSnapshot.Dx = currentSnapshot.X - currentSnapshot.Px; currentSnapshot.Dy = currentSnapshot.Y - currentSnapshot.Py; if (jpParam.DiagonalMovement == DiagonalMovement.Always || jpParam.DiagonalMovement == DiagonalMovement.IfAtLeastOneWalkable) { // check for forced neighbors // along the diagonal if (currentSnapshot.Dx != 0 && currentSnapshot.Dy != 0) { if ((jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X - currentSnapshot.Dx, currentSnapshot.Y + currentSnapshot.Dy) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X - currentSnapshot.Dx, currentSnapshot.Y)) || (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y - currentSnapshot.Dy) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y - currentSnapshot.Dy))) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } } // horizontally/vertically else { if (currentSnapshot.Dx != 0) { // moving along x if ((jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y + 1) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y + 1)) || (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y - 1) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y - 1))) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } } else { if ((jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + 1, currentSnapshot.Y + currentSnapshot.Dy) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + 1, currentSnapshot.Y)) || (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X - 1, currentSnapshot.Y + currentSnapshot.Dy) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X - 1, currentSnapshot.Y))) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } } } // when moving diagonally, must check for vertical/horizontal jump points if (currentSnapshot.Dx != 0 && currentSnapshot.Dy != 0) { currentSnapshot.Stage = 1; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { X = currentSnapshot.X + currentSnapshot.Dx, Y = currentSnapshot.Y, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y) || jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y + currentSnapshot.Dy)) { newSnapshot = new JumpSnapshot { X = currentSnapshot.X + currentSnapshot.Dx, Y = currentSnapshot.Y + currentSnapshot.Dy, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } else if (jpParam.DiagonalMovement == DiagonalMovement.Always) { newSnapshot = new JumpSnapshot { X = currentSnapshot.X + currentSnapshot.Dx, Y = currentSnapshot.Y + currentSnapshot.Dy, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } } else if (jpParam.DiagonalMovement == DiagonalMovement.OnlyWhenNoObstacles) { // check for forced neighbors // along the diagonal if (currentSnapshot.Dx != 0 && currentSnapshot.Dy != 0) { if ((jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y + currentSnapshot.Dy) && jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y + currentSnapshot.Dy) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y)) || (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y + currentSnapshot.Dy) && jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y + currentSnapshot.Dy))) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } } // horizontally/vertically else { if (currentSnapshot.Dx != 0) { // moving along x if ((jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y + 1) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X - currentSnapshot.Dx, currentSnapshot.Y + 1)) || (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y - 1) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X - currentSnapshot.Dx, currentSnapshot.Y - 1))) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } } else { if ((jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + 1, currentSnapshot.Y) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + 1, currentSnapshot.Y - currentSnapshot.Dy)) || (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X - 1, currentSnapshot.Y) && !jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X - 1, currentSnapshot.Y - currentSnapshot.Dy))) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } } } // when moving diagonally, must check for vertical/horizontal jump points if (currentSnapshot.Dx != 0 && currentSnapshot.Dy != 0) { currentSnapshot.Stage = 3; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { X = currentSnapshot.X + currentSnapshot.Dx, Y = currentSnapshot.Y, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y) && jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y + currentSnapshot.Dy)) { newSnapshot = new JumpSnapshot { X = currentSnapshot.X + currentSnapshot.Dx, Y = currentSnapshot.Y + currentSnapshot.Dy, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } } else // if(jpParam.DiagonalMovement == DiagonalMovement.Never) { if (currentSnapshot.Dx != 0) { // moving along x if (!jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y)) { retVal = new GridPos(x, y); continue; } } else { if (!jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y + currentSnapshot.Dy)) { retVal = new GridPos(x, y); continue; } } // must check for perpendicular jump points if (currentSnapshot.Dx != 0) { currentSnapshot.Stage = 5; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { X = currentSnapshot.X, Y = currentSnapshot.Y + 1, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } else // tDy != 0 { currentSnapshot.Stage = 6; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { X = currentSnapshot.X + 1, Y = currentSnapshot.Y, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } } retVal = null; break; case 1: if (retVal != null) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } currentSnapshot.Stage = 2; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { X = currentSnapshot.X, Y = currentSnapshot.Y + currentSnapshot.Dy, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); break; case 2: if (retVal != null) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y) || jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y + currentSnapshot.Dy)) { newSnapshot = new JumpSnapshot { X = currentSnapshot.X + currentSnapshot.Dx, Y = currentSnapshot.Y + currentSnapshot.Dy, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } else if (jpParam.DiagonalMovement == DiagonalMovement.Always) { newSnapshot = new JumpSnapshot { X = currentSnapshot.X + currentSnapshot.Dx, Y = currentSnapshot.Y + currentSnapshot.Dy, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } retVal = null; break; case 3: if (retVal != null) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } currentSnapshot.Stage = 4; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { X = currentSnapshot.X, Y = currentSnapshot.Y + currentSnapshot.Dy, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); break; case 4: if (retVal != null) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y) && jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y + currentSnapshot.Dy)) { newSnapshot = new JumpSnapshot { X = currentSnapshot.X + currentSnapshot.Dx, Y = currentSnapshot.Y + currentSnapshot.Dy, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } retVal = null; break; case 5: if (retVal != null) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } currentSnapshot.Stage = 7; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { X = currentSnapshot.X, Y = currentSnapshot.Y - 1, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); break; case 6: if (retVal != null) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } currentSnapshot.Stage = 7; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { X = currentSnapshot.X - 1, Y = currentSnapshot.Y, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); break; case 7: if (retVal != null) { retVal = new GridPos(currentSnapshot.X, currentSnapshot.Y); continue; } // keep going if (jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X + currentSnapshot.Dx, currentSnapshot.Y) && jpParam.SearchGrid.IsWalkableAt(currentSnapshot.X, currentSnapshot.Y + currentSnapshot.Dy)) { newSnapshot = new JumpSnapshot { X = currentSnapshot.X + currentSnapshot.Dx, Y = currentSnapshot.Y + currentSnapshot.Dy, Px = currentSnapshot.X, Py = currentSnapshot.Y, Stage = 0 }; stack.Push(newSnapshot); continue; } retVal = null; break; } } return(retVal); }