连连看连接算法Javascript版

继连连看连接算法Python版后,我将该算法移植到了Javascript上,为在浏览器版连连看做准备。

功能及使用方法参照另外一篇:连连看连接算法Python版。

值得一提的是由于Javascript语言没有Java中Map那样的<k,v>对应的数据结构,所以在实现这样的结构时就要另辟蹊径了,通用的方法应该是构建一个相关的类,并提供相应的方法操作。不过我发现一个简易的方法,适合将字符串(String)与任意类型数据相关联。具体方法是使用Javascript中类的属性可以使用数组存取方式(L[index]来访问),可以使用属性名的字符串访问属性,还可以使用delete删除属性,当需要新建或修改一个对应关系的时候,就直接使用O[String]=Object新建或修改指定属性保存对应对象,当删除对应关系时使用delete O[String]即可,当这样就可以实现Map的功能了。

 

下面代码没有注释,注释可参见连连看连接算法Python版。

 

  1. function _index(_value){
  2.     for(var v in this){
  3.         if(this[v] == _value){
  4.             return new Number(v)
  5.         }
  6.     }
  7.     return -1;
  8. }
  9. function _remove(_value){
  10.     var _index = this.index(_value);
  11.     this.splice(_index,1);
  12. }
  13. function _insert(_position,_value){
  14.     this.splice(_position,0,_value);
  15. }
  16. Array.prototype.index = _index;
  17. Array.prototype.insert = _insert;
  18. Array.prototype.remove = _remove;
  19. function Point(_x,_y,_value){
  20.     this.x = _x;
  21.     this.y = _y;
  22.     this.value = _value;
  23.     this.directs = null;
  24.     this.changed = 0;
  25. }
  26. function _createDirect(_pre,_target){
  27.     this.directs = new Array();
  28.     var stx = _target.x - this.x;
  29.     var sty = _target.y - this.y;
  30.     if(stx >= 0){
  31.         this.directs.push("right");
  32.         this.directs.push("left");
  33.     }
  34.     else{
  35.         this.directs.push("left");
  36.         this.directs.push("right");
  37.     }
  38.     if(sty >= 0){
  39.         this.directs.insert(1,"up");
  40.         this.directs.push("down");
  41.     }
  42.     else{
  43.         this.directs.insert(1,"down");
  44.         this.directs.push("up");
  45.     }
  46.     if (_pre == null){
  47.         return ;
  48.     }
  49.     var spx = _pre.x - this.x;
  50.     var spy = _pre.y - this.y;
  51.     if (spx == 0){
  52.         if (spy == 1){
  53.             this.directs.remove("up");
  54.         }
  55.         else{
  56.             this.directs.remove("down");
  57.         }
  58.     }
  59.     else{
  60.         if (spx == 1){
  61.             this.directs.remove("right");
  62.         }
  63.         else{
  64.             this.directs.remove("left");
  65.         }
  66.     }
  67. }
  68. function _forward(_pre,_target){
  69.     if(this.directs == null){
  70.         this.createDirect(_pre,_target);
  71.     }
  72.     if(this.directs.length == 0){
  73.         return null;
  74.     }
  75.     var direct = null;
  76.     var tmpDirect = null;
  77.     var x = null;
  78.     var y = null;
  79.     var p = null;
  80.     while(true){
  81.         if(this.directs.length == 0){
  82.             break;
  83.         }
  84.         tmpDirect = this.directs.shift();
  85.         switch(tmpDirect){
  86.             case "up":
  87.                 x = this.x;
  88.                 y = this.y + 1;
  89.                 break;
  90.             case "down":
  91.                 x = this.x;
  92.                 y = this.y - 1;
  93.                 break;
  94.             case "left":
  95.                 x = this.x - 1;
  96.                 y = this.y;
  97.                 break;
  98.             case "right":
  99.                 x = this.x + 1;
  100.                 y = this.y;
  101.                 break;
  102.             default:
  103.                 throw new Error("error direct");
  104.                 break;
  105.         }
  106.         p = points[x][y];
  107.         if(p.value > 0 && p != _target){
  108.             continue;
  109.         }
  110.         else{
  111.             direct = tmpDirect;
  112.             if(_pre == null){
  113.                 this.changed = 1;
  114.             }
  115.             else{
  116.                 if((_pre.x - this.x) == 0 && (p.x - this.x) == 0){
  117.                     this.changed = 0;
  118.                 }
  119.                 else{
  120.                     if((_pre.y - this.y) == 0 && (p.y - this.y) == 0){
  121.                         this.changed = 0;
  122.                     }
  123.                     else{
  124.                         this.changed = 1;
  125.                     }
  126.                 }
  127.             }
  128.             break;
  129.         }
  130.     }
  131.     return direct;
  132. }
  133. function _equals(_point){
  134.     if (_point == null){
  135.         return false;
  136.     }
  137.     if (this.x == _point.x && this.y == _point.y){
  138.         return true;
  139.     }
  140.     else{
  141.         return false;
  142.     }
  143. }
  144. Point.prototype.createDirect = _createDirect;
  145. Point.prototype.forward = _forward;
  146. Point.prototype.equals = _equals;
  147. var points = new Array();
  148. var valueStack = new Array();
  149. function createPoints(w,h){
  150.     var temp;
  151.     var tempValue;
  152.     pointStack(w,h);
  153.     for(var _x = 0 ; _x < w ; _x++){
  154.         temp = new Array();
  155.         for(var _y = 0 ; _y < h ; _y++){
  156.             if(_x == 0 || _x == (w-1) || _y == 0 || _y == (h-1)){
  157.                 tempValue = 9;
  158.             }
  159.             else{
  160.                 if(_x == 1 || _x == (w-2) || _y == 1 || _y == (h-2)){
  161.                     tempValue = 0;
  162.                 }
  163.                 else{
  164.                     tempValue = valueStack.pop();
  165.                 }
  166.             }
  167.             temp[_y] = new Point(_x,_y,tempValue);
  168.         }
  169.         points[_x] = temp;
  170.     }
  171. }
  172. function pointStack(w,h){
  173.     var size = (w*h-(w*4+h*4-16))/2;
  174.     var pointValue;
  175.     for(var i = 0 ; i < size ; i++){
  176.         while(true){
  177.             pointValue = Math.floor(Math.random()*9);
  178.             if(pointValue != 0){
  179.                 break;
  180.             }
  181.         }
  182.         valueStack.insert(Math.floor(Math.random()*valueStack.length),pointValue);
  183.         valueStack.insert(Math.floor(Math.random()*valueStack.length),pointValue);
  184.     }
  185. }
  186. function linkPoints(_source,_target){
  187.     var path = new Array();
  188.     var fail = new Object();
  189.     var change = 0;
  190.     var _current = _source;
  191.     var direct = null;
  192.     var _x,_y;
  193.     while(true){
  194.         //alert("current--"+pointStr(_current)+"change:"+change);
  195.         if(_current == _target && change < 4){
  196.             for(var p in path){
  197.                 path[p].directs = null;
  198.             }
  199.             return path;
  200.         }
  201.         if(change == 4){
  202.             _current.directs = null;
  203.             fail[(_current.x+"_"+_current.y)] = change;
  204.             _current = path.pop();
  205.             change = change - _current.changed;
  206.             continue;
  207.         }
  208.         if(_current == _source){
  209.             direct = _current.forward(null,_target);
  210.         }
  211.         else{
  212.             direct = _current.forward(path[path.length-1],_target);
  213.         }
  214.         if(direct != null){
  215.             if(direct == "up"){
  216.                 _x = _current.x;
  217.                 _y = _current.y + 1;
  218.             }
  219.             if(direct == "down"){
  220.                 _x = _current.x;
  221.                 _y = _current.y - 1;
  222.             }
  223.             if(direct == "left"){
  224.                 _x = _current.x - 1;
  225.                 _y = _current.y ;
  226.             }
  227.             if(direct == "right"){
  228.                 _x = _current.x + 1;
  229.                 _y = _current.y;
  230.             }
  231.             if(fail[(_x+"_"+_y)] != null){
  232.                 if (change >= fail[(_x+"_"+_y)]){
  233.                     continue;
  234.                 }
  235.                 else{
  236.                     delete fail[(_x+"_"+_y)];
  237.                 }
  238.             }
  239.             change = change + _current.changed;
  240.             path.push(_current);
  241.             _current = points[_x][_y];
  242.         }
  243.         else{
  244.             if(_current == _source){
  245.                 _source.directs = null;
  246.                 return false;
  247.             }
  248.             else{
  249.                 _current.directs = null;
  250.                 fail[(_current.x+"_"+_current.y)] = change;
  251.                 _current = path.pop();
  252.                 change = change - _current.changed;
  253.             }
  254.         }
  255.     }
  256. }
  257. /*function pointStr(p){
  258.     return " x:"+p.x+" y:"+p.y+" value:"+p.value;
  259. }
  260. */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值