mramine364

maze-generation.js

Aug 2nd, 2016
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. function maze_node(txt,ki,kj){
  3.     return {
  4.         name: txt,
  5.         succ: [],
  6.         vis: false,
  7.         ki: ki,
  8.         kj: kj,
  9.         // unVisSucc: 0,
  10.         unVisSucc: function(){
  11.             let r=0;
  12.             for(let i=0;i<this.succ.length;i++){
  13.                 if( this.succ[i].to(this).vis==false )
  14.                     r++;
  15.             }
  16.             return r;
  17.         },
  18.         add: function(e){
  19.             this.succ.push(e);
  20.         },
  21.         randT: function(){
  22.             let unvissucc = this.unVisSucc();
  23.             let i=Math.floor(Math.random()*(unvissucc));
  24.             let k=0, vk=-1;
  25.             while(k<this.succ.length && vk!=i){
  26.                 if( this.succ[k].to(this).vis==false )
  27.                     vk++
  28.                 k++;
  29.             }
  30.             this.succ[k-1].broke = true;
  31.             return this.succ[k-1];
  32.         },
  33.         has: function(i,j){
  34.             let k=0;
  35.             while(k<this.succ.length){
  36.                 let n = this.succ[k].to(this);
  37.                 if( n.ki==i && n.kj==j && this.succ[k].broke==true )
  38.                     return true
  39.                 k++;
  40.             }
  41.             return false;
  42.         },
  43.         get: function(i,j) {
  44.             let k=0;
  45.             while(k<this.succ.length){
  46.                 let n = this.succ[k].to(this);
  47.                 if( n.ki==i && n.kj==j && this.succ[k].broke==true )
  48.                     return n;
  49.                 k++;
  50.             }
  51.             return null;
  52.         }
  53.     }
  54. }
  55.  
  56. function maze_edge(a, b){
  57.     // undirected
  58.     return {
  59.         n1: a,
  60.         n2: b,
  61.         broke: false,
  62.         to: function(n){
  63.             if( n==this.n1 )
  64.                 return this.n2;
  65.             else
  66.                 return this.n1;
  67.         }
  68.     }
  69. }
  70.  
  71. let maze_gen = {
  72.     generate: function(n, m){
  73.         let start= maze_node("start",0,-1), end=maze_node("end",n,m-1);
  74.         let ns = [];
  75.         for(let i=0;i<n;i++){
  76.             ns.push([]);
  77.             for(let j=0;j<m;j++){
  78.                 ns[i].push( maze_node("("+i+","+j+")",i,j) );
  79.             }
  80.         }
  81.         //
  82.         let es = [];
  83.         let ie = maze_edge(start, ns[0][0]);
  84.         es.push(ie);
  85.         start.add(ie);
  86.         for(let i=0;i<n;i++){
  87.             for(let j=0;j<m;j++){
  88.                 if(j+1<m){
  89.                     let e = maze_edge(ns[i][j], ns[i][j+1]);
  90.                     es.push(e);
  91.                     ns[i][j].add(e);
  92.                     ns[i][j+1].add(e);
  93.                 }
  94.                 if( i+1<n ){
  95.                     let e = maze_edge(ns[i][j], ns[i+1][j]);
  96.                     es.push(e);
  97.                     ns[i][j].add(e);
  98.                     ns[i+1][j].add(e);
  99.                 }
  100.             }
  101.         }
  102.         let ee = maze_edge(ns[n-1][m-1], end);
  103.         es.push(ee);
  104.         ns[n-1][m-1].add(ee);
  105.         //
  106.         let unvisited = n*m+2;
  107.         let stack = [];
  108.         let curr = start;
  109.         curr.vis = true; //unvisited--;
  110.         stack.push(start);
  111.         while(/*unvisited>0*/ stack.length>0){
  112.             if( curr.unVisSucc()>0 ){
  113.                 let rt = curr.randT(); // random unvisited transition
  114.                 let rn = rt.to(curr);
  115.                 stack.push(curr);
  116.                 curr=rn;               
  117.                 curr.vis=true;
  118.                 // console.log(curr)
  119.                 //unvisited--;
  120.             }else if( stack.length>0 ){
  121.                 curr = stack.pop();
  122.                 // console.log("pop curr")
  123.                 // console.log(curr)
  124.             }
  125.         }
  126.         // console.log("nodes:")
  127.         // console.log(ns)
  128.         // console.log("edges:")
  129.         // console.log(es)
  130.         return es;
  131.     }
  132. }
  133.  
  134. ////////////// MAZE GAME  ///////////////
  135.  
  136.  
  137. var maze_game = {
  138.     canvas : document.getElementById('mazeGame'),
  139.     context: null,
  140.     edges: null,
  141.     startx: null,
  142.     starty: null,
  143.     egdeLen: null,
  144.     edgeH: null,
  145.     draw : function(rows, lines) {
  146.         if( this.gel!=null ){
  147.             this.canvas.removeEventListener('keydown', this.gel);
  148.             this.gel = null;
  149.         }
  150.         this.context = this.canvas.getContext("2d")
  151.         ctx = this.context;
  152.         ctx.fillStyle = "white";
  153.         ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
  154.         let startx = 30, starty = 20;
  155.         let egdeLen = 30, edgeH = 10;
  156.         let edges = maze_gen.generate(rows,lines);
  157.         this.edges = edges;
  158.         this.startx = startx; this.starty = starty;
  159.         this.egdeLen = egdeLen; this.edgeH = edgeH;
  160.         for(let k=0;k<edges.length;k++){
  161.             let e = edges[k];
  162.             if( e.broke ){
  163.                 let sx,sy,wid,hei;
  164.                 sx = startx+(e.n1.kj)*egdeLen;
  165.                 sy = starty+(e.n1.ki)*egdeLen;
  166.                 if( e.n1.ki == e.n2.ki ){
  167.                     wid = egdeLen+edgeH;
  168.                     hei = edgeH;
  169.                 }else{
  170.                     wid = edgeH;
  171.                     hei = egdeLen+edgeH;
  172.                 }
  173.                 // console.log(sx, sy, wid, hei)
  174.                 ctx.fillRect(sx, sy, wid, hei);
  175.                 // console.log(ctx.fillRect(sx, sy, wid, hei))
  176.             }
  177.         }
  178.     },
  179.     gel: null,
  180.     play: function(){
  181.         // start
  182.         let startx = this.startx, starty = this.starty;
  183.         let egdeLen = this.egdeLen, edgeH = this.edgeH;
  184.         let edges = this.edges;
  185.         let ctx = this.context;
  186.  
  187.         let curr = edges[0].n1;
  188.         this.curr = curr;
  189.         // console.log(curr)
  190.         ctx.fillStyle = "red";
  191.         ctx.fillRect(startx+(curr.kj)*egdeLen,starty+(curr.ki)*egdeLen,edgeH,edgeH);
  192.        
  193.         this.canvas.addEventListener('keydown', this.gel = function(event){
  194.             // Left
  195.             if( event.keyCode == 37 ){
  196.                 // console.log( curr.has(curr.ki, curr.kj-1) )
  197.                 // console.log( curr.get(curr.ki, curr.kj-1) )
  198.                 if( curr.has(curr.ki, curr.kj-1) ){
  199.                     let sx,sy;
  200.                     ctx.fillStyle = "white";
  201.                     sx = startx+(curr.kj)*egdeLen;
  202.                     sy = starty+(curr.ki)*egdeLen;
  203.                     ctx.fillRect(sx,sy,edgeH,edgeH);
  204.                     ctx.fillStyle = "red";
  205.                     curr = curr.get(curr.ki, curr.kj-1);
  206.                     sx = startx+(curr.kj)*egdeLen;
  207.                     sy = starty+(curr.ki)*egdeLen;
  208.                     ctx.fillRect(sx,sy,edgeH,edgeH);
  209.                 }
  210.             }
  211.             // Up
  212.             if( event.keyCode == 38 ){
  213.                 // console.log( curr.has(curr.ki-1, curr.kj) )
  214.                 // console.log( curr.get(curr.ki-1, curr.kj) )
  215.                 if( curr.has(curr.ki-1, curr.kj) ){
  216.                     let sx,sy;
  217.                     ctx.fillStyle = "white";
  218.                     sx = startx+(curr.kj)*egdeLen;
  219.                     sy = starty+(curr.ki)*egdeLen;
  220.                     ctx.fillRect(sx,sy,edgeH,edgeH);
  221.                     ctx.fillStyle = "red";
  222.                     curr = curr.get(curr.ki-1, curr.kj);
  223.                     sx = startx+(curr.kj)*egdeLen;
  224.                     sy = starty+(curr.ki)*egdeLen;
  225.                     ctx.fillRect(sx,sy,edgeH,edgeH);
  226.                 }
  227.             }
  228.             // Right
  229.             if( event.keyCode == 39 ){
  230.                 // console.log( curr.has(curr.ki, curr.kj+1) )
  231.                 // console.log( curr.get(curr.ki, curr.kj+1) )
  232.                 if( curr.has(curr.ki, curr.kj+1) ){
  233.                     let sx,sy;
  234.                     ctx.fillStyle = "white";
  235.                     sx = startx+(curr.kj)*egdeLen;
  236.                     sy = starty+(curr.ki)*egdeLen;
  237.                     ctx.fillRect(sx,sy,edgeH,edgeH);
  238.                     ctx.fillStyle = "red";
  239.                     curr = curr.get(curr.ki, curr.kj+1);
  240.                     sx = startx+(curr.kj)*egdeLen;
  241.                     sy = starty+(curr.ki)*egdeLen;
  242.                     ctx.fillRect(sx,sy,edgeH,edgeH);
  243.                 }
  244.             }
  245.             // Down
  246.             if( event.keyCode == 40 ){
  247.                 // console.log( curr.has(curr.ki+1, curr.kj) )
  248.                 // console.log( curr.get(curr.ki+1, curr.kj) )
  249.                 if( curr.has(curr.ki+1, curr.kj) ){
  250.                     let sx,sy;
  251.                     ctx.fillStyle = "white";
  252.                     sx = startx+(curr.kj)*egdeLen;
  253.                     sy = starty+(curr.ki)*egdeLen;
  254.                     ctx.fillRect(sx,sy,edgeH,edgeH);
  255.                     ctx.fillStyle = "red";
  256.                     curr = curr.get(curr.ki+1, curr.kj);
  257.                     sx = startx+(curr.kj)*egdeLen;
  258.                     sy = starty+(curr.ki)*egdeLen;
  259.                     ctx.fillRect(sx,sy,edgeH,edgeH);
  260.                 }
  261.             }
  262.            
  263.         });
  264.         this.canvas.focus();
  265.         // console.log("play")
  266.     }
  267. }
  268.  
  269. maze_game.draw(17, 17);
  270.  
  271. document.getElementById('generate_btn').addEventListener('click', function(event) {
  272.     let r = parseInt(document.getElementById('rows').value);
  273.     let c = parseInt(document.getElementById('cols').value);
  274.     if( isNaN(r) ){
  275.         r = 17;
  276.     }
  277.     if( isNaN(c) ){
  278.         c = 17;
  279.     }
  280.     maze_game.draw(r, c);
  281. });
  282.  
  283. document.getElementById('play_btn').addEventListener('click', function(event) {
  284.     maze_game.play();
  285. });
Advertisement
Add Comment
Please, Sign In to add comment