左上を迷路のスタート地点、右下を迷路のゴール地点とし、0と1の配列で道と壁を作成しています。迷路作成のアルゴリズムは、棒倒し法で記載しています。考えた人は天才ですね。。
棒倒し法
1.一つとびに壁を作る 1れつ目の棒を上下左右のどちらかに倒す
2.2列目以降の棒を左以外のどれかに倒す
00010
11010
00000
01011
01000
どの位置を0から1に変更するかは、以下のように記載します。
var points = [
[0, -1],
[0, 1],
[1, 0],
[-1, 0],
];
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MAZE</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<style>
body {
font-family: "Century Gothic";
font-size: 16px;
}
#container {
text-align: center;
margin: 20px auto;
}
#mycanvas {
background: #AAEDFF;
}
.btn {
margin: 3px auto;
width: 200px;
padding: 5px;
background: #00AAFF;
color: #ffffff;
border-radius:3px;
cursor: pointer;
}
.btn:hover{
opacity: 0.8;
}
</style>
</head>
<body>
<div id="container">
<canvas width="100" height="100" id="mycanvas">
Canvasに対応したブラウザを用意してください。
</canvas>
<div id="reset" class="btn">RESET</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
(function(){
var Maze = function(col, row){
this.map = [];
this.col = col;
this.row = row;
this.startX = 0;
this.startY = 0;
this.goalX =col - 1;
this.goalY =row - 1;
this.points = [
[0, -1],
[0, 1],
[1, 0],
[-1, 0],
];
this.rand = function(n) {
return Math.floor(Math.random() * (n + 1));
};
this.init = function() {
for (var x = 0; x < col; x++) {
this.map[x] = [];
for (var y = 0; y < row; y++) {
this.map[x][y] = 0;
}
}
for (var x = 1; x < col; x += 2) {
for (var y = 1; y < row; y += 2) {
this.map[x][y] = 1;
}
}
for (var x = 1; x < col; x += 2) {
for (var y = 1; y < row; y += 2) {
do {
if (x === 1) {
// 上下左右に倒す
var r = this.points[this.rand(3)];
} else {
// 左以外に倒す
var r = this.points[this.rand(2)];
}
} while (this.map[x + r[0]][y + r[1]] === 1);
this.map[x + r[0]][y + r[1]] = 1;
}
}
};
this.draw = function() {
var view = new View();
view.draw(this);
};
};
var View = function(){
this.wallSize = 10;
this.wallColor = '#3261AB';
this.routeColor = '#ff0088';
this.canvas = document.getElementById('mycanvas');
if (!this.canvas || !this.canvas.getContext){
return false;
}
this.ctx = this.canvas.getContext('2d');
this.draw = function(maze){
this.canvas.width = (maze.col + 2) * this.wallSize;
this.canvas.height = (maze.row + 2) * this.wallSize;
// 上下の壁
for (var x = 0; x < maze.col + 2; x++) {
this.drawWall(x, 0);
this.drawWall(x, maze.row + 1);
}
// 左右の壁
for (var y = 0; y < maze.row + 2; y++) {
this.drawWall(0, y);
this.drawWall(maze.col + 1, y);
}
// 迷路の内部
for (var x = 0; x < maze.col; x++){
for(var y = 0; y < maze.row; y++){
if(maze.map[x][y] === 1){
this.drawWall(x + 1, y + 1);
}
if ((x === maze.startX && y === maze.startY) || (x === maze.goalX && y === maze.goalY))
{
this.drawRoute(x + 1, y + 1);
}
}
}
};
this.drawWall = function(x, y) {
this.ctx.fillStyle = this.wallColor;
this.drawRect(x, y);
};
this.drawRoute = function(x, y) {
this.ctx.fillStyle = this.routeColor;
this.drawRect(x, y);
};
this.drawRect = function(x, y){
this.ctx.fillRect(
x * this.wallSize,
y * this.wallSize,
this.wallSize,
this.wallSize);
};
};
function reset(){
var maze = new Maze(13, 13);
maze.init();
maze.draw();
}
reset();
document.getElementById('reset').addEventListener('click', function(){
reset();
});
// // 迷路のデータを配列で用意
// // 0と1の配列で、1を壁と表現する ※奇数でないと道ができない
// // canvasで描画
// // 棒倒し法
// // 一つとびに壁を作る 1れつ目の棒を上下左右のどちらかに倒す
// // 2列目以降の棒を左以外のどれかに倒す
// // 00010
// // 11010
// // 00000
// // 01011
// // 01000
// var map = [];
// // map[0] = [0, 0, 0];
// // map[1] = [0, 1, 1];
// // map[2] = [0, 0, 0];
// var col = 13; // 奇数
// var row = 13; // 奇数
// for (var x = 0; x < col; x++){
// map[x] = [];
// for (var y = 0; y < row; y++){
// map[x][y] = 0;
// }
// }
// for (var x = 1; x < col; x += 2){
// for(var y = 1; y < row; y += 2){
// map[x][y] = 1;
// }
// }
// var points = [
// [0, -1],
// [0, 1],
// [1, 0],
// [-1, 0],
// ];
// function rand(n){
// return Math.floor(Math.random() * (n + 1));
// }
// for (var x = 1; x < col; x += 2){
// for(var y = 1; y < row; y += 2){
// map[x][y] = 1;
// do {
// if (x === 1){
// var r = points[rand(3)];
// } else {
// var r = points[rand(2)];
// }
// } while (map[x + r[0]][y + r[1]] === 1);
// map[x + r[0]][y + r[1]] = 1;
// }
// }
// var startX = 0;
// var startY = 0;
// var goalX =col - 1;
// var goalY =row - 1;
// var wallSize = 10;
// var wallColor = '#3261AB';
// var routeColor = '#ff0088';
// var canvas = document.getElementById('mycanvas');
// if (!canvas || !canvas.getContext){
// return false;
// }
// var ctx = canvas.getContext('2d');
// canvas.width = (col + 2) * wallSize;
// canvas.height = (row + 2) * wallSize;
// // 上下の壁
// for (var x = 0; x < col + 2; x++) {
// drawWall(x, 0);
// drawWall(x, row + 1);
// }
// // 左右の壁
// for (var y = 0; y < row + 2; y++) {
// drawWall(0, y);
// drawWall(col + 1, y);
// }
// // 迷路の内部
// for (var x = 0; x < col; x++){
// for(var y = 0; y < row; y++){
// if(map[x][y] === 1){
// drawWall(x + 1, y + 1);
// }
// if ((x === startX && y === startY) || (x === goalX && y === goalY))
// {
// drawRoute(x + 1, y + 1);
// }
// }
// }
// // 壁を描画
// function drawWall(x, y) {
// ctx.fillStyle = wallColor;
// drawRect(x, y);
// }
// function drawRoute(x, y) {
// ctx.fillStyle = routeColor;
// drawRect(x, y);
// }
// function drawRect(x, y){
// ctx.fillRect(
// x * wallSize,
// y * wallSize,
// wallSize,
// wallSize);
// }
})();
</script>
</body>
</html>