S-Bot

Entry

JavaScriptで自動迷路生成

DATE:10-04-21 Category:Web

はてなブックマークに追加 del.icio.us に追加 livedoorクリップに追加 Yahoo!ブックマークに登録


現在JavaScriptを勉強中ですが、なぜか急に迷路生成のスクリプトを作りたくなったので書いてみました。

調べてみると迷路生成にはいくつかのアルゴリズムがあるらしく、その中でもっともシンプルな「棒倒し法」というナイスなものがあったので、それを採用することにしました。
参考:迷路自動生成アルゴリズム

このアルゴリズムではまず下のようなグリッドを作ることから始まります。

迷路

この状態から中の黒い部分を棒倒しのように左右上下にランダムに倒していきます。
既に棒が倒れている場所には置けません、また2行目移行は上には倒せないというルールがあります。

すべて倒して、スタートとゴールを設定するとこうなります。

というわけで、そこそこシンプルに迷路を自動生成できました。
なぜこのアルゴリズムで迷路ができるのかは、僕に聞かないでください。

気が向いたら赤い点を操作できるようにしたり、高速化したり、HTML5のcanvasでレンダリングをするようにしたり改良するかもしれません。

以下のリンクからデモを見れます。
デモ

以下はソースです。レンダリングの部分でjQueryを使用しています。

//棒倒し法アルゴリズムで迷路生成
maze = function(h,w){
 var h = h;
 var w = w; 
 
 this.make = function(){

  //gridを初期化
  var grid = new Array();
  for(var i = 0; i < h; i++){
   grid[i] = new Array();
   for(var j = 0; j < w; j++){
    if((i == 0 || i + 1 == h || j == 0 || j + 1 == w) || ((i % 2) == 0 && (j % 2) == 0)){
     grid[i][j] = 1;
    }else{
     grid[i][j] = 0;
    }
   }
  } 

  //棒倒し!
  for(var i = 2; i + 2 < grid.length; i += 2){
   for(var j = 2; j + 2 < grid[i].length; j += 2){
    var set = 0;
    switch(Math.floor(Math.random() * 4 + 1)){
     //上
     case 1:
      if(grid[i-1][j] == 0 && i == 2){
       grid[i-1][j] = 1;
       set = 1;
      }
     break;
     //右
     case 2:
      if(grid[i][j+1] == 0){
       grid[i][j+1] = 1;
       set = 1;
      }
     break;
     //下
     case 3:
      if(grid[i+1][j] == 0){
       grid[i+1][j] = 1;
       set = 1;
      }
     break;
     //左
     case 4:
      if(grid[i][j-1] == 0){
       grid[i][j-1] = 1;
       set = 1;
      }
     break;
    }    
    if(set == 0){
     j -= 2;
    }
   } 
  } 
 
  //ゴールとスタート
  grid[1][1] = 2;
  grid[h - 2][w - 2] = 3;
  
  //render
  for(var i = 0; i < grid.length; i++){
   for(var j = 0; j < grid[i].length; j++){
    //壁
    if(grid[i][j] == 1){
     $("#box").append('<img src="img/wall.gif" width="10" height="10" alt="" />')
    //スタート地点
    }else if(grid[i][j] == 2){
     $("#box").append('<img src="img/start.gif" width="10" height="10" alt="" />')
    //ゴール
    }else if(grid[i][j] == 3){
     $("#box").append('<img src="img/goal.gif" width="10" height="10" alt="" />')
    //道
    }else{
     $("#box").append('<img src="img/road.gif" width="10" height="10" alt="" />')
    }
   }
   $("#box").append("<br>")
  }  
  
 };
};

$(document).ready(function() {
 maze = new maze(31,31);
 maze.make();
});

Comment 0

コメントする(アルファベットのみのコメントは投稿できません。)

trackback

このブログ記事に対するトラックバックURL:
http://s-bot.net/MT/mt-tb.cgi/274

twitter

twitter


▲PageTop