连连看寻路算法
连连看算法

连连看所要求的是: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是否相连嘿,运行试试?这个是上面这几个函数的测试源码点击浏览该文件根据这个原理,把图标对照数组,动态建立数组,加上一些效果啊,鼠标检测啊,就成了下面这个这样的基本《连连看》游戏模块啦点击浏览该文件这个是作成游戏后的源码点击浏览该文件>>>> 进入论坛交流<<<<。
连连看思路算法及实现

连连看思路算法及实现1. 任务概述连连看是一款益智类图标消除游戏,玩家需要通过消除相同的图标来获得分数。
该游戏的思路算法主要包括图标布局、路径查找和消除逻辑。
本文将详细介绍连连看游戏的思路算法及其实现。
2. 游戏规则在连连看游戏中,通常会给出一个NxM的矩阵,矩阵中填充了各种不同类型的图标。
玩家需要通过点击两个相同的图标,使它们之间的路径最多只有两个直角转弯,从而消除这两个图标。
被消除的图标将被移除,并且上方的图标将下落填充空缺。
玩家的目标是在限定时间内消除尽可能多的图标,获得尽可能高的分数。
3. 思路算法及实现3.1 图标布局图标布局是连连看游戏的一个重要部分。
在游戏开始前,需要生成一个随机的NxM矩阵,并在每个格子中填充一个随机的图标。
为了保证游戏的可玩性,生成的矩阵需要满足以下条件: - 每个图标在矩阵中至少出现两次,确保存在与之相匹配的图标。
- 任意两个相同图标之间的路径不超过两个直角转弯,确保图标可以被消除。
其实现思路如下: 1. 随机生成NxM矩阵,并初始化为空。
2. 随机选择一个图标,将其填充到矩阵中某个随机的空格子。
3. 将该图标在矩阵中的位置存储到一个列表中。
4. 重复2-3步骤,直到每个图标至少在矩阵中出现两次。
5. 遍历矩阵,对于每一个空格子,随机选择一个已填充的图标填充进去,确保每个图标的数量相等。
6. 返回生成的矩阵。
3.2 路径查找路径查找是连连看游戏的关键算法之一。
在玩家点击两个图标后,需要通过路径查找算法判断这两个图标之间是否存在符合条件的路径。
一种常用的路径查找算法是深度优先搜索(DFS)算法。
其实现思路如下: 1. 从起点图标开始,将其标记为已访问。
2. 对于当前图标的每个相邻图标,判断是否满足消除条件(路径最多只有两个直角转弯)。
3. 如果相邻图标满足消除条件且没有被访问过,则递归调用步骤2。
4. 如果找到了与目标图标相匹配的路径,则返回True,否则返回False。
连连看

6
using System.Collections; //ArrayList命名空间 private void StartNewGame() { //初始化地图,将地图中所有方块区域位置置为空方块状态 for(int iNum=0;iNum<(m_nCol*m_nRow);iNum++) { m_map[iNum] = BLANK_STATE; } Random r = neWRandom(); //生成随机地图 //将所有匹配成对的动物物种放进一个临时的地图中 ArrayList tmpMap=neWArrayList (); for(int i=0;i<(m_nCol*m_nRow)/4;i++) for(int j=0;j<4;j++) tmpMap.Add(i); //每次从上面的临时地图中取走(获取后并在临时地图删除) //一个动物放到地图的空方块上 for (int i = 0; i < m_nRoW* m_nCol; i++) { //随机挑选一个位置 int nIndex = r.Next() % tmpMap.Count ; //获取该选定物件放到地图的空方块 m_map[i]=(int)tmpMap[nIndex]; //在临时地图除去该动物 tmpMap.RemoveAt(nIndex); } }
} //一个转弯(折点)的联通方式 if(OneCornerLink(x1,y1,x2,y2)) { LType = LinkType.OneCornerType ; return true; } //两个转弯(折点)的联通方式 else if(TwoCornerLink(x1,y1,x2,y2)) { LType = LinkType.TwoCornerType; return true; } return false;
基于深度优先搜索的连连看游戏路径查找算法

【关键词】连 连 看 游 戏 ; 路 径 ; 深 度 优 先 搜 索 ; 栈 ; 轨 迹
连连看的具体算法

2010年02月21日因为有朋友在站内信中问到连连看的具体算法,所以我就把算法post 出来,这个算法也是参考网上Flash游戏的算法改写的,原来的参考信息已经找不到了,不过非常感谢那些无私的朋友。
改写的连连看算法如下:前置条件:用一二维数组存放Map,-1表示没有图案可以连通,非-1表示不同的图案。
首先是横向检测:Java代码privateboolean horizon(Point a, Point b){if(a.x == b.x && a.y == b.y)//如果点击的是同一个图案,直接返回falsereturnfalse;int x_start = a.y <= b.y ? a.y : b.y;int x_end = a.y <= b.y ? b.y : a.y;for(int x = x_start + 1; x < x_end; x++)//只要一个不是-1,直接返回falseif(map[a.x][x] != -1){ returnfalse; } returntrue; }private boolean horizon(Point a, Point b){if(a.x == b.x && a.y == b.y)//如果点击的是同一个图案,直接返回false return false;int x_start = a.y <= b.y ? a.y : b.y;int x_end = a.y <= b.y ? b.y : a.y;for(int x = x_start + 1; x < x_end; x++)//只要一个不是-1,直接返回falseif(map[a.x][x] != -1){return false;}return true;}其次是纵向检测:Java代码privateboolean vertical(Point a, Point b){if(a.x == b.x && a.y == b.y)returnfalse;int y_start = a.x <= b.x ? a.x : b.x;int y_end = a.x <= b.x ? b.x : a.x;for(int y = y_start + 1; y < y_end; y++)if(map[y][a.y] != -1)returnfalse;returntrue;}private boolean vertical(Point a, Point b){if(a.x == b.x && a.y == b.y)return false;int y_start = a.x <= b.x ? a.x : b.x;int y_end = a.x <= b.x ? b.x : a.x;for(int y = y_start + 1; y < y_end; y++)if(map[y][a.y] != -1)return false;return true;}一个拐角的检测:如果一个拐角能连通的话,则必须存在C、D两点。
连连看的算法

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语⾔演⽰(⾃动连连看)(图⽚是游戏的⽰意图,来⾃互联⽹,与本⽂程序⽆关)看题⽬就知道是写给初学者的,没需要的就别看了,⾃⼰都觉得怪⽆聊的。
很多游戏的耐玩性都来⾃精巧的算法,特别是⼈⼯智能的⽔平。
⽐如前⼏天看了著名的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++源码)
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.寻找相同图案在连连看游戏中,最基本的操作就是寻找相同的图案。
因此,在进行游戏时,我们需要将所有可消除的图案都找出来,并建立起它们之间的关联关系。
2.建立关联关系建立图案之间的关联关系是为了方便后续操作。
我们可以使用二维数组或者链表等数据结构来存储每个图案以及它们之间的连接情况。
对于每一个图案,我们可以将其坐标作为数组下标,并将其与周围相邻的图案进行连接。
3.寻找可消除路径在建立好每个图案之间的连接关系后,我们就可以开始寻找可消除路径了。
通常情况下,可消除路径有两种:直线型和弯曲型。
对于直线型路径,我们只需要判断两个图案之间是否存在直线连接即可;而对于弯曲型路径,则需要考虑路径中是否存在转折点。
4.消除图案当我们找到了可消除路径后,就可以进行图案的消除操作了。
在消除时,我们需要将所有经过的图案都从数据结构中删除,并将得分累加到总分中。
此外,在进行消除操作时,我们还需要考虑一些特殊情况,如图案之间存在障碍物等。
5.判断游戏结束当所有的图案都被消除或者无法再进行消除操作时,游戏就结束了。
在判断游戏是否结束时,我们可以检查当前数据结构中是否还有未被消除的图案。
如果存在未被消除的图案,则说明游戏还未结束;否则,游戏就已经结束了。
二、实现方法1.数据结构在实现连连看游戏时,我们通常使用二维数组或链表等数据结构来存储每个图案以及它们之间的连接关系。
对于二维数组来说,其优点是存储简单、操作方便;而链表则更加灵活,可以动态地添加和删除元素。
2.算法实现在实现连连看游戏时,我们需要编写一些算法来完成相应的功能。
例如,在寻找可消除路径时,我们可以使用广度优先搜索算法(BFS)或深度优先搜索算法(DFS)来遍历所有可能的路径,并找到其中符合要求的路径。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
连连看寻路算法的思路2009年07月22日星期三 19:58图-:
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 8, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 9, 0
0, 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, 0
0, 8, -8, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 9, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
我从8向东移动了一步,所以到达了-8的位置,我之所以可以移到-8位置,很明显,是因为-8的位置上原来是一个0,表示没有牌阻挡。
那么现在寻路的问题就变成了,如何从-8找连通9的路了!
说到这里应该明白了吧,好多费话,有点像娘们在说话。
所以目前的寻路算法归结为一个递归算法的基本问题。
先从8到找到下一个结点-8,再用同样的规则,从-8找到下一个结点,比如-88。
图三:
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 8, -8, -88, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
0, 0, 0, 0, 0, 0, 0, 0 , 9, 0
0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
如果一直都能OK,没有阻碍的话,最后找到了9,就算成功以,如要有一步不能走下去了,就再退回上个结点,向别的方向发展,都不行,就再退回上级结点,再向别的方向发展,这里的逻辑就是递归的思想了。
用这样的方法写出来的算法已经能在最优的情形下用了,比如从8,到-88,哈哈。
但在稍微复杂的情况下,会产生奇多的递归结点。
P4机也跑不动啊。
我试过,哈哈。
那么第二步就是为(e,s,w,n)四个方向加权,也就是让它们之间有一个优先权,说白了就是先试哪一条路。
决定的法则应该有好几个吧,比如以9号的位置来看,它处于8号的东南面,
那试路时当然应当优先选择东面和南面,再比如9号如果牌8号的正东面,那当然是选择正东了。
再比如,当走到-8的位置时,明显只能再走三个方向,因为它是不能回头的。
经过这样的处理,递归算法生成的结点数会明显变少,会更快的找到成功的路。
但性能在最坏情况
下没有本质改变。
接下来,第三步,我们把第三个充分条件加进来,来解决根本问题。
3.这一条路不能有两个以上的拐角(corner)
按照面向对象的思想,很自然的,我给每个在递归算法中生成的位置结点加上了个corner 的属性,
来记录这条路到目前为止拐了几个角。
这样一下子就好办了啊。
如果发现这个结点已经拐了两个弯时,如果要再拐弯,或者到达9之前注定
要再增加cornor时,就果断over,返回上级结点。
好,就说到这儿吧,不能再多说了,否则就是等于把代码公开了,哈哈。
注意,要把二、三两步的条件综合起来详细规划一个个可能性,尽可能提早让不可能的结点OVER,
这就是提高性能的关键吧。
你的算法预见性越强,性能就越高吧。
我们的算法在赛扬500,256M的机器上,10万次平均结果是一次运算花时不超过0.1毫秒,算得还不
精确,速度确实很快,因为在很坏的情形下,产生的最大结点数是690几个,这样必然会很快的
,详细的数据已经记不清了。
说了这么多了,应当明白第一步连通算法的思路了吧,我所知道的,都已经尽可能的讲出来了。
这个算法完全是自己按照连连看的特点,度身定做的。
因为是一步步test出来的,所以我个人
觉得是很自然的,没有任何高深的地方,完成后,性能也很好,这才觉得是如此的简单。
相信大家
仔细看看就能写出自己的算法来的吧。
二、整个地图有没有解???可以连通的总牌数?
这是一个问题。
解决这个问题之前,我们先来解决提示功能(hint)就是为玩家提供提示,哪一对牌可以连
通。
我的做法是,先把整个地图中相同牌归到一起,用数组也好,链表也好。
像这样,
4,4,4,4
5,5,5,5
6,6,6,6
......
然后计算比如4个4之间有哪两对可以连,至于如何判断能不能连,第一步算法已经实现了吧,哈哈。
一发现有可以连的牌就退出来,告诉玩家这两张牌可以连啊!
这就OK了。
这完全是建立在第一步算法的基础上实现的。
好的,hint功能可以了,
那么,整个地图没有解的算法是不是出来了?
是的,如果找不到可以hint的牌,那当然就是没有解了!
把所有可以hint的对数记下来,就是总的可以连通数了。
至此,与连连看所有算法有关的问题解决完毕。
第二步算法的实现,明显开销要大很多,最坏情况应当会是单次连通算法计算量的大约50倍以上
(与牌的总数量和摆的位置有关)还好在一般的服务器上单次连通计算花的时间实在太少了,实际运行中完全可以很流畅。
以上数据都是我估计的理论值,因为实际测试时一直没有问题,我也懒得计算出真正比较可靠的均值了。
这一部分也是我认为可以有所改进的部分,公开出来,也希望大家能提供一些更好,更巧妙
的方法,我觉得我计算连通数和有无解的方法是比较笨的方法,几乎是仗着基本的算法快,一
个一个算出来的。
有没有更好的方法呢?期待中,我也会再想想,太忙,太懒,主要是懒,觉得
可以用就行了。