源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

JS连连看源码完美注释版(推荐)

  • 时间:2022-11-12 10:15 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:JS连连看源码完美注释版(推荐)
闲来无事,也写一个javascript连连看,注释比较完整,想学的朋友可要看了。 连连看最难的部分应该是路径搜索,即鼠标点的两点之间看有无可通的路径。 看过有人写的递归写法,心里痒痒,就捉摸了一下,发现不用递归的情况下难度也不大。 路径搜索由简到难分析,先分析一条直线上是否可直线连通,再分析一条直线上的两点通过拐两个弯是否可通,最后分析不在一条直线上的情况. 在IE6, IE8, firefox3.0.3下测试过.
[u]复制代码[/u] 代码如下:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>JS连连看源码完美注释版</title> </head> <style>  table{   border-collapse: collapse;  }  td{   border: solid #ccc 1px;   height: 36px;   width: 36px;   cursor: pointer;  }  td img{    height: 30px;    width: 30px;    border: solid #fff 3px;    /*    filter: alpha(opacity=80);    -moz-opacity: 0.8;    opacity: 0.8;    */  } </style> <script> //以下部分为路径搜索算法部分,与表现层无关 //全局变量 var X = 16;//总行数 var Y = 14;//总列数 var types = 15;//图形种类 //布局矩阵 //为了算法方便,矩阵的第一行,第一列,最后一行,最后一列都标注为0,天然通路。 var arr = new Array(Y); var tbl;//显示布局的table元素 var p1 = null;//搜索路径用的第1个点的坐标 var p2 = null;//搜索路径用的第2个点的坐标 var e1 = null;//第1个点对应的元素 var e2 = null;//第2个点对应的元素 //路径搜索,给出两个点,搜索出通路 //通路用可连通的点表示 function getPath(p1, p2){  //开始搜索前对p1,p2排序,使p2尽可能的在p1的右下方。  //这样做可以简化算法  if(p1.x>p2.x){   var t = p1;   p1 = p2;   p2 = t;   }  else if(p1.x==p2.x){   if(p1.y>p2.y){    var t = p1;    p1 = p2;    p2 = t;    }  }  //通过分析连连看中两点之间的位置关系,逐步由简到难分析每一种类型  //第一种类型, 两点是否在一条直线上,而且两点之间可直线连通  if((onlineY(p1, p2)||onlineX(p1, p2)) && hasLine(p1, p2)){   status = 'type 1';   return [p1,p2];  }  //第二种类型, 如果两点中任何一个点被全包围,则不通。  if( !isEmpty({x:p1.x, y:p1.y+1}) && !isEmpty({x:p1.x, y:p1.y-1}) && !isEmpty({x:p1.x-1, y:p1.y}) && !isEmpty({x:p1.x+1, y:p1.y}) ){   status = 'type 2';   return null;  }  if( !isEmpty({x:p2.x, y:p2.y+1}) && !isEmpty({x:p2.x, y:p2.y-1}) && !isEmpty({x:p2.x-1, y:p2.y}) && !isEmpty({x:p2.x+1, y:p2.y}) ){   status = 'type 2';   return null;  }  //第三种类型, 两点在一条直线上,但是不能直线连接  var pt0, pt1, pt2, pt3;  //如果都在x轴,则自左至右扫描可能的路径,  //每次构造4个顶点pt0, pt1, pt2, pt3,然后看他们两两之间是否连通  if(onlineX(p1, p2)){   for(var i=0; i<Y; i++){    if(i==p1.y){     continue;    }    pt0 = p1;    pt1 = {x: p1.x, y: i};    pt2 = {x: p2.x, y: i};    pt3 = p2;    //如果顶点不为空,则该路不通。    if(!isEmpty(pt1) || !isEmpty(pt2)){     continue;    }    if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){     status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')';     return [pt0, pt1, pt2, pt3];    }   }  }  //如果都在y轴,则自上至下扫描可能的路径,  //每次构造4个顶点pt0, pt1, pt2, pt3,然后看他们两两之间是否连通  if(onlineY(p1, p2)){   for(var j=0; j<X; j++){    if(j==p1.x){     continue;     }    pt0 = p1;    pt1 = {x:j, y:p1.y};    pt2 = {x:j, y:p2.y};    pt3 = p2;    //如果顶点不为空,则该路不通。    if(!isEmpty(pt1) || !isEmpty(pt2)){     continue;    }    if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){     status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')';     return [pt0, pt1, pt2, pt3];    }   }  }  //第四种类型, 两点不在一条直线上。  //先纵向扫描可能的路径  //同样,每次构造4个顶点,看是否可通  for(var k=0; k<Y; k++){    pt0 = p1;    pt1 = {x:p1.x, y:k};    pt2 = {x:p2.x, y:k};    pt3 = p2;    status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')';    //特殊情况,如果pt0和pt1重合    if(equal(pt0,pt1)){     //如果pt2不为空,则此路不通     if(!isEmpty(pt2)){      continue;     }     if( hasLine(pt1, pt2) && hasLine(pt2, pt3) ){      return [pt1, pt2, pt3];     }     else{      continue;     }    }    //特殊情况,如果pt2和pt3重合    else if(equal(pt2,pt3)){     //如果pt1不为空,则此路不通     if(!isEmpty(pt1)){      continue;     }     if( hasLine(pt0, pt1) && hasLine(pt1, pt2) ){      return [pt0, pt1, pt2];     }     else{      continue;     }    }    //如果pt1, pt2都不为空,则不通    if(!isEmpty(pt1) || !isEmpty(pt2)){     continue;    }    if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){     return [pt0, pt1, pt2, pt3];    }  }  //横向扫描可能的路径  for(var k=0; k<X; k++){    pt0 = p1;    pt1 = {x:k, y:p1.y};    pt2 = {x:k, y:p2.y};    pt3 = p2;    status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')';    if(equal(pt0,pt1)){     if(!isEmpty(pt2)){      continue;     }     if( hasLine(pt1, pt2) && hasLine(pt2, pt3) ){      return [pt1, pt2, pt3];     }    }    if(equal(pt2,pt3)){     if(!isEmpty(pt1)){      continue;     }     if( hasLine(pt0, pt1) && hasLine(pt1, pt2) ){      return [pt0, pt1, pt2];     }    }    if(!isEmpty(pt1) || !isEmpty(pt2)){     continue;    }    if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){     return [pt0, pt1, pt2, pt3];    }  }  //status='type4';  return null;  /********** end type 4 **************/ } function equal(p1, p2){  return ((p1.x==p2.x)&&(p1.y==p2.y)); } function onlineX(p1, p2){  return p1.y==p2.y; } function onlineY(p1, p2){  return p1.x==p2.x;  } function isEmpty(p){  return (arr[p.y][p.x]==0);  } function hasLine(p1, p2){  if(p1.x==p2.x&&p1.y==p2.y){   return true;   }  if(onlineY(p1, p2)){   var i = p1.y>p2.y?p2.y:p1.y;   i = i+1;   var max = p1.y>p2.y?p1.y:p2.y;   for(; i<max; i++){    var p = {x: p1.x, y: i};    if(!isEmpty(p)){     break    }   }   if(i==max){    return true;   }   return false;  }  else if(onlineX(p1, p2)){   var j = p1.x>p2.x?p2.x:p1.x;   j = j+1;   var max = p1.x>p2.x?p1.x:p2.x;   for(; j<max; j++){    var p = {x: j, y: p1.y};    if(!isEmpty(p)){     break    }   }   if(j==max){    return true;   }   return false;  } } //以下部分为表现层部分,包括绘图, 初始化矩阵, 绑定鼠标事件... function $(id){return document.getElementById(id)} var t1, t2;//测试用 //图片基路径 var IMG_PATH = 'http://www.1sucai.cn'; //初始化 function init(){  //构造图片库  var imgs = new Array(30);  for(var i=1; i<=30; i++){   imgs[i] = 'r_' + i + '.gif';  }  tbl = $('tbl');  //构造table  for(var row=0;row<Y-2;row++){   var tr=tbl.insertRow(-1);   for(var col=0;col<X-2;col++) {    var td=tr.insertCell(-1);   }  }  //构造矩阵  for(var i=0; i<Y; i++){   arr[i] = new Array(X);   for(var j=0; j<X; j++){    arr[i][j] = 0;   }  }  var total = (X-2)*(Y-2);  var tmp = new Array(total);//产生随机位置用  for(var i=0; i<total; i++){   tmp[i] = 0;  }  for(var i=0; i<total; i++){   if(tmp[i]==0){    var t = Math.floor(Math.random()*types) + 1;    tmp[i] = t;    while(true){     var c = Math.floor(Math.random()*(total-i)) + i;     if(tmp[c]==0){      tmp[c] = t;      break;     }    }   }  }  var c = 0;  for(var i=1; i<Y-1; i++){   for(var j=1; j<X-1; j++){    arr[i][j] = tmp[c++];    tbl.rows[i-1].cells[j-1].innerHTML = '<img src="' + IMG_PATH + imgs[arr[i][j]] + '" />';   }   }  //绑定鼠标事件   var img1, img2;  document.body.onclick = function(e){   var el = document.all?event.srcElement:e.target;   if(el.parentNode.tagName!='TD'){    return;   }   if(!img1){    img1 = el;   }   else{    img2 = el;   }   el.style.border = 'solid #3399FF 3px';   el = el.parentNode;   if(el.innerHTML==''){    p1 = p2 = e1 = e2 = null;   }   var r = el.parentNode.rowIndex +1;   var c = el.cellIndex +1;   if(p1==null){    //el.childNodes[0].style.border = 'solid #ccc 3px';    p1 = {x:c, y:r};    e1 = el;   }   else{    p2 = {x:c, y:r};    e2 = el;    if(!equal(p1, p2)&&e1.innerHTML==el.innerHTML){     var path = getPath(p1, p2);     if(path!=null){      e1.innerHTML = e2.innerHTML = '';      arr[p1.y][p1.x] = arr[p2.y][p2.x] = 0;     }    }    if(t1){t1.style.backgroundColor = '';}    t1 = e1;    if(t2){t2.style.backgroundColor = '';}    t2 = e2;    img1.style.border = 'solid #fff 3px';    img2.style.border = 'solid #fff 3px';    p1 = p2 = e1 = e2 = img1 = img2 = null;    t1.style.backgroundColor = t2.style.backgroundColor = 'lightpink';   }  } } </script> <body onload="init();">  js连连看完美注释版<br />  <table id="tbl" cellspacing="0" cellpadding="0" border="1">  </table> </body> </html>
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部