/**
* MAZE
*/
var MAZE = function(cols, rows){
this.cfg = {
width: 10,
height: 10,
wMargin: 5,
hMargin: 5,
maxLoop: 15000,
cols: 10,
rows: 10
};
this.cluster = {};
this.build(cols, rows);
};
MAZE.prototype.build = function(cols, rows){
var _arr = [];
var _col = [];
var _row = [];
var _num = 0;
this.cfg.cols = cols;
this.cfg.rows = rows;
for(var i=0;i<rows;i++){
_arr[i] = [];
for(var j=0;j<cols;j++){
_arr[i][j] = _num++;
}
}
for(var i=0;i<rows;i++){
_col[i] = [];
for(var j=0;j<=cols;j++){
_col[i][j] = (j==0 || j==cols) ? 3 : 1 ;
}
}
for(var i=0;i<=rows;i++){
_row[i] = [];
for(var j=0;j<cols;j++){
_row[i][j] = (i==0 || i==rows) ? 3 : 1 ;
}
}
this.cluster = {
el: _arr,
col: _col,
row: _row
};
this._breakWark();
};
MAZE.prototype._fillNumber = function(tg, num){
var c = this.cluster.el;
for (var i = 0, max = c.length; i < max; i++) {
for (var j = 0, max2 = c[i].length; j < max2; j++) {
if(c[i][j] == tg){
c[i][j] = num;
}
}
}
};
MAZE.prototype._isAllFill = function(){
var check = null;
var c = this.cluster.el;
for (var i = 0, max = c.length; i < max; i++) {
for (var j = 0, max2 = c[i].length; j < max2; j++) {
if(check == null){
check = c[i][j];
}else if(check != c[i][j]){
return false;
}
}
}
return true;
};
MAZE.prototype._borderBreak = function(){
var c = this.cluster;
var cfg = this.cfg;
var type = (Math.round(Math.random()) == 0) ? \'col\' : \'row\' ;
switch(type){
case \'row\':
var colNum = Math.floor(Math.random()*cfg.cols);
var rowNum = Math.floor(Math.random()*cfg.rows);
if(rowNum <= 0) rowNum = 1;
if(c[type][rowNum][colNum] == 1){
var num1 = c.el[rowNum-1][colNum];
var num2 = c.el[rowNum][colNum];
if(num1 == num2){
c[type][rowNum][colNum] = 2;
}else{
this._fillNumber(Math.max(num1, num2), Math.min(num1, num2));
c[type][rowNum][colNum] = 0;
}
}
break;
case \'col\':
var colNum = Math.floor(Math.random()*cfg.cols);
var rowNum = Math.floor(Math.random()*cfg.rows);
if(colNum <= 0) colNum = 1;
if(c[type][rowNum][colNum] == 1){
var num1 = c.el[rowNum][colNum-1];
var num2 = c.el[rowNum][colNum];
if(num1 == num2){
c[type][rowNum][colNum] = 2;
}else{
this._fillNumber(Math.max(num1, num2), Math.min(num1, num2));
c[type][rowNum][colNum] = 0;
}
}
break;
default:
break;
}
};
MAZE.prototype._breakWark = function(){
var i = 1;
while(!this._isAllFill() && (i%this.cfg.maxLoop != 0 || window.confirm(\'処理を継続しますか ?\'))){
this._borderBreak();
i++;
}
};
MAZE.prototype.draw = function(id){
var cfg = this.cfg;
var w = cfg.width;
var h = cfg.height;
var wm = cfg.wMargin;
var hm = cfg.wMargin;
var cols = cfg.cols;
var rows = cfg.rows;
var tg = (typeof(id)==\'string\') ? $(\'#\'+id) : id ;
var col = this.cluster.col;
var row = this.cluster.row;
var ctx, ww = (w * cols + wm * 2), hh = (h * rows + hm * 2);
if(!tg || !tg.get(0).getContext){
return false;
}
ctx = tg.get(0).getContext("2d");
tg.attr(\'width\', ww);
tg.attr(\'height\', hh);
col[0][0] = 0;
col[rows-1][cols] = 0;
ctx.clearRect(0, 0, ww, hh);
ctx.beginPath();
for (var i = 0, max = col.length; i < max; i++) {
for (var j = 0, max2 = col[i].length; j < max2; j++) {
if(col[i][j] > 0){
//tg.drawLine(j*w+wm, i*h+hm, j*w+wm, i*h+h+hm);
ctx.moveTo(j*w+wm, i*h+hm);
ctx.lineTo(j*w+wm, i*h+h+hm);
}
}
}
for (var i = 0, max = row.length; i < max; i++) {
for (var j = 0, max2 = row[i].length; j < max2; j++) {
if(row[i][j] > 0){
//tg.drawLine(j*w+wm, i*h+hm, j*w+w+wm, i*h+hm);
ctx.moveTo(j*w+wm, i*h+hm);
ctx.lineTo(j*w+w+wm, i*h+hm);
}
}
}
ctx.stroke();
col[0][0] = 3;
col[rows-1][cols] = 3;
};
MAZE.prototype.setWidth = function(_num){
this.cfg.width = _num;
};
MAZE.prototype.setHeight = function(_num){
this.cfg.height = _num;
};
MAZE.prototype.setMarginWidth = function(_num){
this.cfg.wMargin = _num;
};
MAZE.prototype.setMarginHeight = function(_num){
this.cfg.hMargin = _num;
};
MAZE.prototype.getWidth = function(){
return this.cfg.width;
};
MAZE.prototype.getHeight = function(){
return this.cfg.height;
};
MAZE.prototype.getMarginWidth = function(){
return this.cfg.wMargin;
};
MAZE.prototype.getMarginHeight = function(){
return this.cfg.hMargin;
};
MAZE.prototype.getCols = function(){
return this.cfg.cols;
};
MAZE.prototype.getRows = function(){
return this.cfg.rows;
};
MAZE.prototype.isTopWall = function(_x, _y){
var row = this.cluster.row;
if(row[_y][_x] > 0){
return true;
}
return false;
};
MAZE.prototype.isRightWall = function(_x, _y){
var col = this.cluster.col;
if(col[_y][_x+1] > 0){
return true;
}
return false;
};
MAZE.prototype.isBottomWall = function(_x, _y){
var row = this.cluster.row;
if(row[_y+1][_x] > 0){
return true;
}
return false;
};
MAZE.prototype.isLeftWall = function(_x, _y){
var col = this.cluster.col;
if(col[_y][_x] > 0){
return true;
}
return false;
};
/**
* MAZE_BOT
*/
var MAZE_BOT = function(maze){
this._maze = maze;
this._map = null;
this._pos = {x:0, y:0};
this._defpos = {x:0, y:0};
this._isStart = false;
this._name = \'MAZE_BOT_\' + (new Date()).getTime();
this._view = null;
this.duration = 10;
this.createMap();
};
MAZE_BOT.prototype.createMap = function(){
var _arr = [];
var point;
var tgX = this._maze.getRows()-1;
var tgY = this._maze.getCols()-1;
var col = this._maze.getCols();
var row = this._maze.getRows();
for (var i = 0; i < row; i++) {
_arr[i] = [];
for (var j = 0; j < col; j++) {
point = Math.abs((tgX + tgY) - (i + j));
_arr[i][j] = point;
}
}
this._map = _arr;
};
MAZE_BOT.prototype.createView = function(id){
if(this._view) return;
this._view = $("<div />");
this._view.width(this._maze.getWidth());
this._view.height(this._maze.getHeight());
this._view.css(\'position\', \'absolute\');
this._view.css(\'background-color\', \'#FF0000\');
var _parent = (typeof(id) == \'string\') ? $(\'#\'+id) : $(id) ;
_parent.append(this._view);
};
MAZE_BOT.prototype.setPos = function(x, y){
var m = this._maze;
this._defpos.x = this._pos.x = x;
this._defpos.y = this._pos.y = y;
var x = m.getWidth() * x + m.getMarginWidth();
var y = m.getHeight() * y + m.getMarginHeight();
this._view.css(\'top\', y + \'px\');
this._view.css(\'left\', x + \'px\');
};
MAZE_BOT.prototype.moveTo = function(x, y){
var m = this._maze;
var x = m.getWidth() * x + m.getMarginWidth();
var y = m.getHeight() * y + m.getMarginHeight();
this._view.animate({
top: y + \'px\',
left: x + \'px\'
},
{
duration: this.duration,
complete: (function(o){
var obj = o;
return function(){
obj.cycle();
};
})(this)
});
};
MAZE_BOT.prototype.reNumberMap = function(){
var x = this._pos.x;
var y = this._pos.y;
var maze = this._maze;
var map = this._map;
var max = maze.getCols() * maze.getRows();
if(map[y][x] == 0) return false;
var pointSum = 0;
var spaceCount = 0;
if(!(maze.isTopWall(x, y) || map[y-1][x] >= max)){
pointSum += map[y-1][x];
spaceCount++;
}
if(!(maze.isRightWall(x, y) || map[y][x+1] >= max)){
pointSum += map[y][x+1];
spaceCount++;
}
if(!(maze.isBottomWall(x, y) || map[y+1][x] >= max)){
pointSum += map[y+1][x];
spaceCount++;
}
if(!(maze.isLeftWall(x, y) || map[y][x-1] >= max)){
pointSum += map[y][x-1];
spaceCount++;
}
if(spaceCount > 1){
map[y][x] = Math.min(
Math.floor(pointSum / spaceCount) + 1,
max
);
}else{
map[y][x] = max;
}
return true;
};
MAZE_BOT.prototype.nextPos = function(){
var x = this._pos.x;
var y = this._pos.y;
var maze = this._maze;
var map = this._map;
var max = maze.getCols() * maze.getRows();
var min = maze.getCols() * maze.getRows();
var obj = {x:x, y:y};
if(!maze.isTopWall(x, y) && map[y-1][x] < max){
if(map[y-1][x] < min){
min = map[y-1][x];
obj = {x:x, y:y-1};
}
}
if(!maze.isRightWall(x, y) && map[y][x+1] < max){
if(map[y][x+1] < min){
min = map[y][x+1];
obj = {x:x+1, y:y};
}
}
if(!maze.isBottomWall(x, y) && map[y+1][x] < max){
if(map[y+1][x] < min){
min = map[y+1][x];
obj = {x:x, y:y+1};
}
}
if(!maze.isLeftWall(x, y) && map[y][x-1] < max){
if(map[y][x-1] < min){
min = map[y][x-1];
obj = {x:x-1, y:y};
}
}
this._pos = obj;
};
MAZE_BOT.prototype.cycle = function(){
if(this._isStart && this.reNumberMap()){
this.nextPos();
this.moveTo(this._pos.x, this._pos.y);
}else if(this._isStart){
this.kill();
}
};
MAZE_BOT.prototype.start = function(){
this._isStart = true;
this.createMap();
this.setPos(this._defpos.x, this._defpos.y);
this.cycle();
};
MAZE_BOT.prototype.stop = function(){
this._isStart = false;
};
MAZE_BOT.prototype.kill = function(){
this.stop();
this._view.animate({
opacity: \'0\'
}, 500);
};
MAZE_BOT.prototype.restart = function(){
this.stop();
this.start();
};
MAZE_BOT.prototype.isStart = function(){
return this._isStart;
};
MAZE_BOT.prototype.name = function(){
return this._name;
};
/**
* Custom
*/
var mazeObj = null;
var mazeBots = [];
var isCtrl = false;
function createMaze(){
if (isCtrl) {
var w = $(\'#mazeWidth\').val();
var h = $(\'#mazeHeight\').val();
for (var i in mazeBots) {
mazeBots[i].kill();
}
mazeObj = new MAZE(w, h);
$(\'#myCanvas\').empty();
mazeObj.draw(\'myCanvas\');
}
};
function createBot(){
if (isCtrl) {
var s = $(\'#botSpeed\').val();
var mb = new MAZE_BOT(mazeObj);
mb.createView(\'botStage\');
mb.setPos(0, 0);
mb.duration = Number(s);
mb.start();
mazeBots.push(mb);
}
};
$(function(){
isCtrl = true;
createMaze();
});