<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<style type="text/css">
body,div,h2,ul,li{margin:0;padding:0;}
body{font:12px/1.5 Arail;}
.box{width:860px;margin:10px auto;background:#eee;border:1px solid #b8b8b8;overflow:hidden}
.title{height:30px;line-height:30px;font-size:14px;padding:0 15px 0 35px;border-bottom:1px solid #b8b8b8;background:#fafafa url(http://js.alixixi.com/img/mm/ico.gif) 5px 50% no-repeat;}
.title span{float:left;}
.title a{float:right;color:#06f;outline:none;}
.title a:hover{color:red;}
.box .tool {
width:300px;
float:left;
}
.box .content {
width:480px;
margin-left:310px;
}
.tool div {
margin:10px auto;
height:40px;
text-align:center;
}
.content .tag {
height:30px;
line-height:30px;
}
.content td {
width:10px;
height:10px;
font-size:xx-large;
line-height:10px;
border:1px solid #c3c3c3;
background:#fff;
text-align:center;
}
</style>
<script type="text/javascript">
//一些常量
var matrix = [
[0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0]
];
var M = 15, N = 20;
var dir = [[-1, 0], [0, -1], [1, 0], [0, 1]];
var starti = 0, startj = 0;//开始点坐标
var endi = M - 1, endj = N - 1;//结束点坐标
function H(i,j){//估价函数
return Math.abs(endi - i) + Math.abs(endj - j);
}
var BLACK="#000";
var BLUE="#06f";
var WHITE="#fff";
</script>
<script type="text/javascript">
//一些公共函数
//获取ID
var $ = function (id) { return typeof id === "string" ? document.getElementById(id) : id };
//获取tagName
var $$ = function (tagName, oParent) { return (oParent || document).getElementsByTagName(tagName) };
//获取class
var $$$ = function (sClass, oParent) {
var aClass = [],
i = 0,
reClass = new RegExp("(\\s|^)" + sClass + "($|\\s)"),
aElement = $$("*", oParent);
for (i = 0; i < aElement.length; i++) reClass.test(aElement[i].className) && aClass.push(aElement[i]);
return aClass
};
</script>
<script type="text/javascript">
//创建数独对象
var Maze = function () { this.initialize.apply(this, arguments) };
Maze.prototype = {
initMatrix: function (matrix,Map) {
for (var i = 0; i < M; i++) {
matrix[i] = new Array(N);
for (var j = 0; j < N; j++) {
matrix[i][j] = Map[i][j];
}
}
},
renewMatrix: function (matrix,Map) {
for (var i = 0; i < M; i++) {
for (var j = 0; j < N; j++) {
matrix[i][j] = Map[i][j];
}
}
},
initialize: function (obj ,Map) {
var oThis = this;
this.Parent = $(obj);//获得table对象
this.Table = $$("table", this.Parent)[0];
this.tag = $$$("tag", this.Parent)[0];
this.ButtonA = $$$("answer", this.Parent)[0];
this.ButtonB = $$$("restore", this.Parent)[0];
this.ButtonC = $$$("show", this.Parent)[0];
this.ButtonD = $$$("diy", this.Parent)[0];
this.matrix = new Array(M);//存放数独矩阵
this.diyMatrix = new Array(M);//diy迷宫
this.Td = [];//table中的所有td列矩阵
this.maxDeep = 0;
this.stime = null;//计时
this.initMatrix(this.matrix, Map);
this.initMatrix(this.diyMatrix, Map);
this.dom = document.documentElement || document.body;
this.ButtonA.onclick = function () {
oThis.tag.innerText = "运行";
oThis.initOperation();
oThis.show();
oThis.answer();
oThis.print();
}
this.ButtonB.onclick = function () {
oThis.tag.innerText = "还原迷宫";
oThis.initOperation();
oThis.show();
}
this.ButtonC.onclick = function () {
oThis.tag.innerText = "显示答案";
oThis.initOperation();
oThis.answer();
oThis.show();
}
this.ButtonD.onclick = function () {
oThis.tag.innerText = "DIY迷宫";
oThis.initOperation();
oThis.show();
oThis.diy();
}
this.create(Map);
},
initOperation: function () {//初始化操作
var oThis = this;
oThis.renewMatrix(oThis.matrix, oThis.diyMatrix);
clearInterval(oThis.stime);
},
create: function (Map) {
var oThis = this;
var aFrag = document.createDocumentFragment();
var i = 0, j = 0;
for (i = 0; i < M; i++) {
var tr = document.createElement("tr");
oThis.Td.push([]);
for (j = 0; j < N; j++) {
var td = document.createElement("td");
if (Map[i][j] == 1) td.style.backgroundColor = BLACK;
oThis.Td[i].push(td);
tr.appendChild(td);
}
aFrag.appendChild(tr);
}
this.Table.appendChild(aFrag);
},
print: function () {
var oThis = this;
var curi = starti, curj = startj;
var preDir = -3;//访问的上一个方向
this.stime = setInterval(function () {
oThis.Td[curi][curj].style.backgroundColor = BLUE;
if (curi == endi && curj == endj) clearTimeout(oThis.stime);
for (var i = 0; i < 4; i++) {
var ni = curi + dir[i][0];
var nj = curj + dir[i][1];
if (ni >= 0 && ni < M && nj >= 0 && nj < N && Math.abs(i - preDir) != 2 && oThis.matrix[ni][nj] == 2) {
curi = ni, curj = nj;
preDir = i;
break;
}
}
}, 100);
},
show: function () {
for (var i = 0; i < M; i++)
for (var j = 0; j < N; j++) {
if (this.matrix[i][j] == 2)
this.Td[i][j].style.backgroundColor = BLUE;
else if (this.matrix[i][j] == 1)
this.Td[i][j].style.backgroundColor = BLACK;
else this.Td[i][j].style.backgroundColor = WHITE;
}
},
find:function(obj){
for (var i = 0; i < M; i++)
for (var j = 0; j < N; j++)
if (this.Td[i][j] == obj)
return { i: i, j: j };
},
diy: function () {
var oThis=this;
for (var i = 0; i < M; i++) {
for (var j = 0; j < N; j++) {
this.Td[i][j].onclick = function () {
var pos = oThis.find(this);
var i=pos.i,j=pos.j;
if (oThis.diyMatrix[i][j] == 0) {
oThis.diyMatrix[i][j] = 1;
this.style.backgroundColor = BLACK;
} else {
oThis.diyMatrix[i][j] = 0;
this.style.backgroundColor = WHITE;
}
}
}
}
},
answer: function () {
this.IDAstar();
//this.show();
},
dfs:function(curi, curj, depth) {
if (depth + H(curi, curj) > this.maxDeep)//IDA*估价剪枝
return false;
if (curi == endi && curj == endj)
return true;
for (var i = 0; i < 4; i++) {
var ni = curi + dir[i][0];
var nj = curj + dir[i][1];
if (ni >= 0 && ni < M && nj >= 0 && nj < N && this.matrix[ni][nj] == 0) {
this.matrix[ni][nj] = 2;
if (this.dfs(ni, nj, depth + 1) == true) return true;
this.matrix[ni][nj] = 0;
}
}
return false;
},
IDAstar:function(){
this.maxDeep = H(starti, startj);
this.matrix[starti][startj]=2;
while (this.dfs(starti, startj, 0) == false) {
if (this.maxDeep > 100) break;
this.maxDeep = this.maxDeep + 1;
}
}
};
window.onload = function () {
var Box = $$$("box");
//创建实例
new Maze(Box[0], matrix);
};
</script>
</head>
<body>
<div class="box">
<h2 class="title"><span>迷宫模拟</span></h2>
<div class="tool">
<div><button class="answer">运行</button></div>
<div><button class="restore">还原迷宫</button></div>
<div><button class="show">显示答案</button></div>
<div><button class="diy">DIY迷宫</button></div>
</div>
<div class="content">
<div class="tag">默认迷宫</div>
<table class="sudoku">
</table>
</div>
</div>
</body>
</html>
|