连连看寻路算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
主题:[讨论]连连看寻路算法/全程求解算法
作者:华山论剑发表时间:2007-11-28 17:51:00
楼主遇到一个算法问题,希望朋友们多给些意见。
最近SDK写了个连连看游戏,其中的两点间寻路的算法基本上是用网上的一段代码,全路径求解算法则是自己写的,
遇到容易的矩阵可以秒杀,但遇到复杂的则速度就很慢了。希望大家给些意见,改善一下效率。
先说全程求解部分。
说明:
1、如果有解,找出解法;
2、如果无解,给出相对最佳路径;
3、如果有多解,找到一个就退出;
4、连连看的矩阵为10*12(10行,每行12张牌),加上上下左右要各留一空行以便寻路,矩阵为12*14;
5、矩阵中某点值为0表示无牌,否则有牌;
6、矩阵不一定是初始状态,因为有时我们玩到一半可能用软件来求解。
例子数组:
m[12][14] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 29, 3, 18, 26, 9, 2, 6, 33, 10, 9, 4, 15, 0,
0, 19, 18, 29, 7, 14, 9, 10, 23, 34, 16, 21, 15, 0,
0, 21, 27, 26, 2, 26, 11, 30, 17, 25, 14, 10, 5, 0,
0, 19, 12, 33, 33, 31, 34, 15, 11, 28, 7, 8, 23, 0,
0, 12, 16, 27, 4, 5, 21, 27, 8, 1, 6, 23, 4, 0,
0, 19, 34, 25, 1, 6, 26, 25, 15, 17, 12, 6, 31, 0,
0, 10, 4, 16, 17, 31, 8, 8, 7, 28, 28, 34, 30, 0,
0, 3, 21, 5, 14, 18, 2, 12, 20, 20, 2, 25, 1, 0,
0, 30, 20, 19, 31, 3, 9, 14, 16, 5, 29, 33, 3, 0,
0, 1, 20, 11, 27, 28, 17, 30, 18, 7, 29, 11, 23, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
这个数组也许是无解的,如果无解,则给出相对最好的解法。
基本流程:
1、复制矩阵和路径数组为m和way;
2、先找一个有牌点p1;
3、然后找其它几个配对的点same[N];
4、依次检查p1和same[N]中的元素是否相通;
5、若相通则消去两张牌,若消完则返回;
6、没消完再递归寻路。
作者:雨中飞燕发表时间:2007-11-28 17:54:00
第1楼那个叫回溯嘛。。。。
作者:华山论剑发表时间:2007-11-28 17:56:00
第2楼下面是代码:
typedef struct
{
int m[12][14];
point way[60][4];
}llk;
int least_left; //最少剩牌数,用于无解时保存最好解法point shortest_way[60][4]; //相对最好解法路径
int find_same(point p, point same[], const int m[][14])
{ //找相同的点
int i, j;
int num = 0;
for (i=1; i for (j=1; j { if ( m[i][j]==m[p.x][p.y] && (i!=p.x||j!=p.y) ) { same[num].x = i; same[num++].y = j; } } return num; } BOOL find_way(llk *v, //llk结构 int left, //剩下牌张 const int in[][14], //矩阵 point wayin[][4]);//全程求解路径 { int i, j, k; //循环变量 int m[12][14]; //矩阵复制品 int num, idx; //对于一个点,有几个相同的int old; //保存旧值 point way[60][4], same[10]; //路径,相同点的坐标数组 point p; //要找配对的点 if (least_left==0) return TRUE; idx = (120 - left) / 2; //路径中要更新的位置索引 memcpy(m, in, sizeof(m)); //矩阵复制品 memcpy(way, wayin, sizeof(way));//路径复制品 for (i=1; i for (j=1; j //缩进太多,将之提前------------num1 if (m[i][j] && least_left) //找到有牌点 { p.x = i; p.y = j;