Started updating the main form to have control over how the maze's properties. Search algorithm can now be changed on the fly.

This commit is contained in:
2020-05-19 13:28:54 -05:00
parent ff496ff63b
commit 6e8c700b9b
3 changed files with 102 additions and 37 deletions
+44 -8
View File
@@ -22,6 +22,31 @@
clear: both; clear: both;
} }
</style> </style>
<script>
function updateCanvasWidth(){
let w = document.getElementById('canvasWidthTextbox').value;
resizeCanvas(w, height);
}
function updateCanvasHeight(){
let h = document.getElementById('canvasHeightTextbox').value;
}
function toggleForm(enabled){
document.getElementById("canvasProperties").disabled = !enabled;
document.getElementById("algo").disabled = !enabled;
document.getElementById("misc").disabled = !enabled;
document.getElementById("runButton").disabled = !enabled;
}
function rerun(){
algo = {};
maze.resetMazeState();
maze.updateMazeDisplay();
loop();
}
</script>
<script src="maze-solver.js"></script> <script src="maze-solver.js"></script>
<script src="cell.js"></script> <script src="cell.js"></script>
<script src="gen-maze.js"></script> <script src="gen-maze.js"></script>
@@ -33,19 +58,30 @@
<body> <body>
<div id="sketch-holder" class="column"></div> <div id="sketch-holder" class="column"></div>
<div class="column"> <div class="column">
<label id="information"></label>
<form action=""> <form action="">
<label for="canvasWidthTextbox" >Canvas Size Width: </label><input type="number" id="canvasWidthTextbox" value="400"/> <fieldset id="canvasProperties" name="canvasProperties" disabled="disabled">
<label for="canvasHeighTextbox"> Height: </label><input type="number" id="canavasHeightTextbox" value="400"/><br/> <legend>Canvas Properties</legend>
<label for="genFrameRate">Framerate During Maze Generation: </label><input type="number" id="genFrameRate" min="1" max="144" step="1" value="30"/><br /> <label for="canvasWidthTextbox" >Canvas Size Width: </label><input type="number" id="canvasWidthTextbox" value="500" onchange="updateCanvasWidth()"/>
<label for="canvasHeightTextbox"> Height: </label><input type="number" id="canavasHeightTextbox" value="500" onchange="updateCanvasHeight()"/><br/>
<label for="genFrameRate">Framerate During Maze Generation: </label><input type="number" id="genFrameRate" min="1" max="144" step="1" value="30" /><br />
<label for="solvingFrameRate">Framerate During Maze Solving: </label><input type="number" id="solvingFrameRate" min="1" max="144" step="1" value="30" /><br />
<input id="reuseMaze" type="checkbox" checked="true" /><label for="reuseMaze">Reuse current maze on next run (uncheck to generate a new maze)</label>
</fieldset>
<fieldset id="algo" name="algo" disabled="disabled">
<legend>Search Algorithms</legend>
<label for="searchAlgo">Search Algorithm to Find Maze Anwser: </label> <label for="searchAlgo">Search Algorithm to Find Maze Anwser: </label>
<select id="searchAlgo"> <select id="searchAlgo">
<option value="depthFirst">Depth First</option> <option value="depthFirst">Depth First</option>
<option value="breadthFirst">Breadth First</option> <option value="breadthFirst">Breadth First</option>
<option value="a">a*</option> <option value="a*">a*</option>
</select><br /> </select>
<label for="solvingFrameRate">Framerate During Maze Solving: </label><input type="number" id="solvingFrameRate" min="1" max="144" step="1" value="30"/><br /> </fieldset>
<input id="reuseMaze" type="checkbox" checked="true"/><label for="reuseMaze">Reuse current maze on next run</label> <fieldset id="misc" disabled="disabled">
<br /><button type="button" onClick="draw();">Again</button> <legend>Misc.</legend>
<label for="cellWidthInput">Cell Width: </label><input type="number" id="cellWidthInput" value="50" />
</fieldset>
<button id="runButton" type="button" onClick="rerun()" disabled>Re-run</button>
</form> </form>
</div> </div>
+37 -16
View File
@@ -1,33 +1,40 @@
class MazeSolver { class MazeSolver {
constructor(startingCell, targetCell, searchedColor = [210, 180, 140]){ constructor(startingCell, targetCell, searchedColor = [210, 180, 140], finalPathColor = [173, 216, 230]){
this.frontier = []; this.frontier = [];
this.explored = []; this.explored = [];
this.finalPathColor = finalPathColor;
this.targetCell = targetCell; this.targetCell = targetCell;
this.startingCell = startingCell;
this.searchedColor = searchedColor; this.searchedColor = searchedColor;
this.selectedColor = [50, 175, 50];
this.currentCell = startingCell; this.currentCell = startingCell;
this.frontier.push(startingCell); this.frontier.push(startingCell);
this.statesExplored = 0;
} }
clearState(){ clearState(){
this.frontier = []; this.frontier = [];
this.explored = []; this.explored = [];
this.statesExplored = 0;
} }
depthFirstNextCell(maze){ highlightFinalPath(maze){
breadthFirstNextCell(maze, true); let tmp = this.explored.pop();
while(tmp != undefined){
tmp.color = this.finalPathColor;
tmp = tmp.parent;
} }
breadthFirstNextCell(maze, depthFirst = false){ maze.updateMazeDisplay();
}
}
class DepthFirstSolver extends MazeSolver {
solve(maze) {
this.currentCell.color = this.searchedColor; this.currentCell.color = this.searchedColor;
if(!depthFirst)
this.currentCell = this.frontier.shift();
else
this.currentCell = this.frontier.pop(); this.currentCell = this.frontier.pop();
this.currentCell.color = this.selectedColor;
this.currentCell.visited = true; this.currentCell.visited = true;
let moves = maze.getLegalMoves(this.currentCell); let moves = maze.getLegalMoves(this.currentCell);
@@ -38,20 +45,34 @@ class MazeSolver {
} }
this.explored.push(this.currentCell); this.explored.push(this.currentCell);
this.statesExplored++;
if(this.currentCell.x == this.targetCell.x && this.currentCell.y == this.targetCell.y) if(this.currentCell.x == this.targetCell.x && this.currentCell.y == this.targetCell.y)
this.frontier = []; this.frontier = [];
this.currentCell.color = this.searchedColor; this.currentCell.color = this.searchedColor;
} }
}
highlightFinalPath(maze, finalPathColor = [173, 216, 230]){ class BreadthFirstSolver extends MazeSolver {
let tmp = this.explored.pop(); solve(maze) {
this.currentCell.color = this.searchedColor;
while(tmp != undefined){ this.currentCell = this.frontier.shift();
tmp.color = finalPathColor;
tmp = tmp.parent; this.currentCell.visited = true;
let moves = maze.getLegalMoves(this.currentCell);
for (let i = 0; i < moves.length; i++){
this.frontier.push(moves[i]);
moves[i].parent = this.currentCell;
} }
maze.updateMazeDisplay(); this.explored.push(this.currentCell);
this.statesExplored++;
if(this.currentCell.x == this.targetCell.x && this.currentCell.y == this.targetCell.y)
this.frontier = [];
this.currentCell.color = this.searchedColor;
} }
} }
+13 -5
View File
@@ -6,8 +6,7 @@ var maze = {};
var algo = {}; var algo = {};
function setup() { function setup() {
print("hell"); var canvas = createCanvas(500, 500);
var canvas = createCanvas(400, 400);
canvas.parent('sketch-holder'); canvas.parent('sketch-holder');
maze = new Maze(width, height, cellWidth, "Depth"); maze = new Maze(width, height, cellWidth, "Depth");
frameRate(30); frameRate(30);
@@ -23,18 +22,27 @@ function draw() {
} }
else if (maze.mazeGenDone && algo.frontier == undefined){ else if (maze.mazeGenDone && algo.frontier == undefined){
maze.resetMazeState(); maze.resetMazeState();
algo = new MazeSolver(maze.grid[0], maze.grid[maze.index(7,7)]); //maze.updateMazeDisplay();
let selectedAlgo = document.getElementById("searchAlgo").value;
if(selectedAlgo == "depthFirst")
algo = new DepthFirstSolver(maze.grid[0], maze.grid[maze.index(7, 7)]);
else if(selectedAlgo == "breadthFirst")
algo = new BreadthFirstSolver(maze.grid[0], maze.grid[maze.index(7,7)]);
//else if(selectedAlgo == "a*")
print("Maze generation done"); print("Maze generation done");
frameRate(10); frameRate(10);
} }
else if (maze.mazeGenDone && algo.frontier.length > 0){ else if (maze.mazeGenDone && algo.frontier.length > 0){
algo.breadthFirstNextCell(maze); //algo.breadthFirstNextCell(maze);
algo.solve(maze);
} }
else{ else{
algo.highlightFinalPath(maze); algo.highlightFinalPath(maze);
let label = document.getElementById('information').innerHTML = `Maze Finished. Explored ${algo.statesExplored} states to find the answer.`;
print("Maze search done"); print("Maze search done");
noLoop(); noLoop();
toggleForm(true);
} }
} }