欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS連連看源碼完美注釋版(推薦)

 更新時間:2013年12月09日 09:18:56   作者:  
連連看最難的部分應(yīng)該是路徑搜索,即鼠標(biāo)點的兩點之間看有無可通的路徑。 看過有人寫的遞歸寫法,心里癢癢,就捉摸了一下,發(fā)現(xiàn)不用遞歸的情況下難度也不大

閑來無事,也寫一個javascript連連看,注釋比較完整,想學(xué)的朋友可要看了。

連連看最難的部分應(yīng)該是路徑搜索,即鼠標(biāo)點的兩點之間看有無可通的路徑。 看過有人寫的遞歸寫法,心里癢癢,就捉摸了一下,發(fā)現(xiàn)不用遞歸的情況下難度也不大。

路徑搜索由簡到難分析,先分析一條直線上是否可直線連通,再分析一條直線上的兩點通過拐兩個彎是否可通,最后分析不在一條直線上的情況.

在IE6, IE8, firefox3.0.3下測試過.

復(fù)制代碼 代碼如下:

<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>
//以下部分為路徑搜索算法部分,與表現(xiàn)層無關(guān)

//全局變量
var X = 16;//總行數(shù)
var Y = 14;//總列數(shù)
var types = 15;//圖形種類

//布局矩陣
//為了算法方便,矩陣的第一行,第一列,最后一行,最后一列都標(biāo)注為0,天然通路。
var arr = new Array(Y);
var tbl;//顯示布局的table元素

var p1 = null;//搜索路徑用的第1個點的坐標(biāo)
var p2 = null;//搜索路徑用的第2個點的坐標(biāo)
var e1 = null;//第1個點對應(yīng)的元素
var e2 = null;//第2個點對應(yīng)的元素

//路徑搜索,給出兩個點,搜索出通路
//通路用可連通的點表示
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; 
  }
 }
 //通過分析連連看中兩點之間的位置關(guān)系,逐步由簡到難分析每一種類型
 //第一種類型, 兩點是否在一條直線上,而且兩點之間可直線連通
 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軸,則自左至右掃描可能的路徑,
 //每次構(gòu)造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軸,則自上至下掃描可能的路徑,
 //每次構(gòu)造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];
   }
  }
 }
 //第四種類型, 兩點不在一條直線上。
 //先縱向掃描可能的路徑
 //同樣,每次構(gòu)造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;
 }
}
//以下部分為表現(xiàn)層部分,包括繪圖, 初始化矩陣, 綁定鼠標(biāo)事件...
function $(id){return document.getElementById(id)}

var t1, t2;//測試用
//圖片基路徑
var IMG_PATH = 'http://www.dbjr.com.cn';
//初始化
function init(){
 //構(gòu)造圖片庫
 var imgs = new Array(30);
 for(var i=1; i<=30; i++){
  imgs[i] = 'r_' + i + '.gif';
 }
 tbl = $('tbl');
 //構(gòu)造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);
  }
 }
 //構(gòu)造矩陣
 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);//產(chǎn)生隨機(jī)位置用
 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]] + '" />';
  } 
 }
 //綁定鼠標(biāo)事件
  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>

相關(guān)文章

  • js通過canvas生成圖片縮略圖

    js通過canvas生成圖片縮略圖

    對于生成縮略圖一般做法是通過后端語言php等來生成,但是為了給服務(wù)器減壓,我們或許可以從前端來著手,先生成好不同尺寸的縮略圖,傳給后端,而后端只需要將前端傳過來的圖片進(jìn)行存儲就好了
    2020-10-10
  • 分享Javascript中最常用的55個經(jīng)典小技巧

    分享Javascript中最常用的55個經(jīng)典小技巧

    這篇文章主要介紹了Javascript中最常用的55個經(jīng)典小技巧。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-11-11
  • JSON鍵值對序列化和反序列化解析

    JSON鍵值對序列化和反序列化解析

    這篇文章主要介紹了JSON鍵值對序列化和反序列化知識,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧
    2017-01-01
  • [js高手之路]圖解javascript的原型(prototype)對象,原型鏈實例

    [js高手之路]圖解javascript的原型(prototype)對象,原型鏈實例

    下面小編就為大家?guī)硪黄猍js高手之路]圖解javascript的原型(prototype)對象,原型鏈實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • JS面試之手寫節(jié)流防抖詳解

    JS面試之手寫節(jié)流防抖詳解

    作為一個程序員,代碼實現(xiàn)才是能力體現(xiàn),在大部分面試的時候,我們都會被要求手寫代碼實現(xiàn)一個功能,本文總結(jié)了一下經(jīng)常被面試官問到的節(jié)流和防抖功能的實現(xiàn),分享給有需要的小伙伴
    2023-07-07
  • HTML+JS模擬實現(xiàn)QQ下拉菜單效果

    HTML+JS模擬實現(xiàn)QQ下拉菜單效果

    這篇文章主要為大家詳細(xì)介紹了如何利用HTML+JavaScript模擬實現(xiàn)QQ中的下拉菜單效果。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下
    2022-05-05
  • 如何用javascript控制上傳文件的大小

    如何用javascript控制上傳文件的大小

    如何用javascript控制上傳文件的大小...
    2006-10-10
  • javascript Array.sort() 跨瀏覽器下需要考慮的問題

    javascript Array.sort() 跨瀏覽器下需要考慮的問題

    最近組里項目需要一個簡單的Table排序的功能,這個功能實現(xiàn)起來很簡單,并且網(wǎng)上也有很多現(xiàn)成的代碼,因此任務(wù)很快完成。
    2009-12-12
  • webpack@v4升級踩坑(小結(jié))

    webpack@v4升級踩坑(小結(jié))

    這篇文章主要介紹了webpack@v4升級踩坑(小結(jié)),之前就嘗試了升級,由于部分插件的原因,未能成功,今天就來試一下在我的項目中升級會遇到哪些坑。感興趣的小伙伴們可以參考一下
    2018-10-10
  • javascript 公用拖拽類代碼

    javascript 公用拖拽類代碼

    兼容Event對象等 拖拽類代碼
    2008-12-12

最新評論