I forked the PathFinding.js project and implemented a custom IDDFS (Iterative Deepening Depth-First Search) algorithm. I want to make it work with the visual demo but I keep getting an error.
When I click the Start Search button, I get this error:
Uncaught TypeError: PF.CustomIDDFSFinder is not a constructor
I already made these changes:
Step 1 - Updated the main module exports in src/PathFinding.js:
module.exports = {
'Heap': require('heap'),
'Node': require('./core/Node'),
'Grid': require('./core/Grid'),
'Util': require('./core/Util'),
'DiagonalMovement': require('./core/DiagonalMovement'),
'Heuristic': require('./core/Heuristic'),
'AStarFinder': require('./finders/AStarFinder'),
'BestFirstFinder': require('./finders/BestFirstFinder'),
'BreadthFirstFinder': require('./finders/BreadthFirstFinder'),
'DijkstraFinder': require('./finders/DijkstraFinder'),
'BiAStarFinder': require('./finders/BiAStarFinder'),
'BiBestFirstFinder': require('./finders/BiBestFirstFinder'),
'BiBreadthFirstFinder': require('./finders/BiBreadthFirstFinder'),
'BiDijkstraFinder': require('./finders/BiDijkstraFinder'),
'IDAStarFinder': require('./finders/IDAStarFinder'),
'JumpPointFinder': require('./finders/JumpPointFinder'),
'CustomIDDFSFinder': require('./finders/CustomIDDFSFinder')
};
Step 2 - Added switch case in visual/js/panel.js:
case 'custom_iddfs_header':
allowDiagonal = typeof $('#custom_iddfs_section .allow_diagonal:checked').val() !== 'undefined';
biDirectional = typeof $('#custom_iddfs_section .bi-directional:checked').val() !== 'undefined';
dontCrossCorners = typeof $('#custom_iddfs_section .dont_cross_corners:checked').val() !== 'undefined';
finder = new PF.CustomIDDFSFinder({
allowDiagonal: allowDiagonal,
dontCrossCorners: dontCrossCorners
});
break;
Step 3 - Added HTML section in visual/index.html:
<h3 id="custom_iddfs_header"><a href="#">Custom IDDFS Algorithm</a></h3>
<div id="custom_iddfs_section" class="finder_section">
<header class="option_header">
<h3>Settings</h3>
</header>
<div class="optional sub_options">
<input type="checkbox" class="allow_diagonal" checked>
<label class="option_label">Allow Diagonal</label><br>
<input type="checkbox" class="bi-directional">
<label class="option_label">Bi-directional</label><br>
<input type="checkbox" class="dont_cross_corners">
<label class="option_label">Don't Cross Corners</label><br>
</div>
</div>
My custom finder implementation:
var Util = require('../core/Util');
var DiagonalMovement = require('../core/DiagonalMovement');
function CustomIDDFSFinder(options) {
options = options || {};
this.allowDiagonal = options.allowDiagonal;
this.dontCrossCorners = options.dontCrossCorners;
this.diagonalMovement = options.diagonalMovement;
if (!this.diagonalMovement) {
if (!this.allowDiagonal) {
this.diagonalMovement = DiagonalMovement.Never;
} else {
if (this.dontCrossCorners) {
this.diagonalMovement = DiagonalMovement.OnlyWhenNoObstacles;
} else {
this.diagonalMovement = DiagonalMovement.IfAtMostOneObstacle;
}
}
}
}
function limitedDepthSearch(searchState, currentNode, goalNode, visitedNodes, gridMap, maxDepth, movementType) {
if (maxDepth === 0) {
currentNode.opened = true;
if (currentNode === goalNode) {
searchState[0] = true;
searchState[1].push(goalNode);
return;
}
}
var nodeId = "[x=" + currentNode.x + ", y=" + currentNode.y + "]";
if (visitedNodes[nodeId]) {
return;
}
visitedNodes[nodeId] = true;
currentNode.closed = true;
if (maxDepth > 0) {
var adjacentNodes = gridMap.getNeighbors(currentNode, movementType);
var nodeCount = adjacentNodes.length;
var index;
for (index = 0; index < nodeCount; ++index) {
var adjacentNode = adjacentNodes[index];
if (searchState[0]) {
return;
}
var adjacentNodeId = "[x=" + adjacentNode.x + ", y=" + adjacentNode.y + "]";
if (visitedNodes[adjacentNodeId]) {
continue;
}
limitedDepthSearch(searchState, adjacentNode, goalNode, visitedNodes, gridMap, maxDepth - 1, movementType);
}
}
}
CustomIDDFSFinder.prototype.findPath = function(startX, startY, endX, endY, grid) {
var startingNode = grid.getNodeAt(startX, startY);
var targetNode = grid.getNodeAt(endX, endY);
var movementType = this.diagonalMovement;
startingNode.opened = true;
var resultPath = [];
var exploredNodes = {};
var previousExploredCount = 0;
var searchState = [false, []];
for (var currentDepth = 0;; ++currentDepth) {
limitedDepthSearch(searchState, startingNode, targetNode, exploredNodes, grid, currentDepth, movementType);
if (searchState[0]) {
return searchState[1].reverse();
}
var exploredCount = Object.keys(exploredNodes).length;
if (previousExploredCount === exploredCount) {
return [];
}
previousExploredCount = exploredCount;
exploredNodes = {};
searchState[1] = [];
}
};
module.exports = CustomIDDFSFinder;
What am I missing to make this work properly?