I am trying to solve a shortest path algorithm problem using a knight on a chess board. I understand that BFS (breadth first search) is the most efficient approach but I want to try and solve it using DFS (Depth first search) first. Understanding both algorithms will greatly help my knowledge.
Issue/Problem: My nextMove(curRow, curCol, moves) function eventually stack overflows. The base case of my function works because I can see the first stacks return successfully. But as it gets towards the end of possible scenarios it runs infinitely with the same array values.
What I expected: I expect the recursive function to exit when there are no more scenarios left
What I've tried: I tried to pop the array when the recursive function returns so it does not keep trying with the same array values.
Code: https://jsfiddle.net/mschreider/jaqL1c5d/ uncomment line 115 to run
I commented out the console.log() function call because of the stack overflow problem.
function knightMoves(start, finish) {
let shortestPath = []
function nextMove(curRow, curCol, moves) {
//console.log(moves)
if (curRow === finish[0] && curCol === finish[1]) {
if (shortestPath.length === 0) {
shortestPath = moves
}
else {
shortestPath = moves.length < shortestPath.length ? moves : shortestPath
}
console.log(shortestPath)
return
}
// coordinates the knight can move [row, col]
let options = [[1,2], [1,-2], [-1,2], [-1,-2], [2,1], [2,-1], [-2,1], [-2,-1]]
for (let i=0; i<options.length; i++) {
let moveRow = options[i][0]
let moveCol = options[i][1]
let newRow = curRow + moveRow
let newCol = curCol + moveCol
let proceed = validMove(newRow, newCol, moves)
// if there is space to move, move knight
if (proceed) {
let arr = [...moves]
arr.push([newRow, newCol])
nextMove(newRow, newCol, arr)
arr.pop()
}
}
return
}
nextMove(start[0], start[1], [start])
return shortestPath
}
function validMove(row, col, moves) {
// Check if the location has already been seen
let coordinate = [row, col]
let newSpot = true
if (moves.length > 0) {
for (let i = 0; i <moves.length; i++) {
let seen = moves[i].length === coordinate.length && moves[i].every((value, index) => value === coordinate[index])
if (seen) {
return false
}
}
}
else {
newSpot = true
}
// Check if the knight has space to move
if (newSpot) {
if ((row >= 0 && row < 8) && (col >= 0 && col < 8)) {
return true
}
else {
//debugger;
return false
}
}
}
// console.log(knightMoves([0,0],[3,3]))