返回列表 回复 发帖

连连看算法[zszen式连连算法]070626更新

理论和实践的结合,完美的连连看算法

原理是扫描横排或是纵排是否存在全空行/列  只有存在这种状况 连线的拐点才能达到2个以内

070626最新修改
增加了例子,特效算上不到200行代码
  1. //矩阵
  2. /*
  3. [0,2,1,0]
  4. [0,1,2,0]
  5. [0,1,1,0]
  6. [0,0,1,0]

  7. [0,2,1,0]
  8. [0,1,0,0]
  9. [0,1,1,0]
  10. [0,0,0,2]

  11. [0,2,0,1]
  12. [0,1,0,0]
  13. [1,1,1,2]
  14. [0,1,1,0]
  15. */
  16. //前两个是两个目标点,最后一个是整体最大区域 目标点修改 矩阵也需要修改
  17. //ary = [[0, 2, 1, 0], [0, 1, 2, 0], [0, 1, 1, 0], [0, 0, 1, 0]];
  18. //trace(outPath({i:0, j:1}, {i:1, j:2}, {i:4, j:4}));
  19. //ary = [[0, 2, 1, 0], [0, 1, 0, 0], [0, 1, 1, 0], [0, 0, 0, 2]];
  20. //trace(outPath({i:0, j:1}, {i:3, j:3}, {i:4, j:4}));
  21. ary = [[0, 2, 0, 1], [0, 1, 0, 0], [1, 1, 1, 2], [0, 1, 1, 0]];
  22. trace(outPath({i:0, j:1}, {i:2, j:3}, {i:4, j:4}));
  23. function outPath(now, then, limit) {
  24. var mini = Math.min(now.i, then.i);
  25. var maxi = Math.max(now.i, then.i);
  26. var minj = Math.min(now.j, then.j);
  27. var maxj = Math.max(now.j, then.j);
  28. var limiti = limit.i;
  29. var limitj = limit.j;
  30. var haveLine;
  31. var i = 0;
  32. var j = 0;
  33. ///纵列 当用纵列来扫描 行i就限制在两目标点之间
  34. for (i=0; i<limiti; i++) {
  35.   haveLine = true;
  36.   for (j=minj; j<=maxj; j++) {
  37.    //trace([i, j, ary[j]]);
  38.    if (!(i == now.i && j == now.j) && !(i == then.i && j == then.j)) {
  39.     if (ary[j] == 1) {
  40.      haveLine = false;
  41.      break;
  42.     }
  43.    }
  44.   }
  45.   if (haveLine) {
  46.    var check = unitEmpty({i:i, j:now.j}, {i:now.i, j:now.j}) && unitEmpty({i:i, j:then.j}, {i:then.i, j:then.j});
  47.    if (check) {
  48.     break;
  49.    } else {
  50.     haveLine = false;
  51.    }
  52.   } else {
  53.    haveLine = false;
  54.   }
  55. }
  56. if (haveLine) {
  57.   return haveLine;
  58. } else {
  59.   //行列 当用行列来扫描 列j限制在两个目标点之间
  60.   for (j=0; j<=limitj; j++) {
  61.    haveLine = true;
  62.    for (i=mini; i<=maxi; i++) {
  63.     if (!(i == now.i && j == now.j) && !(i == then.i && j == then.j)) {
  64.      //trace([i, j, ary[j]]);
  65.      if (ary[j] == 1) {
  66.       haveLine = false;
  67.       break;
  68.      }
  69.     }
  70.    }
  71.    if (haveLine) {
  72.     var check = unitEmpty({i:now.i, j:j}, {i:now.i, j:now.j}) && unitEmpty({i:then.i, j:j}, {i:then.i, j:then.j});
  73.     if (check) {
  74.      break;
  75.     } else {
  76.      haveLine = false;
  77.     }
  78.    } else {
  79.     haveLine = false;
  80.    }
  81.   }
  82.   return haveLine;
  83. }
  84. }
  85. function unitEmpty(now, then) {
  86. //取得两目标点是否其间可穿越,必须是同行或是同列
  87. var mini = Math.min(now.i, then.i);
  88. var maxi = Math.max(now.i, then.i);
  89. var minj = Math.min(now.j, then.j);
  90. var maxj = Math.max(now.j, then.j);
  91. //trace([mini, maxi, minj, maxj]);
  92. var haveLine = true;
  93. if (mini == maxi) {
  94.   for (var j = minj+1; j<maxj; j++) {
  95.    if (ary[mini][j] == 1) {
  96.     haveLine = false;
  97.     break;
  98.    }
  99.   }
  100.   return haveLine;
  101. } else if (minj == maxj) {
  102.   for (var i = mini+1; i<maxi; i++) {
  103.    if (ary[minj] == 1) {
  104.     haveLine = false;
  105.     break;
  106.    }
  107.   }
  108.   return haveLine;
  109. }
  110. return false;
  111. }
复制代码
[ 本帖最后由 zszen 于 2007-9-2 17:39 编辑 ]

先纵向计算

01.gif

纵向有贯通点,进一步横向检测

02.gif

如果纵向无法联通,横向计算

03.gif

横向有连通,进一步纵向检测

04.gif

核心算法.swf (622 Bytes)

核心算法.zip (8.56 KB)

my link up.swf (5.41 KB)

linkup简单实例[核心算法得到]

lp.zip (21.63 KB)

linkup实例源文件

http://zszen.host6.heyhost.cn/wp
没看出什么时候是false..
喜帖街my blog
沉了 沉了 这么好的算法 没人顶真可惜
http://zszen.host6.heyhost.cn/wp
又没原文件,又没图释,又没注释,啥都没有,懒的看
啊~!好算法!收藏!顺便顶!
不过建议还是加上注释
假如这样的情况
ary = [[1, 1, 1, 1], [1, 2, 0, 1], [1, 1, 2, 1], [1, 1, 1, 1]];

结果返回的是false....

是不是limit也要跟着设置?
喜帖街my blog
循环那个位置 有问题 呆细琢磨 之前我设置的外循环是 在min和max之间 包括他们 后来又给改成了limit的最大和最小了  具体问题还需要多画图
http://zszen.host6.heyhost.cn/wp
刚学flash的时候写过一个连连看.考虑的情况有多种
你现在有几种情况,返回是false的
:L 连个注释都没啊 这怎么看 以前的算法好像是 看折点
感觉就用一个fn没必要注释吧 代码也不长 ,除非你不想看懂就想改代码直接用
http://zszen.host6.heyhost.cn/wp
更新了 更新了 还增加了 注释和图解
http://zszen.host6.heyhost.cn/wp
..怎么能通过两个位置来确定一个矩形范围呢?>>>

//矩阵
/*
[0,2,1,0]
[0,1,0,0]
[0,1,1,0]
[0,0,0,2]
*/
ary = [[0, 2, 1, 0], [0, 1, 0, 0], [0, 1, 1, 0], [0, 0, 0, 2]];

trace(outPath({i:0, j:1}, {i:3, j:3}, {i:4, j:4}));

//打印结果看看
喜帖街my blog
有这么几种情况
1. 两点之间没有拐点
2. 两点之间只有一个拐点
3. 两点之间有两个拐点

第一中情况,很好判断.不说了,
第二种情况:分别取两点横\纵方向,通路的线段,如果有交叉点,则通过
第三种 :a,b两点
取a点,先取其横向通路线段的点加入列表A,从A列表第一个点开始,取其纵向通路的点线段,如果该线段与b点的横向线段交叉则相通.........(其他情况类似)

太拗口了,表达不清楚

第三中情况的图

[ 本帖最后由 quhuan 于 2007-6-22 15:03 编辑 ]
111.jpg
这回没有问题了 ><
http://zszen.host6.heyhost.cn/wp

ary = [[0, 2, 0,1], [0, 1, 0, 0], [1, 1, 1, 2], [0, 1, 1, 0]];
trace(outPath({i:0, j:1}, {i:2, j:3}, {i:4, j:4}));
这样返回true

[ 本帖最后由 quhuan 于 2007-6-22 15:28 编辑 ]
唉 哈 不好意思 第一个循环里面的襄套循环 j<=maxj 不是j<maxj 疏忽 疏忽 呵呵
http://zszen.host6.heyhost.cn/wp
终于有注释了~
呵呵,谢谢楼主的热心啊~
严重谢谢ycccc8202和quhuan帮我测试
http://zszen.host6.heyhost.cn/wp
:) 谢谢版主 HOHO 不错 ~
有点象迷宫哈!·
各位朋友,谁下载好了[超级收集2500多个FLASH源代码下载演示]?现在不能下载,哪个朋友能传给我,QQ343776259,谢谢
当年我写过,也一样沉得很快
欢迎大家加入Flash侠客群,无论新老手,均一视同仁:24549400
应该顶呀
看的有点蒙 继续看:loveliness:
这坟挖得好 顶下慢慢看.
提示: 作者被禁止或删除 内容自动屏蔽
提示: 作者被禁止或删除 内容自动屏蔽
提示: 作者被禁止或删除 内容自动屏蔽
提示: 作者被禁止或删除 内容自动屏蔽
返回列表