【github地址】speedlink-qt

连连看路线判定算法分析

连连看游戏规则:若两个图块相同且它们可以用一条两折之内的折线相连,那么它们消除掉。
用一个二位数组表示连连看的面板,那么每一种图块都可以用一个数字来表示,不同的数字代表不同的图案,0代表没有,消除图案=将该处置为0,这样,游戏的逻辑表示就完成了。
仔细分析连连看的规则,可以发现连连看的连线无非这么几种类型:直连型、一折型、两折型,它们大致的线型有如图:

仔细观察图,就可以发现,虽然两折型稍微复杂,但是观察一下就可以发现,如果将这两个点分别看成一个矩形两条平行边上的两点,这个矩形的另外两条边最大延伸到面板的边界,如果这两点是可连的,那么必定有一条线段可以连通这两条平行边,而且两点分别可以直线连通这条线段的两个端点。这种见解虽然没错,却不太方便实现,如果再观察一下,如果将其中一点为中心画一个十字,那么只要在这个十字上找到一点,这一点可以与另外一点以不多于一个折点相连,这就足以概括几乎所有的情况,因此实现了“判定一个点与另一个点可以使用一个折点相连“就可以了。

为什么不使用简单的回溯呢?如果使用上面的方法,寻路算法的复杂度要远远低于回溯,由于连连看中图块位置随机,不能定量分析,在此不仔细分析其复杂度。在实践中发现,如果使用回溯的方法,那么对于死局判定这种比较耗时的操作,往往游戏时就会稍微“卡”一下,对于小型设备则更是影响游戏流畅度,因此不使用回溯。

算法实现:

bool
DrawArea::isPosLinkable(int x1_,int y1_,int x2_,int y2_,int *nPos,Pos *pos1,Pos *pos2)
{assert(isValid(x1_,y1_));assert(isValid(x2_,y2_));bool posFlag=false;//传入参数中是否有折点if(nPos){posFlag=true;if(!(pos1&&pos2))return false;}int x1=x1_;int x2=x2_;int y1=y1_;int y2=y2_;if(!isSame(x1,y1,x2,y2))return false;//First,check whether they can be directly linkedif(isLineLinkable(x1,y1,x2,y2)){if(posFlag) *nPos=0;return true;}//Second,check whether they can be linked with one turningif(findInteractPoint(x1,y1,x2,y2)){if(posFlag){*nPos=1;pos1->x=x2;pos1->y=y2;}return true;}//Third,check x-direct point that can be linked with one turningfor(int i=0;i<xMax;++i){if(isBlank(i,y1) && isLineLinkable(i,y1,x1,y1) && findInteractPoint(i,y1,x2,y2)){if(posFlag){*nPos=2;pos1->x=i;pos1->y=y1;pos2->x=x2;pos2->y=y2;}return true;}}//Fourth,check y-direct point that can be linked with one turningfor(int i=0;i<yMax;++i){if(isBlank(x1,i) && isLineLinkable(x1,i,x1,y1) && findInteractPoint(x1,i,x2,y2)){if(posFlag){*nPos=2;pos1->x=x1;pos1->y=i;pos2->x=x2;pos2->y=y2;}return true;}}return false;
}
/* * 寻找以 (x1,y1)和 (x2,y2)所在线段为对角线的矩形中对这两个点均可直线到达的顶点* 若找到,则将 (x2,y2)改写为该顶点,否则,返回false*/
bool
DrawArea::findInteractPoint(const int &x1,const int &y1,int &x2,int &y2)
{if(!board[x1][y2]){if(isLineLinkable(x1,y1,x1,y2) &&isLineLinkable(x2,y2,x1,y2)){x2=x1;return true;}}if(!board[x2][y1]){if(isLineLinkable(x1,y1,x2,y1)&&isLineLinkable(x2,y2,x2,y1)){y2=y1;return true;}}return false;
}
/** 检验两点是否可以直线无障碍到达*/
bool
DrawArea::isLineLinkable(int x1,int y1,int x2,int y2)
{if(x1 == x2){if(y1>y2)    std::swap(y1,y2);for(y1+=1;y1<y2;++y1)if(board[x1][y1])return false;}else if(y1 == y2){if(x1>x2)    std::swap(x1,x2);for(x1+=1;x1<x2;++x1)if(board[x1][y1])return false;}elsereturn false;return true;
}

死局判断就容易多了,布局完成之后,以及每次销块结束之后进行一次判定即可。因为游戏还要有提示功能,在做遍历寻找可消块过程中把找到的第一对可销块记录作为提示之用就可以了。(由于我的游戏中创造了“上帝模式”,进入死局时,提示块为任意一对相同图案的图块。)

死局判断及提示块记录:

/* 判断是否已经进入死局,死局条件:* 在回合尚未结束的情况下遍历面板,无法找到一对可销图块* 则判定为死局。若找到一对可销图块,则将其记录为hintA* 和hintB,以供hint()函数利用。*/
bool
DrawArea::isDead()
{int i,j,x,y;if(!pairLeft)return true;for(i=0;i<xMax;++i){for(j=0;j<yMax;++j){if(board[i][j]){for(x=i;x<xMax;++x){if(x==i)    y=j+1;else y=0;for(;y<yMax;++y){if(board[x][y]==board[i][j]){if(isPosLinkable(i,j,x,y)){//如果消块成功,那么这里就变成了0hintA.x=i;hintA.y=j;hintB.x=x;hintB.y=y;return false;}}}}}}}return true;
}

转载于:https://www.cnblogs.com/qianyuming/archive/2011/08/15/2139857.html

Qt版连连看之极速连连看:路线判定算法相关推荐

  1. Qt版连连看之极速连连看:设计

    [源码及安装包下载地址]http://code.google.com/p/speedlink/downloads/list [项目展示及相关截图在最后] 术语约定: 面板:连连看中用于拜访小图案的区域 ...

  2. Qt版连连看之极速连连看:界面设计(一)QSS更换主题

    [github地址]speedlink-qt 极速连连看在界面上的特点: 1.支持更换主题 2.画面能够全部切换,基本不使用对话框等方式进行消息提示 3.使用的某些控件(如移动到上面发出声音的按钮.具 ...

  3. Qt版连连看之极速连连看:结构解析

    [github地址]speedlink-qt [源码结构说明] 本来想用Umbrello自动生成类图的,可惜不知道怎么的,我的源码导入之后Umbrello老是死掉,而我又不怎么会画UML图,只好画个概 ...

  4. 植物大战僵尸 PVZ Qt版

    前排提示:这是我花了两个星期写的QT版PVZ程序,时间比较紧,因此许多地方可能有不足,请见谅!在GitHub的代码没有注释,因为...即使有注释你也未必能看得懂 ,所以阅读代码前先看这篇文章. 源代码 ...

  5. c语言连连看实验报告,连连看C语言课程设计报告.doc

    连连看C语言课程设计报告 连连看 问题描述 连连看是一款简单有趣的小游戏,曾经风靡一时,玩家要将相同的两张牌用三根以内的直线连在一起就可以消除,规则简单容易上手,游戏速度节奏快,画面清晰可爱,适合细心 ...

  6. 北斗短报文一体机-Qt版(适用于Ubuntu和Windows)

    北斗短报文一体机-Qt版-适用于Ubuntu和Windows 本人有些原著作品是之前所写,由于当时没有做好记录,所以有些数据和图片都是最近补上的,同时有些结果都是当时所测的,现在有些都可能记不太清了, ...

  7. 如何成为java架构师?2023版Java架构师学习路线总结完成,真实系统有效,一切尽在其中

    导读 从初级Java工程师成长为Java架构师,你需要走很长的路,很多有计划的人在学习之初就在做准备.你知道Java架构师学习路线该怎么走吗?成为一个优秀的Java架构师究竟需要学什么?接下来就跟小编 ...

  8. alin的学习之路:嵌入式课程设计总结(基于Linux的Qt版MP3播放器)

    嵌入式课程设计总结(基于Linux的Qt版MP3播放器) 废话不多写直接上图上代码,其中有很多不规范的地方,希望大佬们指正. 1.课设题目 设计一个MP3播放器,要求:使用Linux下的madplay ...

  9. Qt版双人俄罗斯方块游戏

    Qt版双人俄罗斯方块游戏 转载请标明出处:牟尼的专栏 http://blog.csdn.net/u012027907     之前写过<VC版双人俄罗斯方块>,将其在Qt下又重写了一遍,核 ...

最新文章

  1. 使用JMX监控Kafka
  2. Application failure. hr=0x80040101:Failed to initialize virtual machine.
  3. 【POJ - 3694】Network(对dfn求lca 或 缩点+lca 或 边双连通+并查集)
  4. 不带parent指针的successor求解
  5. mongodb的条件查询笔记
  6. 纵横安卓刷机界的CM,如今转行做无人车了,还获得了加州路测许可
  7. 网站服务器系统组成,linux系统由哪几部分组成_网站服务器运行维护,linux
  8. 高程数据的下载以及运用高程数据进行坡度和坡向的计算
  9. 【数学建模】因子分析
  10. 2022年贵州二级建造师建设工程法规及相关知识模拟题及答案
  11. 2020-10-19 进制转换
  12. 【支线】基于Aidlux的Arduino小车
  13. lua认识(lua)中的变量
  14. Python3,区区5行代码,让黑白老照片变成华丽的彩色照,被吸粉了。
  15. access是用来干什么的_Access数据库是做什么的?
  16. 科技计算机作文200字,关于网络的作文200字(5篇)
  17. Unity3D RectTransform中文教程详细用法分析
  18. php 对字母排序,PHP按字母顺序排序
  19. RTX SDK Refrence RTXSDK教程之入门篇
  20. 《AI算法工程师手册》

热门文章

  1. 基于设计原理与理念和实践的ElasticSearch学习、ELK日志收集、网盘搜索引擎
  2. java 答题卡_阅读下列说明和java代码,将应填入(n)处的字句写在答题纸的对应栏内。【说明】 - 信管网...
  3. 什么是轨道镜动态投影技术
  4. Webapi添加token认证功能
  5. 利用爬虫和Django+echarts建立自己的动画人气统计小站
  6. Unity 开发中常见问题 Unity bug reporter
  7. LIO-SAM代码流程详解
  8. 一些常用的SCI论文句式 (1)
  9. unity2d实现一个全方位的无限随机地图
  10. 数据库系统--关系代数中笛卡尔积,选择,投影,自然连接,除运算