迷路を作って遊んでみる4

3回目の続きです。多分このシリーズは最終回。プログラム設計が適当なので、回を追うごとごとにやばい仕様になりつつあります…。

最短経路をハイライトする

前回は迷路の最短経路を求め、文字として以下のように表示しました。

今回はこの経路を実際に迷路上でハイライトしてみます。

経路をハイライト

今回ハイライトの機能はセルを表現するDOM要素の背景色を変えることで実装したいと思います。

まずdisplayメソッドに変更を加え、セルのDOM要素を作る際にidを振り当てます。以下にソースコードを示します。新たにmakeDomElementとpositionToDomIdというメソッドも追加しました。

Maze.prototype.display = function() {

    ……

    for(var i = 0; i < maze.w; i++){
        for (var j = 0; j < maze.h; j++) {
            var cell = this.makeDomElement(i, j); //この部分だけ変更
            place.insert(cell);
        }
    }

    ……
}

Maze.prototype.makeDomElement = function(i, j) {
        var cell = new Element("div", { id : this.positionToDomId(i, j), style : "position:absolute;width:" + this.cellsize + "px;height:" + this.cellsize + "px;left:" + this.cellsize * i + "px;top:" + this.cellsize * j + "px;" });
        switch(maze.array[i][j]){
            case MAZETYPE.BLOCK :
                cell.setStyle("background-color:#2e2e2e");
            break;
            case MAZETYPE.WAY :
                cell.setStyle("background-color:#e0e0e0");
            break;
            case MAZETYPE.START :
                cell.setStyle("background-color:blue");
            break;
            case MAZETYPE.GOAL :
               cell.setStyle("background-color:red");
            break;
        }
        return cell;    
};

/**
 * 座標を元にDOM要素のidを求める
 * @param {Object} x
 * @param {Object} y
 */
Maze.prototype.positionToDomId = function(x, y) {
    return "cell" + ( x + y * this.w);
};
ハイライト

上で作成したセルのDOM要素の色を変える、highlightメソッドを実装します。

Maze.prototype.highlight = function(x, y, color) {
    var e = $( this.positionToDomId(x, y) );
    e.setStyle("background-color:" + color);
};

そして、これを利用してルートをハイライトするrouteHighlightメソッドを実装します

/**
 * 引数で指定されたルートをハイライトする
 * @param {Object} route
 */
Maze.prototype.routeHighlight = function(route) {
    if(!route) return;        
    var list = route.route;
    var from = route.from.position;
    var to = route.to.position;
    if(list.constructor != Array || !from || !to) return;
    this.highlight(from.x, from.y, "yellow");
    for(var i = 0; i < list.length; i++ ){
        var cell = list[i].position;
        this.highlight(cell.x, cell.y, "yellow");
    }
    this.highlight(to.x, to.y, "yellow");
};
利用してみる

例えば最短経路をハイライトする場合は、以下のようになります。

var maze = new Maze(15,15);
maze.setCell(1,1,MAZETYPE.WAY);    
maze.setCell(2,1,MAZETYPE.WAY);
maze.setCell(3,1,MAZETYPE.WAY);

……

maze.setCell(1,1,MAZETYPE.START);
maze.setCell(9,13,MAZETYPE.GOAL);
maze.display(); //迷路を表示


//最短経路を取得
var route = Search.getShortestPath(maze);
maze.routeHighlight(route); //この経路をハイライト

これを表示すると以下のようになります。

以下のURLから実行可能です。

http://www17.atpages.jp/prime503/maze/

おわり

以上で迷路シリーズおわりです。ダイクストラアルゴリズムは少し難しかったですが、迷路自体の作成は結構簡単にできました。最短経路を求めるアルゴリズムは、ダイクストラアルゴリズム以外にもベルマン-フォード法があります。これを使ってみても面白いかもしれませんね。

ダウンロード

HelloMaze3.zip 直