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:
+48
-12
@@ -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="searchAlgo">Search Algorithm to Find Maze Anwser: </label>
|
<label for="canvasHeightTextbox"> Height: </label><input type="number" id="canavasHeightTextbox" value="500" onchange="updateCanvasHeight()"/><br/>
|
||||||
<select id="searchAlgo">
|
<label for="genFrameRate">Framerate During Maze Generation: </label><input type="number" id="genFrameRate" min="1" max="144" step="1" value="30" /><br />
|
||||||
<option value="depthFirst">Depth First</option>
|
<label for="solvingFrameRate">Framerate During Maze Solving: </label><input type="number" id="solvingFrameRate" min="1" max="144" step="1" value="30" /><br />
|
||||||
<option value="breadthFirst">Breadth First</option>
|
<input id="reuseMaze" type="checkbox" checked="true" /><label for="reuseMaze">Reuse current maze on next run (uncheck to generate a new maze)</label>
|
||||||
<option value="a">a*</option>
|
</fieldset>
|
||||||
</select><br />
|
<fieldset id="algo" name="algo" disabled="disabled">
|
||||||
<label for="solvingFrameRate">Framerate During Maze Solving: </label><input type="number" id="solvingFrameRate" min="1" max="144" step="1" value="30"/><br />
|
<legend>Search Algorithms</legend>
|
||||||
<input id="reuseMaze" type="checkbox" checked="true"/><label for="reuseMaze">Reuse current maze on next run</label>
|
<label for="searchAlgo">Search Algorithm to Find Maze Anwser: </label>
|
||||||
<br /><button type="button" onClick="draw();">Again</button>
|
<select id="searchAlgo">
|
||||||
|
<option value="depthFirst">Depth First</option>
|
||||||
|
<option value="breadthFirst">Breadth First</option>
|
||||||
|
<option value="a*">a*</option>
|
||||||
|
</select>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset id="misc" disabled="disabled">
|
||||||
|
<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>
|
||||||
|
|||||||
+39
-18
@@ -1,32 +1,39 @@
|
|||||||
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();
|
||||||
}
|
|
||||||
|
|
||||||
breadthFirstNextCell(maze, depthFirst = false){
|
while(tmp != undefined){
|
||||||
|
tmp.color = this.finalPathColor;
|
||||||
|
tmp = tmp.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
maze.updateMazeDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DepthFirstSolver extends MazeSolver {
|
||||||
|
solve(maze) {
|
||||||
this.currentCell.color = this.searchedColor;
|
this.currentCell.color = this.searchedColor;
|
||||||
|
|
||||||
if(!depthFirst)
|
this.currentCell = this.frontier.pop();
|
||||||
this.currentCell = this.frontier.shift();
|
|
||||||
else
|
|
||||||
this.currentCell = this.frontier.pop();
|
|
||||||
|
|
||||||
this.currentCell.color = this.selectedColor;
|
|
||||||
|
|
||||||
this.currentCell.visited = true;
|
this.currentCell.visited = true;
|
||||||
|
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user