当前位置:文档之家› AS3连连看核心算法详解

AS3连连看核心算法详解

[教程] 连连看核心算法详解最近做了个连连看游戏,综合网上各种不同的思路,整理出了个人认为大家都比较好理解的一套思路。

游戏规则:很简单,就是点中两个互相匹配并且可以通过不多于两个折点的折线连在一起的方块后,这两个方块就可以消掉。

(说明:下面的行和列按照现实的行和列,并不是按照flash坐标系的坐标,请大家按需转换)连通算法:1.直连型2.一折型3.两折型下面我们来分析每一种情况:直连型直连性又分为两种情况:横向直连,纵向直连。

首先是横向检测:a(1,2) , b(1,7)1.private function horizon(a:Point,b:Point):Boolean2.{3. if (a.x == b.x && a.y == b.y) return false; //如果点击的是同一个图案,直接返回false;4. var x_start:int = a.y < b.y?a.y:b.y; //获取a,b中较小的y值5. var x_end:int = a.y < b.y?b.y:a.y; //获取a,b中较大的值6. //遍历a,b之间是否通路,如果一个不是就返回false;7. for (var i:int = x_start + 1; i < x_end;i ++ )8. {9. if (mapData[a.x][i] != 0)10. {11. return false;12. }13. }14. return true;15.}16.其次是纵向检测:1.a(1,1) , b(4,1)2.3.private function vertical(a:Point,b:Point):Boolean4.{5. if (a.x == b.x && a.y == b.y) return false;6. var y_start:int = a.x < b.x?a.x:b.x;7. var y_end:int = a.x < b.x?b.x:a.x;8. for (var i:int = y_start + 1; i < y_end; i ++ )9. {10. if (mapData[i][a.y] != 0)11. {12. return false;13. }14. }15. return true;16.}一个拐角的检测如果一个拐角能连通的话,则必须存在C、D两点。

其中C点的横坐标和B相同,纵坐标与A相同,D的横坐标与A相同,纵坐标与B相同1.* a(4,2) , b(2,7)2.* c(2,2) , d(4,7)3.private function oneCorner(a:Point,b:Point):Boolean4.{5. var c:Point = new Point(b.x, a.y);6. var d:Point = new Point(a.x, b.y);7. //判断C点是否有元素8. if (mapData[c.x][c.y] == 0)9. {10. var path1:Boolean = horizon(b, c) && vertical(a, c);11. return path1;12. }13. //判断D点是否有元素14. if (mapData[d.x][d.y] == 0)15. {16. var path2:Boolean = horizon(a, d) && vertical(b, d);17. return path2;18. }else19. {20. return false;21. }22.23.}两个拐角的检测:这个比较复杂,如果两个拐角能连通的话,则必须存在图中所示的连线,这些连线夹在A、B的横、纵坐标之间,这样的线就以下这个类存储,direct是线的方向,用0、1表示不同的方向.Line类结构如下:1.package2.{3. import flash.display.Sprite;4. import flash.geom.Point;5.6. /**7. * ...8. * @author icekiller9. */10. public class Line extends Sprite11. {12. public var a:Point;13. public var b:Point;14. public var direct:int; //连线方向1:水平直连 0:垂直直连15. public function Line(a:Point,b:Point,direct:int)16. {17. this.a = a;18. this.b = b;19. this.direct = direct;20. }21.22. }23.24.}从A、B点的横纵两个方向进行扫描,就是Scan函数做的事情,把合适的线用LinkList存起来。

判断是否是二连型的算法需要做两个方向上的扫描:水平扫描和垂直扫描。

先看水平的,首先,要找到棋子往左右可以延伸的范围,这里的延伸是指左右有多少空的位置;然后,计算水平坐标上两个棋子延伸出来的公共部分;最后,找公共的水平坐标里有没有可以“垂直直连”的.用图6,7,8说明图(6)图(7)水平延伸图(8)求得水平延伸公共范围从图(8)可以看出,左边缘(第零列)有一对叉可以直连,所以红色棋子是可以“二折连通”的!1.2.private function scan(a:Point,b:Point):Vector.<Line>3.{4. linkList = new Vector.<Line>();5. //检测a点,b点的左侧是否能够垂直直连6. for (var i:int = a.y; i >= 0; i -- )7. {8. if (mapData[a.x][i] == 0 && mapData[b.x][i] == 0 && vertical(new Point(a.x,i),new Point(b.x,i)))9. {10. linkList.push(new Line(new Point(a.x,i),new Point(b.x,i),0));11. }12. }13. //检测a点,b点的右侧是否能够垂直直连14. for (i = a.y; i < col;i ++ )15. {16. if (mapData[a.x][i] == 0 && mapData[b.x][i] == 0 && vertical(new Point(a.x,i),new Point(b.x,i)))17. {18. linkList.push(new Line(new Point(a.x,i),new Point(b.x,i),0));19. }20. }21. //检测a点,b点的上侧是否能够水平直连22. for (var j:int = a.x; j >= 0; j -- )23. {24. if (mapData[j][a.y] == 0 && mapData[j][b.y] == 0 && horizon(new Point(j,a.y),new Point(j,b.y)))25. {26. linkList.push(new Line(new Point(j, a.y), new Point(j, b.y), 1));27. }28. }29. //检测a点,b点的下侧是否能够水平直连30. for (j = a.x; j < row; j ++ )31. {32. if (mapData[j][a.y] == 0 && mapData[j][b.y] == 0 && horizon(new Point(j,a.y),new Point(j,b.y)))33. {34. linkList.push(new Line(new Point(j, a.y), new Point(j, b.y), 1));35.36. }37. }38.39. return linkList;40.}取出LinkList里面的线,测试A与B到该线的两点是否连通1.2.private function twoCorner(a:Point,b:Point):Boolean3.{4. var ll:Vector.<Line> = scan(a, b);5. if (ll.length == 0)6. {7. return false;8. }9. for (var i:int = 0; i < ll.length; i ++ )10. {11. var tmpLine:Line = ll[i];12. if (tmpLine.direct == 1)13. {14.15. if (vertical(a,tmpLine.a) && vertical(b,tmpLine.b))16. {17. return true;18. }19. }else if (tmpLine.direct == 0)20. {21. if (horizon(a, tmpLine.a) && horizon(b, tmpLine.b))22. {23. return true;24. }25. }26. }27. return false;28.}前面的函数有以下这个总的调用函数来调用,传入两个点,就可以判断这两个点是否符合连连看的算法了:1.2.//总函数3.private function checkLink(a:Point,b:Point):Boolean4.{5.6. if (a.x == b.x && horizon(a, b))7. {8. return true;9. }10. if (a.y == b.y && vertical(a, b))11. {12. return true;13. }14. if (oneCorner(a, b))15. {16. return true;17. }18. else19. {20. return twoCorner(a, b);21. }22.}。

相关主题