I'm having an architectural dilemma. I am making a website to display pathfinding algorithms. I am using Redux to store a 2D array which represents the state of each cell in the grid.
The way my application works is that I have a classes that inherit from a base class called PathfindingAlgorithm which has a function called pass() that does one pass of the algorithm and updates the grid in the store.
Below is an example of Depth First Search being implemented. My 'SET_CELL_STATE' redux action updates the 2D grid in my redux store with the newState. Coordinate just holds {x, y} values, and coordinateMap is there for backtracking on the path.
export class DepthFirstSearch extends PathfindingAlgorithm {
private stack: coordinate[] = [this.startIndex];
private coordinateMap: Map<coordinate, coordinate> = new Map();
private current: any;
public pass(): boolean {
const {grid} = store.getState();
if (this.stack.length !== 0) {
this.currentIndex = this.stack[this.stack.length - 1];
this.stack.pop();
if (grid[this.currentIndex.y][this.currentIndex.x] === CellState.Exit) {
return true;
} else if (grid[this.currentIndex.y][this.currentIndex.x] === CellState.Empty) {
store.dispatch({
type: 'SET_CELL_STATE',
x: this.currentIndex.x,
y: this.currentIndex.y,
newState: CellState.Visited});
}
const neighbors = super.getUnvisitedNeighbors(this.currentIndex.x, this.currentIndex.y);
neighbors.forEach(val => {
this.coordinateMap.set(val, this.currentIndex);
this.stack.push(val);
});
}
return false;
}
}
I want to call pass until I find an exit and have my view components update in response to the 2D grid. For the view, I dynamically generate cells based on the 2D grid.
function Board(props: any) {
const grid = props.grid;
const renderBoard = () => {
return grid.map((gridRow: Array<CellState>, i: number) => {
return gridRow.map((gridItem: CellState, j: number) => {
return (
<div key={uuidv4()}>
<Cell x={j} y={i}/>
</div>);
})
});
}
return(
<BoardView
renderBoard = { renderBoard }
/>
);
}
function BoardView(props: any) {
const { renderBoard } = props;
return(
<div className="board">
{ renderBoard() }
</div>
);
}
How can I efficiently achieve this looping effect? Making a while loop inside the button that starts it does not update the components until the loop is finished which is bad since I want to animate this in the future. Should I just directly change the Cells straight from the DOM?