|
- function spawnPathfinder(root) {
-
- class Cell
- {
- is_state(state){return this.State == state}
- reset(){this.make_state("null")}
- make_state(state){this.State = state;}
- draw(grid){
- grid.children[this.Y].children[this.X].classList.remove("animate")
- grid.children[this.Y].children[this.X].classList = "cell " + this.State + ` x${this.X}-y${this.Y}`;
- grid.children[this.Y].children[this.X].style.backgroundPosition = `${this.X * horizontal_cells * 0}px ${this.Y * vertical_cells / 4}px`;
- if(this.State != "null") grid.children[this.Y].children[this.X].classList.add("animate");
-
- }
- update_neighbours(grid, diagonal=true)
- {
- this.neighbours = []
- let space_top = this.Y > 0 && grid[this.Y-1][this.X];
- let space_down = this.Y < vertical_cells - 1 && grid[this.Y+1][this.X];
- let space_left = this.X > 0 && grid[this.Y][this.X-1];
- let space_right = this.X < horizontal_cells - 1 && grid[this.Y][this.X+1];
-
- let shiftXR = this.Y % 2 === 0 ? 0 : 1;
- let shiftXL = this.Y % 2 === 0 ? 1 : 0;
-
- let left = space_left && !grid[this.Y][this.X - 1].is_state("wall");
- let right = space_right && !grid[this.Y][this.X + 1].is_state("wall");
-
- let top_right = space_top && grid[this.Y-1][this.X + 1 - shiftXR] && !grid[this.Y-1][this.X + 1 - shiftXR].is_state("wall");
- let top_left = space_top && grid[this.Y-1][this.X - 1 + shiftXL] && !grid[this.Y-1][this.X - 1 + shiftXL].is_state("wall");
- let down_right = space_down && grid[this.Y+1][this.X + 1 - shiftXR] && !grid[this.Y+1][this.X + 1 - shiftXR].is_state("wall");
- let down_left = space_down && grid[this.Y+1][this.X - 1 + shiftXL] && !grid[this.Y+1][this.X - 1 + shiftXL].is_state("wall");
-
-
- if(top_right) this.neighbours.push(grid[this.Y-1][this.X + 1 - shiftXR]);
-
- if(top_left) this.neighbours.push(grid[this.Y-1][this.X - 1 + shiftXL]);
-
- if(down_right) this.neighbours.push(grid[this.Y+1][this.X + 1 - shiftXR]);
-
- if(down_left) this.neighbours.push(grid[this.Y+1][this.X - 1 + shiftXL]);
-
- if(right) this.neighbours.push(grid[this.Y][this.X+1]);
-
- if(left) this.neighbours.push(grid[this.Y][this.X-1]);
- }
-
- update_wall_neighbours(grid,space=1)
- {
- this.wall_neighbours = []
-
- let space_top = this.Y > space;
- let space_down = this.Y < vertical_cells - 1 - space;
- let space_left = this.X > space;
- let space_right = this.X < horizontal_cells - 1 - space;
-
- if(space_top) this.wall_neighbours.push(grid[this.Y-1-space][this.X]);// UP
-
- if(space_down) this.wall_neighbours.push(grid[this.Y+1+space][this.X]);// DOWN
-
- if(space_right) this.wall_neighbours.push(grid[this.Y][this.X+1+space]);// RIGHT
-
- if(space_left) this.wall_neighbours.push(grid[this.Y][this.X-1-space]);// LEFT
- }
-
- constructor(X,Y)
- {
- this.X = X;
- this.Y = Y;
- this.State = "null"
- this.neighbours = []
- this.wall_neighbours = []
- }
- }
- // Main grid
- let grid = [];
-
- // Grid element
- let body = root;
- let grid_HTML = root.getElementsByClassName("grid")[0];
- let navbar_HTML = root.getElementsByClassName("navbar")[0];
- let speed_range = root.getElementsByClassName("range-speed")[0];
- let algo_select = root.getElementsByClassName("algo-select")[0];
- let maze_algo_select = root.getElementsByClassName("maze-algo-select")[0];
-
- const window_y = (body.scrollHeight - navbar_HTML.scrollHeight);
- const window_x = body.scrollWidth;
-
- let horizontal_cells;
- let vertical_cells;
- let tile_size ;
- let placing_tiles = false;
- let erasing_tiles = false;
- let dragging_tile = false;
- let dragged_tile = "";
- let is_running = false;
-
-
- tile_size = "big"
- horizontal_cells = Math.floor(window_x / 35);
- vertical_cells = Math.floor(window_y / 35);
-
- horizontal_cells = Math.floor( (window_x - horizontal_cells) /35);
- vertical_cells = Math.floor( (window_y - vertical_cells) / 35 * 0.9);
-
- grid_HTML.style.width = `${horizontal_cells * 35}px`;
- grid_HTML.style.height = `${vertical_cells * 30}px`;
-
-
- // Start and End nodes
- let start_node = [Math.floor(horizontal_cells/3) , Math.floor(vertical_cells/2)];
- let end_node = [Math.floor(horizontal_cells/3*2) , Math.floor(vertical_cells/2)];
-
- let start_node_initial = [Math.floor(horizontal_cells/3) , Math.floor(vertical_cells/2)]
- let end_node_initial = [Math.floor(horizontal_cells/3*2) , Math.floor(vertical_cells/2)]
-
- // Populating grid
- for(var i = 0; i < vertical_cells; i++)
- {
- let row = [];
- let odd = i % 2 === 0;
- var row_HTML = document.createElement("div");
- row_HTML.classList = "row " + tile_size + (odd ? " odd" : "");
- for(var j = 0; j < horizontal_cells; j++)
- {
- let cell = new Cell(j,i);
- row.push(cell);
-
- var cell_HTML = document.createElement("div");
- cell_HTML.classList.add("cell");
- row_HTML.appendChild(cell_HTML);
- }
- grid.push(row);
-
- grid_HTML.appendChild(row_HTML);
- }
- // Setting tile placing
- for(var i = 0; i < vertical_cells; i++)
- {
- for(var j = 0; j < horizontal_cells; j++)
- {
- grid[i][j].draw(grid_HTML);
- grid_HTML.children[i].children[j].X=j;
- grid_HTML.children[i].children[j].Y=i;
-
- grid_HTML.children[i].children[j].onmouseover = function()
- {
- if(placing_tiles) PlaceTile(this.X,this.Y);
- else if(erasing_tiles) ResetTile(this.X,this.Y);
-
- if(dragging_tile) this.classList = "cell "+dragged_tile
- } ;
- grid_HTML.children[i].children[j].onmouseleave = function()
- {
- if(dragged_tile) grid[this.Y][this.X].draw(grid_HTML);
- }
- grid_HTML.children[i].children[j].onmousedown = function() {
- if(this.X == start_node[0] && this.Y == start_node[1] || this.X == end_node[0] && this.Y == end_node[1]){
- dragging_tile = true;
- dragged_tile = grid[this.Y][this.X].State;
- }
- else{
- if(grid[this.Y][this.X].is_state("wall")) erasing_tiles = true;
- else placing_tiles = true;
-
- if(placing_tiles) PlaceTile(this.X,this.Y);
- if(erasing_tiles) ResetTile(this.X,this.Y)
- }
- }
- grid_HTML.children[i].children[j].onmouseup = function() {
- if(dragging_tile)
- {
- dragging_tile = false;
- PlaceTile(this.X,this.Y,dragged_tile)
- }
- }
- grid_HTML.children[i].children[j].ondragstart = function(){return false};
- grid_HTML.children[i].children[j].ondrop = function(){return false};
- }
- }
-
- grid_HTML.onmouseup = function() {
- placing_tiles = false
- erasing_tiles = false
- }
-
- PlaceTile(start_node_initial[0],start_node_initial[1],"start")
- PlaceTile(end_node_initial[0],end_node_initial[1],"end")
-
- async function SelectChange(select)
- {
- if(select == "maze-algo-select")
- {
- await RunMaze();
- }
- }
-
- function PlaceTile(x,y,tile = "wall")
- {
- if(is_running) return;
- let is_start = start_node.length != 0 ? x==start_node[0] && y==start_node[1] : false;
- let is_end = end_node.length != 0 ? x==end_node[0] && y==end_node[1] : false;
-
- if(start_node.length == 0 || tile == "start"){
- if(!is_end){
- if(start_node.length != 0) ResetTile(start_node[0],start_node[1], true);
-
- grid[y][x].make_state("start");
- start_node = [x,y];
- }
- }
- else if(end_node.length == 0 || tile == "end"){
- if(!is_start){
- if(end_node.length != 0) ResetTile(end_node[0],end_node[1], true);
-
- grid[y][x].make_state("end");
- end_node = [x,y]
- }
- }
- else{
- if(!is_start && !is_end){
- grid[y][x].make_state("wall");
- }
- }
- grid[y][x].draw(grid_HTML);
- }
-
- function ResetTile(x,y,full=false)
- {
- if(is_running) return
- if(full){
- grid[y][x].reset();
- grid[y][x].draw(grid_HTML);
- return;
- }
- if(grid[y][x].is_state("wall"))
- {
- grid[y][x].reset();
- }
- grid[y][x].draw(grid_HTML);
- }
-
- async function ReconstructPath(came_from, current)
- {
- while(came_from[""+current.X+"y"+current.Y] != undefined){
- current = came_from[""+current.X+"y"+current.Y]
- current.make_state("path")
- current.draw(grid_HTML);
- await sleep(25)
- }
- }
-
- function sleep (time) {
- return new Promise((resolve) => setTimeout(resolve, time));
- }
-
- function ResetPath()
- {
- if(is_running) return
- for(var i = 0; i < vertical_cells; i++){
- for(var j = 0; j < horizontal_cells; j++){
- let cell = grid[i][j];
- if(!cell.is_state("wall") && !cell.is_state("start") && !cell.is_state("end")){
- grid[i][j].reset();
- grid[i][j].draw(grid_HTML);
- }
- }
- }
- }
-
- function ClearWalls()
- {
- if(is_running) return
- for(var i = 0; i < vertical_cells; i++){
- for(var j = 0; j < horizontal_cells; j++){
- let cell = grid[i][j];
- if(cell.is_state("wall")){
- grid[i][j].reset();
- grid[i][j].draw(grid_HTML);
- }
- }
- }
- }
-
- function ClearGrid()
- {
- if(is_running) return
- start_node = [];
- end_node = [];
- for(var i = 0; i < vertical_cells; i++){
- for(var j = 0; j < horizontal_cells; j++){
- grid[i][j].reset();
- grid[i][j].draw(grid_HTML);
- }
- }
- PlaceTile(start_node_initial[0],start_node_initial[1])
- PlaceTile(end_node_initial[0],end_node_initial[1])
- }
-
- async function Run()
- {
- let algo = algo_select.value;
- switch(algo){
- case "AStar":
- await RunAStar();
- break;
- case "Dijkstra":
- await RunDijkstra();
- break;
- case "BFS":
- await RunBFS();
- break;
- case "DFS":
- await RunDFS();
- break;
- case "Greedy":
- await RunGreedy();
- break;
- }
- }
-
- async function RunAStar()
- {
- if(is_running) return;
- ResetPath();
- is_running = true;
- let start = grid[start_node[1]][start_node[0]];
- let end = grid[end_node[1]][end_node[0]];
- for (var row of grid)
- {
- for (var cell of row)
- {
- cell.update_neighbours(grid)
- }
- }
- let count = 0;
- let open_set = [];
- open_set.push([0,count,start]);
- let came_from = {}
-
- let g_score = {}
- for(let row of grid){
- for(let cell of row){
- g_score[""+cell.X+"y"+cell.Y] = Number.MAX_VALUE
- }
- }
- g_score[""+start.X+"y"+start.Y] = 0;
- let f_score = {}
- for(let row of grid){
- for(let cell of row){
- f_score[""+cell.X+"y"+cell.Y] = Number.MAX_VALUE
- }
- }
- f_score[""+start.X+"y"+start.Y] = H(start_node[0],start_node[1],end_node[0],end_node[1]);
-
- let open_set_hash = new Set();
- open_set_hash.add(start);
-
- while(!open_set.length == 0)
- {
- let current = open_set[0][2]
- let current_smallest = Number.MAX_VALUE
- let temp_index = 0;
- for(let cell = 0; cell < open_set.length; cell ++)
- {
- if(open_set[cell][0] < current_smallest)
- {
- temp_index = cell;
- current = open_set[cell][2]
- current_smallest = open_set[cell][0]
- }
- }
- open_set.splice(temp_index, 1);
- open_set_hash.delete(current)
- if(current == end)
- {
- // make path
- end.make_state("end")
- start.make_state("start")
- end.draw(grid_HTML);
- start.draw(grid_HTML)
- await ReconstructPath(came_from,end)
- end.make_state("end")
- start.make_state("start")
- end.draw(grid_HTML);
- start.draw(grid_HTML)
- is_running = false;
- return
- }
-
- for(var neighbour of current.neighbours){
- let temp_g_score = g_score[""+current.X+"y"+current.Y]+1
- if(temp_g_score < g_score[""+neighbour.X+"y"+neighbour.Y] || g_score[""+neighbour.X+"y"+neighbour.Y] == undefined){
- came_from[""+neighbour.X+"y"+neighbour.Y] = current
- g_score[""+neighbour.X+"y"+neighbour.Y] = temp_g_score
- f_score[""+neighbour.X+"y"+neighbour.Y] = temp_g_score + H(neighbour.X,neighbour.Y, end.X,end.Y)
- if(!open_set_hash.has(neighbour)){
- count++;
- open_set.push([f_score[""+neighbour.X+"y"+neighbour.Y],count,neighbour])
- open_set_hash.add(neighbour)
- neighbour.make_state("open")
- }
- neighbour.draw(grid_HTML)
- }
- }
- if(current != start)
- {
- current.make_state("closed");
- current.draw(grid_HTML)
- }
-
- await sleep(200-speed_range.value)
- }
- is_running = false;
- }
-
- function H(x1,y1,x2,y2){
- return Math.abs(x1-x2)+Math.abs(y1-y2);
- }
-
- async function RunDijkstra()
- {
- if(is_running) return;
- ResetPath();
- is_running = true;
- let start = grid[start_node[1]][start_node[0]];
- let end = grid[end_node[1]][end_node[0]];
-
- let dist = {};
- let prev = {};
- let Q = []
-
-
- for (var row of grid)
- {
- for (var cell of row)
- {
- cell.update_neighbours(grid)
- }
- }
-
- for(var row of grid){
- for(var cell of row){
- dist[""+cell.X+"y"+cell.Y] = Number.MAX_VALUE;
- prev[""+cell.X+"y"+cell.Y] = null;
- Q.push(cell)
- }
- }
- dist[""+start.X+"y"+start.Y] = 0;
-
- while (Q.length > 0)
- {
- let u = Q[0];
- let current_smallest = Number.MAX_VALUE;
- let temp_index = 0;
- for(let cell = 0; cell < Q.length; cell ++)
- {
- if(parseFloat(dist[""+Q[cell].X+"y"+Q[cell].Y]) < current_smallest)
- {
- temp_index = cell;
- current_smallest = parseFloat(dist[""+ Q[cell].X+"y"+ Q[cell].Y]);
- u = Q[cell];
- }
- }
- Q.splice(temp_index, 1);
-
- if(current_smallest == Number.MAX_VALUE)
- {
- is_running = false;
- return;
- }
- for(let v of u.neighbours)
- {
- if(Q.indexOf(v) != -1)
- {
- let alt = parseFloat(dist[""+u.X+"y"+u.Y]) + H(u.X,u.Y,v.X,v.Y);
- if(alt < parseFloat(dist[""+v.X+"y"+v.Y])){
- dist[""+v.X+"y"+v.Y] = alt;
- prev[""+v.X+"y"+v.Y] = u;
- }
- v.make_state("open");
- v.draw(grid_HTML);
- }
- if(v == end)
- {
- end.make_state("end")
- start.make_state("start")
- end.draw(grid_HTML);
- start.draw(grid_HTML)
- await ReconstructPath(prev,end)
- end.make_state("end")
- start.make_state("start")
- end.draw(grid_HTML);
- start.draw(grid_HTML)
- is_running = false;
- return
- }
- }
-
- if(u != start && u != end)
- {
- u.make_state("closed");
- u.draw(grid_HTML);
- }
- await sleep(200-speed_range.value)
- }
- is_running = false;
- }
-
- async function RunBFS()
- {
- if(is_running) return;
- ResetPath();
- is_running = true;
- let start = grid[start_node[1]][start_node[0]];
- let end = grid[end_node[1]][end_node[0]];
-
- let disc = [];
- let prev = {};
- let Q = []
-
- disc.push(start)
- Q.push(start)
-
- for (var row of grid)
- {
- for (var cell of row)
- {
- cell.update_neighbours(grid)
- }
- }
-
- while(Q.length > 0)
- {
- let v = Q[0];
- Q.splice(0,1);
-
- for(var n of v.neighbours)
- {
- if(disc.indexOf(n) == -1)
- {
- disc.push(n);
- Q.push(n);
- n.make_state("open");
- n.draw(grid_HTML);
- prev[""+n.X+"y"+n.Y] = v;
- if(n == end)
- {
- end.make_state("end")
- start.make_state("start")
- end.draw(grid_HTML);
- start.draw(grid_HTML)
- await ReconstructPath(prev,end)
- end.make_state("end")
- start.make_state("start")
- end.draw(grid_HTML);
- start.draw(grid_HTML)
- is_running = false;
- return
- }
- }
- }
- if(v != start && v != end)
- {
- v.make_state("closed");
- v.draw(grid_HTML);
- }
- await sleep(200-speed_range.value)
- }
- is_running = false;
- }
-
- async function RunDFS()
- {
- if(is_running) return;
- ResetPath();
- is_running = true;
- let start = grid[start_node[1]][start_node[0]];
- let end = grid[end_node[1]][end_node[0]];
-
- let disc = [];
- let prev = {};
- let S = []
-
- S.push(start)
-
- for (var row of grid)
- {
- for (var cell of row)
- {
- cell.update_neighbours(grid,false)
- }
- }
-
- while(S.length > 0)
- {
- let v = S.pop();
- disc.push(v);
-
- for(var i = v.neighbours.length-1;i>=0;i--)
- {
- let n = v.neighbours[i];
- if(disc.indexOf(n) == -1)
- {
- n.make_state("open");
- n.draw(grid_HTML);
- prev[""+n.X+"y"+n.Y] = v;
- if(n == end)
- {
- end.make_state("end")
- start.make_state("start")
- end.draw(grid_HTML);
- start.draw(grid_HTML)
- await ReconstructPath(prev,end)
- end.make_state("end")
- start.make_state("start")
- end.draw(grid_HTML);
- start.draw(grid_HTML)
- is_running = false;
- return
- }
- else{
- S.push(n)
- }
- }
- }
- if(v != start && v != end)
- {
- v.make_state("closed");
- v.draw(grid_HTML);
- }
- await sleep(200-speed_range.value)
- }
- is_running = false;
- }
-
- async function RunGreedy()
- {
- if(is_running) return;
- ResetPath();
- is_running = true;
- let start = grid[start_node[1]][start_node[0]];
- let end = grid[end_node[1]][end_node[0]];
-
- let dist = {}
- let disc = []
- let prev = {};
- let Q = []
-
- for (var row of grid)
- {
- for (var cell of row)
- {
- cell.update_neighbours(grid)
- }
- }
-
- for(let row of grid){
- for(let cell of row){
- dist[""+cell.X+"y"+cell.Y] = Number.MAX_VALUE
- }
- }
- dist[""+start.X+"y"+start.Y] = H(start.X,start.Y,end.X,end.Y);
- Q.push(start);
-
- while(Q.length > 0){
- let u = Q[0];
- let current_smallest = Number.MAX_VALUE;
- let temp_index = 0;
- for(let cell = 0; cell < Q.length; cell ++)
- {
- if(parseFloat(dist[""+Q[cell].X+"y"+Q[cell].Y]) < current_smallest)
- {
- temp_index = cell;
- current_smallest = parseFloat(dist[""+ Q[cell].X+"y"+ Q[cell].Y]);
- u = Q[cell];
- }
- }
- Q.splice(temp_index, 1);
- disc.push(u);
-
- if(u == end)
- {
- end.make_state("end")
- start.make_state("start")
- end.draw(grid_HTML);
- start.draw(grid_HTML)
- await ReconstructPath(prev,end)
- end.make_state("end")
- start.make_state("start")
- end.draw(grid_HTML);
- start.draw(grid_HTML)
- is_running = false;
- return
- }
-
- for(var n of u.neighbours)
- {
- if(disc.indexOf(n) == -1)
- {
- dist[""+n.X+"y"+n.Y] = H(n.X,n.Y,end.X,end.Y);
- disc.push(n);
- Q.push(n);
- n.make_state("open");
- n.draw(grid_HTML);
- prev[""+n.X+"y"+n.Y] = u;
- }
- }
- if(u != start && u != end)
- {
- u.make_state("closed");
- u.draw(grid_HTML);
- }
- await sleep(200-speed_range.value)
- }
- is_running = false;
- }
-
-
-
- // MAZES
- async function RunMaze()
- {
- ClearGrid();
- is_running = true;
- for (var row of grid)
- {
- for (var cell of row)
- {
- cell.update_wall_neighbours(grid);
- cell.update_neighbours(grid,false);
- cell.visited_fill = null;
- cell.visited = null;
- cell.connect_visited = null;
- }
- }
-
-
-
- let ctX = Math.floor(horizontal_cells/2);
- let ctY = Math.floor(vertical_cells/2);
-
- if(grid[ctY][ctX].is_state("start") || grid[ctY][ctX].is_state("end") && !grid[ctY+1][ctX].is_state("start") && !grid[ctY+1][ctX].is_state("end"))
- {
- ctY++;
- }
- else if(grid[ctY+1][ctX].is_state("start") || grid[ctY+1][ctX].is_state("end") && !grid[ctY][ctX+1].is_state("start") && !grid[ctY][ctX+1].is_state("end")){
- ctX++;
- }
-
-
-
- let algo = maze_algo_select.value;
- switch(algo){
- case "DFS":
- FillWithWalls();
- await RecursiveMazeDFS(ctY,ctX);
- break;
- case "Prim":
- FillWithWalls();
- await MazePrim(grid[ctY][ctX]);
- break;
- case "Random":
- FillWithWalls();
- await RecursiveMazeRandom(grid[ctY][ctX]);
- break;
- }
-
- is_running = false;
-
-
- }
-
-
- function FillWithWalls()
- {
- if(!grid[0][0].is_state("start") && !grid[0][0].is_state("end"))
- {
- RecursiveFillWithWalls(grid[0][0]);
- }
- else if(!grid[0][1].is_state("start") && !grid[0][1].is_state("end"))
- {
- RecursiveFillWithWalls(grid[0][1]);
- }
- else{
- RecursiveFillWithWalls(grid[1][0]);
- }
-
- }
-
- function RecursiveFillWithWalls(current)
- {
- if(current.is_state("start") || current.is_state("end")) return;
- current.make_state("wall");
- current.draw(grid_HTML);
- current.visited_fill = true;
- for(let n of current.neighbours)
- {
- if(n.visited_fill != true)RecursiveFillWithWalls(n);
- }
- }
-
- async function RecursiveMazeRandom(current)
- {
- current.visited = true;
- let neighbours = current.wall_neighbours;
- while(neighbours.length > 0)
- {
- let idx = Math.floor(Math.random() * neighbours.length);
- let n = neighbours[idx];
- neighbours.splice(idx,1);
-
- if(n.visited != true)
- {
- n.visited = true;
- let wall = [];
- if(n.X == current.X) wall = [n.X, n.Y>current.Y ? current.Y+1 : n.Y+1 ];
- else wall = [n.X>current.X ? current.X+1 : n.X+1, n.Y ];
-
- let wall_cell = grid[wall[1]][wall[0]]
- if(!wall_cell.is_state("start") && !wall_cell.is_state("end"))
- {
- wall_cell.make_state("null");
- wall_cell.draw(grid_HTML);
- }
- //await sleep(1);
- await RecursiveMazeRandom(wall_cell);
-
- }
- }
- }
-
- async function RecursiveMazeDFS(r,c)
- {
- let randDirs = [1,2,3,4];
- shuffle(randDirs);
- for (var i = 0; i < randDirs.length; i++) {
-
- switch(randDirs[i]){
- case 1:
- if (r - 2 <= 0 )
- continue;
- if (grid[r - 2][c].State != "null") {
- if(!grid[r-2][c].is_state("start") && !grid[r-2][c].is_state("end")) grid[r-2][c].make_state("null");
- if(!grid[r-1][c].is_state("start") && !grid[r-1][c].is_state("end")) grid[r-1][c].make_state("null");
-
- grid[r-2][c].draw(grid_HTML);
- grid[r-1][c].draw(grid_HTML);
-
- await sleep(1);
- RecursiveMazeDFS(r - 2, c);
- }
- break;
- case 2:
- if (c + 2 >= horizontal_cells - 1)
- continue;
- if (grid[r][c + 2].State != "null") {
- if(!grid[r][c + 2].is_state("start") && !grid[r][c + 2].is_state("end")) grid[r][c + 2].make_state("null");
- if(!grid[r][c + 1].is_state("start") && !grid[r][c + 1].is_state("end")) grid[r][c + 1].make_state("null");
-
- grid[r][c + 2].draw(grid_HTML);
- grid[r][c + 1].draw(grid_HTML);
-
- await sleep(1);
- RecursiveMazeDFS(r, c + 2);
- }
- break;
- case 3:
- if (r + 2 >= vertical_cells - 1)
- continue;
- if (grid[r + 2][c].State != "null") {
- if(!grid[r+2][c].is_state("start") && !grid[r+2][c].is_state("end")) grid[r+2][c].make_state("null");
- if(!grid[r+1][c].is_state("start") && !grid[r+1][c].is_state("end")) grid[r+1][c].make_state("null");
-
- grid[r+2][c].draw(grid_HTML);
- grid[r+1][c].draw(grid_HTML);
-
- await sleep(1);
- RecursiveMazeDFS(r + 2, c);
- }
- break;
- case 4:
- if (c - 2 <= 0)
- continue;
- if (grid[r][c - 2].State != "null") {
- if(!grid[r][c - 2].is_state("start") && !grid[r][c - 2].is_state("end")) grid[r][c - 2].make_state("null");
- if(!grid[r][c - 1].is_state("start") && !grid[r][c - 1].is_state("end")) grid[r][c - 1].make_state("null");
-
- grid[r][c - 2].draw(grid_HTML);
- grid[r][c - 1].draw(grid_HTML);
-
- await sleep(1);
- RecursiveMazeDFS(r, c - 2);
- }
- break;
- }
- }
-
- }
-
- async function MazePrim(start)
- {
-
- for(var row of grid){
- for(var cell of row){
- cell.update_wall_neighbours(grid,0);
- }
- }
-
- start.make_state("null");
- start.draw(grid_HTML);
- start.visited = true;
-
- let walls = [];
-
- for(let n of start.wall_neighbours){
- if(n.is_state("wall")) walls.push(n);
- }
-
- while(walls.length > 0)
- {
- let idx = Math.floor(Math.random() * walls.length);
- let r = walls[idx];
- walls.splice(idx,1);
-
- if( !(r.X <= 0 || r.X >= horizontal_cells-1) ){
-
- let prev = grid[r.Y][r.X-1];
- let next = grid[r.Y][r.X+1];
-
- if(prev.visited != true && next.visited == true){
- if(!r.is_state("start") && !r.is_state("end")){
- r.make_state("null");
- r.draw(grid_HTML);
- }
-
- prev.visited = true;
- if(!prev.is_state("start") && !prev.is_state("end")){
- prev.make_state("null");
- prev.draw(grid_HTML);
- }
-
- for(var n of prev.wall_neighbours){
- if(n.is_state("wall")) walls.push(n);
- }
- }
- else if(prev.visited == true && next.visited != true){
- if(!r.is_state("start") && !r.is_state("end")){
- r.make_state("null");
- r.draw(grid_HTML);
- }
-
- next.visited = true;
- if(!next.is_state("start") && !next.is_state("end")){
- next.make_state("null");
- next.draw(grid_HTML);
- }
-
- for(var n of next.wall_neighbours){
- if(n.is_state("wall")) walls.push(n);
- }
- }
- }
-
- if( !(r.Y <= 0 || r.Y >= vertical_cells-1) ){
- let prev = grid[r.Y-1][r.X];
- let next = grid[r.Y+1][r.X];
-
- if(prev.visited != true && next.visited == true){
- if(!r.is_state("start") && !r.is_state("end")){
- r.make_state("null");
- r.draw(grid_HTML);
- }
-
- prev.visited = true;
- if(!prev.is_state("start") && !prev.is_state("end")){
- prev.make_state("null");
- prev.draw(grid_HTML);
- }
-
- for(var n of prev.wall_neighbours){
- if(n.is_state("wall")) walls.push(n);
- }
- }
- else if(prev.visited == true && next.visited != true){
- if(!r.is_state("start") && !r.is_state("end")){
- r.make_state("null");
- r.draw(grid_HTML);
- }
-
- next.visited = true;
- if(!next.is_state("start") && !next.is_state("end")){
- next.make_state("null");
- next.draw(grid_HTML);
- }
-
- for(var n of next.wall_neighbours){
- if(n.is_state("wall")) walls.push(n);
- }
- }
- }
- await sleep(0);
- }
-
- }
-
- function RecursiveAreConnected(start,end)
- {
- if(start == end) return true;
- start.connect_visited = true;
- let connected = false;
- start.update_neighbours(grid,false);
- for(var n of start.neighbours)
- {
- if(n == end) return true;
- if(n.connect_visited != true) connected = connected || RecursiveAreConnected(n,end);
- }
- return connected;
-
- }
-
- function shuffle(array) {
- array.sort(() => Math.random() - 0.5);
- }
-
- return {Run, RunMaze};
- }
|