连连看核心算法

合集下载

《连连看分步实现》课件

《连连看分步实现》课件
连连看分步实现
汇报人:
目录
添加目录标题
连连看游戏简介
连连看游戏开发流 程
连连看游戏核心算 法
连连看游戏界面设 计
连连看游戏性能优 化
添加章节标题
连连看游戏简介
连连看游戏是一种流行的 休闲游戏,起源于中国
游戏玩法:通过连接两个 相同的图案来消除它们
游戏目标:在限定时间内 消除所有图案
游戏特点:简单易学,适 合各年龄段玩家
连连看游戏界面设 计
游戏背景:选择清新、舒适的 背景颜色和图案
游戏区域:设置合理的游戏区 域大小和位置
游戏元素:设计可爱的游戏元 素,如动物、水果等
操作按钮:设置清晰的操作按 钮,如开始、暂停、帮助等
设计原则:简洁、清晰、易于识别 颜色搭配:鲜艳、对比度高,易于区分 图标形状:圆形、方形、三角形等,易于识别和记忆 图标内容:动物、植物、食物、交通工具等,易于理解
游戏元素:卡通形象,色彩 鲜艳
游戏界面:简洁明了,易于 操作
游戏功能:得分、时间、提 示等
游戏音效:轻松愉快,增加 游戏趣味性
连连看游戏的基本规则 连连看游戏的数据结构 连连看游戏的搜索算法 连连看游戏的优化算法
功能测试:确保游戏功能正常,无 bug
用户体验测试:收集用户反馈,优 化游戏界面和操作流程
游戏特色:画面简 洁,操作简单,适 合各年龄段玩家
游戏逻辑设计:如何实现连连看的游戏规则和逻辑 图形界面设计:如何设计出美观、易用的图形界面 性能优化:如何优化游戏性能,提高运行速度 用户体验设计:如何设计出符合用户习惯的操作方式和界面布局
优化游戏界面:提高用户 体验,增加游戏趣味性
优化游戏规则:简化游戏 规则,提高游戏可玩性

连连看算法

连连看算法

连连看所要求的是:1:两个目标是相同的2:两个目标之间连接线的折点不超过两个。

(连接线由x轴和y轴的平行线组成)那么分析一下连接的情况可以看到,一般分三种情况1:直线相连2:一个折点3:两个折点如图:可以发现,如果有折点,每个折点必定有且至少有一个坐标(x或者y)是和其中一个目标点是相同的,也就是说,折点必定在两个目标点所在的x方向或y方向的直线上。

所以设计思路就是:假设目标点p1 , p2 ,如果有两个折点分别为z1 , z2 那么,所要进行的是1:如果验证p1 , p2 直线连线,则连接成立2:搜索以p1,p2的x,y方向四条直线(可能某两条直线会重合)上的有限点,每次取两点作为z1,z2 ,验证p1到z1/z1到z2/z2到p2 是否都能直线相连,是则连接成立。

(如果z1=z2也就是只有一个折点喽,对判断没影响)那么程序算法上,这里先就理论进行一个试验var mmap=new Array();mmap[0]=new Array(0,0,0,0,0,0);mmap[1]=new Array(0,1,2,8,1,0);mmap[2]=new Array(0,5,5,4,3,0);mmap[3]=new Array(0,4,6,7,3,0);mmap[4]=new Array(0,8,2,6,7,0);mmap[5]=new Array(0,0,0,0,0,0);p1=new Array(1,4);p2=new Array(1,2);//定义一个二维数组作为游戏的映像,相同的数字代表相同的图标,0是空处,p1,p2是选择的点linelink=function(o1,o2){var t=new Array(0,0);if(o1[0]==o2[0] || o1[1]==o2[1]){if(Math.abs(o1[0]-o2[0])+Math.abs(o1[1]-o2[1])<=1){return true;}else{t[0]=isNaN((o2[0]-o1[0])/Math.abs(o2[0]-o1[0])) ? o1[0] :o1[0]+((o2[0]-o1[0])/Math.abs(o2[0]-o1[0]));t[1]=isNaN((o2[1]-o1[1])/Math.abs(o2[1]-o1[1])) ? o1[1] :o1[1]+((o2[1]-o1[1])/Math.abs(o2[1]-o1[1]));return mmap[t[0]][t[1]]==0 ? linelink(t,o2) : false}}else{return false;}}// 上面这个函数是判断任意两个点是否能直线连接(中间的点全为0)var parr=new Array(); pickpoint=function(q1,q2){var j;parr.splice(0);for(j=0;j<mmap[q1[0]].length;j++){parr=mmap[q1[0]][j]==0?parr.concat([[q1[0],j]]):parr; }for(j=0;j<mmap[q2[0]].length;j++){parr=mmap[q2[0]][j]==0?parr.concat([[q2[0],j]]):parr; }for(j=0;j<mmap.length;j++){parr=mmap[j][q1[1]]==0?parr.concat([[j,q1[1]]]):parr; }for(j=0;j<mmap.length;j++){parr=mmap[j][q2[1]]==0?parr.concat([[j,q2[1]]]):parr; }}//上面这个函数是取出两个点的x和y直线方向上的所有空点保存进parr这个数组里面待搜索islink=function(p1,p2){var i,jif(p1==p2){return false;}if(mmap[p1[0]][p1[1]]<>mmap[p2[0]][p2[1]]){return false;}if(linelink(p1,p2)){return true;}else{for(i=0;i<parr.length;i++){for(j=0;j<parr.length;j++){if(linelink(p1,parr[i]) && linelink(p2,parr[j]) && linelink(parr[i],parr[j])) {trace(parr[i]+"->"+parr[j]);return true;}}} }return false;}//上面这个函数是校验两个目标点是否相连,//先判断是否同类点,再判断是否直线相连,最后搜索parr里的每对折点是否使目标点相连pickpoint(p1,p2); //取得parr数组trace(islink(p1,p2)); //测试p1,p2是否相连嘿,运行试试?这个是上面这几个函数的测试源码点击浏览该文件根据这个原理,把图标对照数组,动态建立数组,加上一些效果啊,鼠标检测啊,就成了下面这个这样的基本《连连看》游戏模块啦点击浏览该文件这个是作成游戏后的源码点击浏览该文件>>>> 进入论坛交流<<<<。

毕业设计基于JME的连连看游戏开发

毕业设计基于JME的连连看游戏开发

引言在如今3G时代,手机游戏、移动多媒体无线增值服务,已会成为一个热点。

我国主要的移动运营商正在积极努力致力于发展手机游戏业务。

在中国,手机游戏仍处于探索时期,其发展仍然受很多因素的制约。

面对广阔的市场和无限的潜在客户的基础上,如何真正让手机游戏在正确的轨道上发展和运作是电信运营商和游戏开发商急需解决的问题。

从用户角度看,手机游戏因其随时随地便于携带的基本特征备受用户关注。

因此用户无论在户外或车里,只要是空闲时间,都可以成为手机游戏参与者。

由于游戏节奏很快,不会占用用户大量的时间,游戏情节进度可以暂停等效果,给用户提供方便,并降低了游戏难度的阈值,提高用户的游戏的兴致度及可玩值,提供更适合的人在旅游时的休闲、娱乐功能。

从开发的角度上来看,成熟的手机游戏产品应该有以下几个方面:一个是能够适应庞大的用户群,即可以在高峰时间内集中加载游戏的信息;二是游戏可以适应不同的移动终端的屏幕尺寸;三是一个手机游戏的兼容性,一些智能手机的色彩和声音支持具有良好的兼容性;四是游戏中应当应用合理大小,若手机没有太大内存,用户下载和存储很难;五是游戏过程能中断性要求,结合不同的特点,可以实现手机操作系统的背景。

目前,手机网络游戏有两大发展的基本条件:一是有效的3G网络传输平台,在3G手机网络时代的传输速率和承载能力有了很大程度的提高,互联网电话打开网页时间基本控制在3秒左右,对移动电话使用3G网络的高速数据传输的实时转播的多媒体内容丰富,打破了数据传输速度的对手机游戏开发限制;二是完美的电话终端的软硬件支持环境,手机硬件生产、开发与手机操作系统的不断成熟,为移动终端平台实现多种插件凝聚力提供依据,手机的娱乐功能越来越易于实现高质量的,有利于各种手机网络游戏需要。

手机网络游戏市场的需求将在几年呈强劲的势头。

首先,是指在2002年左右发展迅速的PC网络游戏。

从中可以看到,中国的宽带互联网业务网络游戏和走进公众生活,占用庞大的用户群体,使中国的游戏厂商也如雨后春笋般迅速崛起一般。

连连看原理

连连看原理

用 JAVA 开发游戏连连看其实不管是做软件也好,做游戏也好,只要是写程序,在动手之前是一定会存在需求和分析的,如果不经过一定的分析就开始动手写程序,那么,这个程序一定会很难写下去的,最后的结果可能会导致放弃。

那么,在我们动手之前,让我们先简单的分析一下吧。

由于“连连看”并不是一个我们凭空开发的游戏,并且网上也已经有很多别人已经开发好的版本,因此,对于我们来说,我们已经拥有了一个很好的原型(比如说 QQ 游戏中的“连连看”),分析起来也应该是轻松得多。

由于 QQ 中的“连连看”是网络版,为了开发上的简便,我们先放弃网络功能,做一个简单的单机版就行了。

现在,让我们现在来看一看 QQ 中的连连看吧。

“连连看”的游戏规则其实并不复杂,首先,游戏开始的时候,地图上会有由数张不同的图片随机分散在地图上(并且每张图片会出现偶数次,通常是 4 次),只需要在地图上找出两张相同的图片(点),并且这两个点之前可以用不超过 3 条的直线连接起来就可以消除这两点,如此下去,直到地图上的点全部消除完就算游戏结束,怎么样,规则很简单吧?:)我们的开发就完全按照些规则来吧。

分析游戏规则找出算法通过上面的分析,我们已经知道了游戏规则,可是,我们怎么样去实现呢?其实所谓的实现也就是算法,那我们怎么样找出算法呢?别急,让我们来看一看上图,或者自己动手玩一玩别人做好的。

通过对上图的观察,我们发现,可以将游戏中的地图看作是一个二维数组,其中的所有图片(以下称“点”)可以看作是数组中的一个具体的元素。

那么,游戏中相同的图片可以看作是数组中不同位置两个值相同的元素。

至于直线,让我们给组数中的每一个元素赋一个特殊的值如 0 ,以表示地图上空白的位置。

并且同时规定:当连续的具有该特殊值的点的横向索引或纵向索引相同时,可以认为这是一条直线,比如下图:当数组中两点的值相同并且两点间只需要不超过 3 根直线能连接起来的时候,就让这两点的值变为 0 ,如果数组中全是 0 值的点,就认为游戏已经结束:)怎么样,算法够简单了吧:)用伪代码来描述程序的结构现在,我们用伪代码来描述一下游戏,假设用户开始了游戏:消除两点;上次选择的点 = null ;if ( 地图上已没有可消除的点 ) { 游戏结束;}}else {上次选择的点 = 当前点;}}else {上次选择的点 = 当前点;}}游戏结束;看看有没有什么问题?如果没有问题,我们进入下一步吧:)确定程序需要的模块当伪代码完成后,并且在我们的大脑里转了几圈发现没有问题后,现在就可以开始进行模块的划分工作了。

连连看的算法

连连看的算法

0, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 8, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 9, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 0这是一张连连看的地图,假设标8和9的部分是两张相同的牌。

在数组矩阵中,0表示没有牌,大于1表示有牌。

至于是什么牌,那是随机的了。

不要告诉我,你说的“布局算法”是指怎么把牌刚刚好放上去,那个无所谓什么算法,你只要首先在地图数组中准备好偶数个1,在布牌时保证每种牌是偶数个(不同种类的牌用大于1的数来表示),相应地放入每个1的位置上就可以了。

一、计算地图上这两张牌能不能连通(当然能了,哈哈)。

这是连连看寻路算法的第一步。

先定义一下两张牌能连的充分条件:1.两张牌是同一种。

2.两张牌之间有一条全是0的路可以连通。

3.这一条路不能有两个以上的拐角(corner)满足这三个条件,就可以认为这两张牌是可以连的。

首先,我们依据前两个条件来完成一个基本的寻路算法。

我们的目的是从8到9找出一条可以连通的路来。

那么很明显从8到9的第一步一其有四个方向可以选择,分别是东,南,西,北(e, s, w, n以中国地图方向为标准)四个方向,在第一步中我们首先假设四个方面没有任何优劣,那么我可以任意选择一个方向移动,那就是东面吧。

图二:0, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 8, -8, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 00, 0, 0, 0, 0, 0, 0, 0 , 9, 00, 0, 0, 0, 0, 0, 0, 0 , 0, 0我从8向东移动了一步,所以到达了-8的位置,我之所以可以移到-8位置,很明显,是因为-8的位置上原来是一个0,表示没有牌阻挡。

连连看算法详谈

连连看算法详谈

游戏连连看的算法探究及源码实现(1)------ 综述述---转载时请注明原文出处(/wyw1976)及作者邮箱(wyw1976@)“连连看”是一款老少皆宜、百玩不厌的休闲类小游戏。

各种“连连看”也层出不穷、五花八门,例如“果蔬连连看”、“宠物连连看”、“麻将连连看”等。

各种“连连看”大同小异,无非就是界面图片不同,其核心算法应该是类似的。

闲暇时,自己也编了一个“连连看”小游戏,大约有1000行代码,功能如下:(1)纯C、纯字符界面,下面是截图:(2)10种游戏模式:∙普通模式∙左移模式∙右移模式∙上移模式下移模式∙左右分离模式∙上下分离模式∙水平中线聚集模式∙垂直中线聚集模式中心点聚集(3)随机产生游戏初始布局。

(4)随时进行“死锁”监控(5)“死锁”发生时,重新生成游戏残局(6)“路径输出”。

在连通时,输出连通路径。

(7)支持“自动”和“手动”两种模式。

在“自动”模式中,计算机模拟用户完成整个游戏。

这在算法测试时显得尤为重要,因为靠人工来完成算法的测试,十分低效甚至不可能全覆盖,而“自动”模式中,计算机完成一局的时间只要几秒,很容易发现算法中的漏洞。

(8)支持性能统计。

这对于算法优化很重要。

游戏"连连看"的算法探究及源码实现(2)----- 流程图下面是“连连看”的流程图:说明:(1)在"死锁"判定时,只要找到了一对匹配的点,就立即退出并记录该匹配点对,(在需要提示的时候,只要输出该点对即可)。

(2)如果用户的输入点对是连通的,而且与匹配点对中的任何一个是相同的,则需要重新进行“死锁”判定。

(3)在“连通”判定过程中,会生成连通路径。

(4)“更新游戏布局”包括移动相关的点,及消除匹配点。

(5)“初始布局”和“残局”的处理是不同的,这点我们还会详细说明(6)从上述流程图中,可以看出程序主要包含以下几个模块:∙随机生成游戏初始布局∙“死锁”判定∙随机产生游戏残局∙连通判定∙游戏布局更新∙生成联通路径我们将详细描述以上模块的算法及其实现。

《连连看》算法c语言演示(自动连连看)

《连连看》算法c语言演示(自动连连看)

《连连看》算法c语⾔演⽰(⾃动连连看)(图⽚是游戏的⽰意图,来⾃互联⽹,与本⽂程序⽆关)看题⽬就知道是写给初学者的,没需要的就别看了,⾃⼰都觉得怪⽆聊的。

很多游戏的耐玩性都来⾃精巧的算法,特别是⼈⼯智能的⽔平。

⽐如前⼏天看了著名的Alpha GO的算法,⽤了复杂的⼈⼯智能⽹络。

⽽最简单的,可能就是连连看了,所以很多⽼师留作业,直接就是实现连连看。

连连看游戏的规则⾮常简单:1. 两个图⽚相同。

2. 两个图⽚之间,沿着相邻的格⼦画线,中间不能有障碍物。

3. 画线中间最多允许2个转折。

所以算法主要是这样⼏部分:1. ⽤数据结构描述图板。

很简单,⼀个2维的整数数组,数组的值就是图⽚的标志,相同的数字表⽰相同的图⽚。

有⼀个⼩的重点就是,有些连连看的地图中,允许在边界的两个图⽚,从地图外连线消除。

这种情况⼀般需要建⽴的图板尺⼨,⽐实际显⽰的图板,周边⼤⼀个格⼦,从⽽描述可以连线的空⽩外边界。

本例中只是简单的使⽤完整的图板,不允许利⽤边界外连线。

2. ⽣成图板。

通常⽤随机数产⽣图⽚ID来填充图板就好。

⽐较复杂的游戏,会有多种的布局⽅式,例如两个三⾓形。

这种⼀般要⼿⼯编辑图板模板,在允许填充的区域事先⽤某个特定的整数值来标注,随后的随机数填充只填充允许填充的区域。

本例中只是简单的随机填充。

3. 检查连线中的障碍物。

确定有障碍物的关键在于确定什么样的格⼦是空。

通常定义格⼦的值为0就算空。

要求所有的图⽚ID从1开始顺序编码。

复杂的游戏还会定义负数作为特定的标志,⽐如允许填充区之类的。

4. 检查直接连接:两张图⽚的坐标,必然x轴或者y轴有⼀项相同,表⽰两张图⽚在x轴或者y轴的同⼀条线上才可能出现直接连接。

随后循环检查两者之间是否有障碍物即可确定。

5. 检查⼀折连接:与检查直接连接相反,两个图⽚必须不在⼀条直线上,才可能出现⼀折连接,也就是x/y必须都不相同。

随后以两张图⽚坐标,可以形成⼀个矩阵,矩阵的⼀对对⾓是两张图⽚,假设是A/B两点。

连连看算法及实现原理详解(C++源码)

连连看算法及实现原理详解(C++源码)
////////////////////////////////////////////////////////////////////////
void FunctionalModule::m_ColorToNum(HWND hwnd) //把像素转换为数组格式
{
HDC hdc=GetDC(hwnd);
break;
default:
break;
}
}
}
}
}
}
}
}
}
}
////////////////////////////////////////////////////////////////////////
int icolor=0;
COLORREF ccolor1,ccolor2;
for (int n1=0,nx=10;n1<5;n1++,nx-=5)
{
for (int m1=0,my=10;m1<5;m1++,my-=5)
int m_LeftTop(int ax,int ay,int bx,int by); //左上 11
int m_YLeft(int ax,int ay,int bx,int by); //y左 12
int m_LeftBottom(int ax,int ay,int bx,int by); //左下 13
{
ptLineOne.x=0;ptLineOne.y=0;//转折点的两个坐标设为0
ptLineTwo.x=0;ptLineTwo.y=0;
numTotal=(xLast+1)*(yLast+1);//图案总的个数
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

连连看核心算法转:最近参考一个JAVA的版本写了一个AS3版的连连看游戏算法, 欢迎大家拍砖指正,里面用到了as3ds类库, 还有一些粉简单的辅助类就不贴出来了, 各位闭着眼睛也能想象出来, 看主要的逻辑吧:package ponents{import de.polygonal.ds.Array2;import de.polygonal.ds.DLinkedList;import de.polygonal.ds.Iterator;import flash.geom.Point;import utils.*;/*** 连连看算法* @author Luan (verycss-ok@)*/public class Map{private var _level:uint; //游戏关卡对应的项目数量private var _map:Array2; //二维数组private var _array:Array; //辅助的一维数组private var _restBlock:uint = 0; //剩余的项目数量private var _vector:DLinkedList; //保存符合条件线段的地方private var _countOfPerItem:uint; //每个项目出现的次数(偶数)private var _result:MatchResult; //暂存符合条件的结果public function Map(level:uint = 16){//加2是为了加一圈0_map = new Array2( Setting.COLUMN+2, Setting.ROW+2 );_array = new Array(_map.size - 2*_map.width - 2*_map.height + 4);_vector = null;_result = new MatchResult();//调用setterthis.level = level;}/********************** getter & setter **********************/public function set level(value:uint):void{_level = value;//取得一个尽量大的偶数值_countOfPerItem = NumberUtil.getFloorEven(_map.size / _level);_restBlock = _level * _countOfPerItem;_initMap();}public function get count():uint{return _restBlock <= 0?0:_restBlock;}public function get map():Array2{return _map;}public function get result():MatchResult{return _result;}/********************** 私有方法**********************/private function _initMap():void{//一维数组初始化和乱序for (var n:uint = 0; n < _array.length; n++)_array[n] = 0;for (var i:uint = 0; i < _level; i++){for (var j:uint = 0; j < _countOfPerItem; j++){_array[i * _countOfPerItem + j] = i + 1;}}_array = ArrayUtil.random(_array);ArrayUtil.drawWrappedMap(_array, _map);}/*** 横向检查* @param a* @param b* @return*/private function _hTest(a:Point, b:Point):MatchResult {if (a.x == b.x || a.y != b.y ) return null;var x_start:uint = Math.min(a.x, b.x);var x_end:uint = Math.max(a.x, b.x);for (var x:uint = x_start + 1; x < x_end; x++)if ( _map.get(x, a.y) != 0 )return null;return _result.fill(a.clone(), b.clone());}/*** 纵向检查* @param a* @param b* @return*/private function _vTest(a:Point, b:Point):MatchResult {if (a.y == b.y || a.x != b.x) return null;var y_start:uint = Math.min(a.y, b.y);var y_end:uint = Math.max(a.y, b.y);for (var y:uint = y_start + 1; y < y_end; y++)if ( _map.get(a.x, y) != 0 )return null;return _result.fill(a.clone(), b.clone());}/*** A 、B 之间有一个拐点* @param a* @param b* @return*/private function _oneCorner(a:Point, b:Point):MatchResult {var c:Point = new Point(a.x, b.y);var d:Point = new Point(b.x, a.y);var isMatch:Boolean = false;if (_map.get(c.x, c.y) == 0) //C 点上必须没有障碍{isMatch = _vTest(a, c) && _hTest(b, c);if (isMatch){_result.clear();return _result.fill(a.clone(), b.clone(), c.clone());}}if (_map.get(d.x, d.y) == 0) //D 点上必须没有障碍{isMatch = _hTest(a, d) && _vTest(b, d);if (isMatch){_result.clear();return _result.fill(a.clone(), b.clone(), d.clone());}}return null;}/*** 扫描两点决定的矩形范围内有没有完整的空白线段* @param a* @param b* @return*/private function _scanLine(a:Point, b:Point):DLinkedList {var v:DLinkedList = new DLinkedList();// 从a, c 连线向b 扫描,扫描竖线// 扫描A 点左边的所有线for (var x1:Number = a.x; x1 >= 0; x1--){var c1:Point = new Point(x1, a.y);var d1:Point = new Point(x1, b.y);// 存在完整路线-- c,d点为零且纵向连通if ( _map.get(x1, a.y) == 0 && _map.get(x1, b.y) ==0 && _vTest(c1, d1) )v.append( new Line(Line.VERTICAL, c1, d1) );}// 扫描A 点右边的所有线for (var x2:Number = a.x; x2 < _map.width; x2++) {var c2:Point = new Point(x2, a.y);var d2:Point = new Point(x2, b.y);if ( _map.get(x2, a.y) == 0 && _map.get(x2, b.y) ==0 && _vTest(c2, d2) )v.append( new Line(Line.VERTICAL, c2, d2) );}// 从a, d 连线向b 扫描,扫描横线// 扫描A 点上面的所有线for (var y1:Number = a.y; y1 >= 0; y1--){var c3:Point = new Point(a.x, y1);var d3:Point = new Point(b.x, y1);if ( _map.get(a.x, y1) == 0 && _map.get(b.x, y1) ==0 && _hTest(c3, d3) )v.append( new Line(Line.HORIZONTAL, c3, d3) ); }// 扫描A 点下面的所有线for (var y2:Number = a.y; y2 < _map.height; y2++) {var c4:Point = new Point(a.x, y2);var d4:Point = new Point(b.x, y2);if ( _map.get(a.x, y2) == 0 && _map.get(b.x, y2) ==0 && _hTest(c4, d4) )v.append( new Line(Line.HORIZONTAL, c4, d4) );}return v;}/*** 对所有找到的符合线进行判断,看看AC 、DB 是否同样也可以消除* @param a* @param b* @return*/private function _twoCorner(a:Point, b:Point):MatchResult{_vector = _scanLine(a, b);if (_vector.isEmpty()) return null; //没有完整的空白线段,无解var itr:Iterator = _vector.getIterator();while (itr.hasNext()){var ln:Line = itr.next() as Line;switch (ln.direct){case Line.HORIZONTAL:if ( _vTest(a, ln.a) && _vTest(b, ln.b) ){_result.clear();return _result.fill(a.clone(), b.clone(),ln.a.clone(), ln.b.clone());}break;case Line.VERTICAL:if ( _hTest(a, ln.a) && _hTest(b, ln.b) ){_result.clear();return _result.fill(a.clone(), b.clone(),ln.a.clone(), ln.b.clone());}break;}}return null;}private function _findRestPointA(map:Array2 = null):Point {var m:Array2 = map || _map;if (m.width >= m.height){for (var col:Number = 0; col < m.width; col++){var max_y:Number = Math.min(col + 1, m.height);for (var y1:Number = 0; y1 < max_y; y1++){if (m.get(col, y1) != 0)return new Point(col, y1);}for (var x1:Number = 0; x1 < col; x1++){if (m.get(x1, max_y-1) != 0)return new Point(x1, max_y-1);}}}else{for (var row:Number = 0; row < m.height; row++){var max_x:Number = Math.min(row + 1, m.width);for (var x2:Number = 0; x2 < max_x; x2++){if (m.get(x2, row) != 0)return new Point(x2, row);}for (var y2:Number = 0; y2 < row; y2++){if (m.get(max_x-1, y2) != 0)return new Point(max_x-1, y2);}}}return null;}private function _findRestPointB(a:Point, ignore_b_arr:Array= null):Point{if (!a) return null;var tempMap:Array2 = ArrayUtil.cloneArray2(_map);tempMap.set(a.x, a.y, 0);if (ignore_b_arr && ignore_b_arr.length){for each (var bb:Point in ignore_b_arr)tempMap.set(bb.x, bb.y, 0);}var b:Point = _findRestPointA(tempMap);if (!b) return null;while ( _map.get(a.x, a.y) != _map.get(b.x, b.y) ){tempMap.set(b.x, b.y, 0);b = _findRestPointA(tempMap);if (!b) return null;}return b;}/********************** 公开方法**********************//*** 测试两点是否可以连通* @param a* @param b* @usage 判断两点的值相同并且满足连通条件* @return*/public function test(a:Point, b:Point):Boolean{_result = new MatchResult();if (_map.get(a.x, a.y) != _map.get(b.x, b.y))return false;if ( _hTest(a, b) || _vTest(a, b) || _oneCorner(a, b) ||_twoCorner(a, b) )return true;elsereturn false;}/*** 自动寻找一条可连通的路径* @return*/public function autoFindLine():MatchResult{var a:Point = _findRestPointA(); if (!a) return null;var b:Point = _findRestPointB(a); if (!b) return null;var ignoreA:Array = [];var ignoreB:Array = [];while ( !this.test(a, b) ){ignoreB.push(b);b = _findRestPointB(a, ignoreB);//基于A没有可以连通的点了, 换一个A试试if (!b){ignoreB = [];ignoreA.push(a);var tempMap:Array2 = ArrayUtil.cloneArray2(_map);tempMap.set(a.x, a.y, 0);if (ignoreA.length)for each (var p:Point in ignoreA)tempMap.set(p.x, p.y, 0);a = _findRestPointA(tempMap);b = _findRestPointB(a);}}//找不到可以连通的B点if (!b) return null;return _result.clone();}/*** 清除两点* @param a* @param b*/public function earse(a:Point, b:Point):void{_map.set(a.x, a.y, 0);_map.set(b.x, b.y, 0);_restBlock -= 2;}/*** 刷新*/public function refresh():void{var num:uint = this.count;if (num <= 0) return;_array = ArrayUtil.random( ArrayUtil.getWarppedMapArray(_map) );ArrayUtil.drawWrappedMap(_array, _map);}} }。

相关文档
最新文档