学深搜的时候想起来了这个游戏,于是就想用深搜还原一下,练练手。不要看这个游戏这么简单,要考虑的东西还不少呢,写游戏真的很麻烦。
游戏链接:https://www.windfamily.cn/module/games/maze.html
1. 首先是HTML:
地下迷宫
2. 然后是CSS:
.maze{
display: inline-block;
width:300px;
height: 260px;
position: absolute;;
left: 50%;
top:10px;
margin-left: -150px;
border: 1px solid black;
}
#tip{
position: absolute;
z-index: 2;
background-color: red;
width: 100%;
top:30%;
color: #fefefe;
padding-top:3px;
padding-bottom: 3px;
text-align: center;
font-size: 16px;
}
.head{
display: inline-block;
width: 150px;
position: absolute;
left: 50%;
margin-left: -75px;
margin-top: 5px;
}
.head>a{
margin-left: 10px;
}
.table{
position: absolute;
top:50px;
}
.block1{
display: inline-block;
position: relative;
width: 30px;
height: 20px;
line-height: 20px;
text-align: center;
}
.bottom{
position: absolute;
left: 50%;
bottom: 10px;
margin-left: -55px;
}
.bottom>a{
margin-left: 10px;
padding-right: 20px;
}
3. 最后是精华部分,JS代码:
var rule = document.getElementById('rule'); //获取按钮
var reset = document.getElementById('reset');
var start = document.getElementById('start');
var table = new Array(); //定义数组,记录迷宫
for(var i=0;i<56;i++){ //给每一个元素编号
var block = document.getElementsByClassName('block1')[i];
block.style.cursor='pointer';
block.id=i;
}
//初始化迷宫函数1-
var origin = function(){
var tip=document.getElementById('tip');
if(tip.innerHTML!='走的时候不妨体验一下其它路线,不要为了找出口而走'){
tip.style.visibility='hidden';
}
start.innerHTML='开始';
for(var i=0;i<56;i++){
var block = document.getElementsByClassName('block1')[i];
block.style.color='black';
block.style.cursor='pointer';
block.innerHTML = 'X';
if (i==52) {
block.style.color='black';
block.style.cursor='pointer';
}
}
}
origin();
//初始化迷宫函数-1
//建立迷宫函数2-
var newMaze = function(){
var tip=document.getElementById('tip');
tip.style.visibility='hidden';
start.innerHTML='重置';
for(var i=0;i<56;i++){ //初始化迷宫
var block = document.getElementsByClassName('block1')[i];
block.innerHTML = 'X';
block.style.color='black';
if (i==52) {
block.innerHTML='入';
block.style.color='blue';
block.style.cursor='pointer';
console.log('Powered By http://www.windfamily.cn');
}
}
for(var i=0;i<7;i++){ //初始化数组
table[i] = new Array();
for(var j=0;j<8;j++){
table[i][j]=0;
}
}
var startx=6;
var starty=4;
var endx; //生成随机终点
var endy;
var whichside;
var num=Math.floor(Math.random()*100);
endx=num%7; //终点随机
endy=num%8;
if(endx==6 && endy==4){
endx=endx-1;
}
/*whichside = num%3+1; //终点只在边缘
if(whichside==1){
endx=num%7;
endy=0;
}else if(whichside==2){
endx=0;
endy=num%8;
}else{
endx=num%7;
endy=7;
}*/
/*endx=0; //终点只在顶部
endy=num%8;*/
var dir = [[-1,0],[0,1],[0,-1]]; //搜索方向,不用考虑下,因为往上左右一定能找出一条通路
var vis = new Array(); //记录走过的位置
for(var i=0;i<7;i++){ //初始化数组
vis[i] = new Array();
for(var j=0;j<8;j++){
vis[i][j]=0;
}
}
//搜索,生成通往终点唯一方向2.1-
var flag=0;
function dfs(x,y) {
vis[x][y]=1;
if(x==endx && y==endy){
flag=1;
return 0;
}
var dirorder = [0,1,2];
for(var i=0;i<3;i++){
var num=Math.floor(Math.random()*100); //生成随机方向,不用的话生成的是一条笔直的折线
num=num%3;
var t;
t=dirorder[num];
if (i<2) {
dirorder[num]=dirorder[2];
dirorder[2]=t;
}
}
for(var i=0;i<3;i++){
if(flag==1) break;
var j = dirorder[i]; //使用随机方向
var newx=x+dir[j][0];
var newy=y+dir[j][1];
if(newx>=0 && newx<7 && newy>=0 && newy<8 && vis[newx][newy]==0){
table[newx][newy]=1;
dfs(newx,newy);
if(flag==0){ //flag为0说明这条路不可行,回退
table[newx][newy]=0;
}
}
}
}
dfs(startx,starty);
table[endx][endy]=2;
table[startx][starty]=3;
//搜索,生成通往终点唯一方向-2.1
//生成干扰路线2.2-
var dir = [[1,0],[-1,0],[0,1],[0,-1]];
var flag=1;
var endx2;
var endy2;
function dfs2(x2,y2){
if(x2==endx2 && y2==endy2){
flag=0;
return 0;
}
table[x2][y2]=1;
var dirorder = [0,1,2,3];
for(var i=0;i<3;i++){
var num=Math.floor(Math.random()*100); //生成随机方向
num=num%4;
var t;
t=dirorder[num];
dirorder[num]=dirorder[3-num];
dirorder[3-num]=t;
}
for(var i=0;i<4;i++){
if(flag==0) break;
var newx=x2+dir[dirorder[i]][0];
var newy=y2+dir[dirorder[i]][1];
if(table[newx][newy]<=1){
dfs(newx,newy);
}
}
}
for(var x=0;x<7;x++){
for(var y=0;y<8;y++){
var num=Math.floor(Math.random()*100);
num=num%4;
var num3=Math.floor(Math.random()*100);
endx2=num3%7;
endy2=num3%8;
if(table[endx2][endy2]<=1 && num>=2 && table[x][y]<=1) {
flag=0;
dfs2(x,y);
table[startx][starty]=3;
}
}
}
table[startx][starty]=3;
//生成干扰路线-2.2
/*var blocknum; //用于测试,显示迷宫
for(var i=0;i<7;i++){
for(var j=0;j<8;j++){
blocknum=i*8+j;
var block = document.getElementsByClassName('block1')[blocknum];
if(table[i][j]==1){
block.innerHTML='Y';
}
if(i==endx && j==endy){
block.innerHTML='出';
}
}
}*/
}
//建立迷宫函数-2
//按键功能绑定相关函数3-(函数的思想超级重要,这么做少写了很多重复的东西)
var showblock = function(x,y,id){
var block = document.getElementsByClassName('block1')[id];
if(table[x][y]==0){
block.innerHTML='石';
}else if(table[x][y]==1){
block.style.color='blue';
block.innerHTML='X';
}else if(table[x][y]==2){
block.innerHTML='出';
block.style.color='blue';
}else if(table[x][y]==3){
block.innerHTML='入'
block.style.color='blue';
}
}
var hiddenblock = function(x,y,id){
var block = document.getElementsByClassName('block1')[id];
block.innerHTML='X';
block.style.color='black';
}
var now = function(){
var block = document.getElementsByClassName('block1')[this.id];
var x=Math.floor(this.id/8);
var y=(this.id)%8;
var tip=document.getElementById('tip');
if(block.innerHTML!='石' && block.style.color=='blue'){
block.innerHTML='我';
if(table[x][y]==2){
tip.innerHTML='YOU WIN.';
tip.style.visibility='visible';
}
if(x-1>=0) showblock(x-1,y,Number(this.id)-8);
if(x+1<7) showblock(x+1,y,Number(this.id)+8);
if(y-1>=0) showblock(x, y-1,Number(this.id)-1);
if(y+1<8) showblock(x, y+1,Number(this.id)+1);
if(x+1<7 && y-1>=0) hiddenblock(x+1,y-1,Number(this.id)+7);
if(x+1<7 && y+1<8) hiddenblock(x+1,y+1,Number(this.id)+9);
if(x-1>=0 && y-1>=0) hiddenblock(x-1,y-1,Number(this.id)-9);
if(x-1>=0 && y+1<8) hiddenblock(x-1,y+1,Number(this.id)-7);
if(x-2>=0) hiddenblock(x-2,y,Number(this.id)-16);
if(x+2<7) hiddenblock(x+2,y,Number(this.id)+16);
if(y-2>=0) hiddenblock(x,y-2,Number(this.id)-2);
if(y+2<8) hiddenblock(x,y+2,Number(this.id)+2)
}
}
//按键功能绑定相关函数-3
//按键绑定函数操作4-
for(var i=0;i<56;i++){ //给每一个元素绑定点击事件
var block = document.getElementsByClassName('block1')[i];
block.onclick=now;
}
start.onclick=newMaze;
reset.onclick=origin;
rule.onclick=function(){
alert('1. 玩家进入迷宫后,"你"的周围会显示"石"、"X"、"入"、"出"。\n2. "石"代表障碍物,不可走,"X"代表可进行的路线,"入"代表迷宫入口,"出"代表迷宫出口 。\n3. 迷宫大小为宽度为8,高度为7,玩家最多可看到的高度为5,即上下左右和目前位置。');
}
//按键绑定函数操作-4
我生成迷宫的方案是先用深搜搜出一可以走到终点条路线,然后再随机生成起点和终点,再搜从起点到终点的路线。如果有更好的方案,欢迎留言啊。