cocos2d-x3.6 连连看连通算法
发布时间:2020-12-14 21:37:26 所属栏目:百科 来源:网络整理
导读:我的博客:http://blog.csdn.net/dawn_moon 上一章讲了连连看游戏的主要逻辑,连通算法并有讲如何实现。 这个连连看没有使用广度优先搜索算法,采用的是一种比较有技巧的算法,参见前面章节。 大致分为几个部分: 直连通 两个点X轴扩展后可以直连通 两个点Y
我的博客:http://blog.csdn.net/dawn_moon 上一章讲了连连看游戏的主要逻辑,连通算法并有讲如何实现。 这个连连看没有使用广度优先搜索算法,采用的是一种比较有技巧的算法,参见前面章节。 大致分为几个部分:
看下连接函数 bool GameScene::link(cocos2d::Vec2 v1,cocos2d::Vec2 v2)
{
if (v1.equals(v2)) {
return false;
}
// 路径点集,是一个vector
mPath.clear();
// 判断点击的两个点是不是图案一致
if (mMap[(int)v1.x][(int)v1.y] == mMap[(int)v2.x][(int)v2.y]) {
// 直连
if (linkD(v1,v2)) {
mPath.push_back(v1);
mPath.push_back(v2);
return true;
}
// 一个拐角,对角可直连
auto p = Vec2(v1.x,v2.y);
if (mMap[(int)p.x][(int)p.y] == 0) {
if (linkD(v1,p) && linkD(p,v2)) {
mPath.push_back(v1);
mPath.push_back(p);
mPath.push_back(v2);
return true;
}
}
// 一个拐角,对角可直连
p = Vec2(v2.x,v1.y);
if (mMap[(int)p.x][(int)p.y] == 0) {
if (linkD(v1,v2)) {
mPath.push_back(v1);
mPath.push_back(p);
mPath.push_back(v2);
return true;
}
}
// X扩展,判断是否有可直连的点
expandX(v1,p1E);
expandX(v2,p2E);
for (auto pt1 : p1E) {
for (auto pt2 : p2E) {
if (pt1.x == pt2.x) {
if (linkD(pt1,pt2)) {
mPath.push_back(v1);
mPath.push_back(pt1);
mPath.push_back(pt2);
mPath.push_back(v2);
return true;
}
}
}
}
// Y扩展,判断是否有可直连的点
expandY(v1,p1E);
expandY(v2,p2E);
for (auto pt1 : p1E) {
for (auto pt2 : p2E) {
if (pt1.y == pt2.y) {
if (linkD(pt1,pt2)) {
mPath.push_back(v1);
mPath.push_back(pt1);
mPath.push_back(pt2);
mPath.push_back(v2);
return true;
}
}
}
}
return false;
}
return false;
}
连通函数的基础是直连通,两个点,最后都要转化成是否可直连,来看这个函数: bool GameScene::linkD(Vec2 v1,Vec2 v2)
{
// X坐标一致,逐个扫描Y坐标,中间如果都是通路,那么可以直连
if (v1.x == v2.x) {
int y1 = MIN(v1.y,v2.y);
int y2 = MAX(v2.y,v2.y);
bool flag = true;
for (int y = y1 + 1; y < y2; y++) {
if (mMap[(int)v1.x][y] != 0) {
flag = false;
break;
}
}
if (flag) {
return true;
}
}
// Y坐标一致,逐个扫描X坐标,中间如果都是通路,那么可以直连
if (v1.y == v2.y) {
int x1 = MIN(v1.x,v2.x);
int x2 = MAX(v1.x,v2.x);
bool flag = true;
for (int x = x1 + 1; x < x2; x++) {
if (mMap[x][(int)v1.y] != 0) {
flag = false;
break;
}
}
if (flag) {
return true;
}
}
return false;
}
注意这里的坐标都是地图坐标,就是第几格第几格这样的整数。 再来看下扩展函数: void GameScene::expandX(Vec2 v,std::vector<Vec2> &vector)
{
// 注意第二个参数vector是传的引用
vector.clear();
// X轴扩展到边界,如果都是空的就将扩展的点放入容器
for (int x = (int)v.x + 1; x < xCount; x++) {
if (mMap[x][(int)v.y] != 0) {
break;
}
vector.push_back(Vec2(x,(int)v.y));
}
// Y周扩展到边界,如果都是空的就将扩展的点放入容器
for (int x = (int)v.x - 1; x >= 0; x--) {
if (mMap[x][(int)v.y] != 0) {
break;
}
vector.push_back(Vec2(x,(int)v.y));
}
}
void GameScene::expandY(Vec2 v,std::vector<Vec2> &vector)
{
vector.clear();
for (int y = (int)v.y + 1; y < yCount; y++) {
if (mMap[(int)v.x][y] != 0) {
break;
}
vector.push_back(Vec2((int)v.x,y));
}
for (int y = (int)v.y - 1; y >= 0 ; y--) {
if (mMap[(int)v.x][y] != 0) {
break;
}
vector.push_back(Vec2((int)v.x,y));
}
}
注意这两个函数的第二个参数是传引用,为什么要这样做。 连通函数会判断两个点是否连通,如果连通,讲连通的点放入容器,后续会用这个容器里的点来绘制连通路线。 下一节讲如何画线。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- 如何使用log miner分析oracle日志
- objective-c – NSMutableArray – 如何访问
- react native Exception in thread "main" java
- objective-c – GCRectMake的iOS错误 – 将’int’发送到不
- c# – 如何对使用OWIN Cookie Authenthication的代码进行单
- ruby-on-rails – 具有ActiveAdmin和Rails 4的多个HABTM属性
- c – Printf和Array
- NoSQL架构实践(一)——以NoSQL为辅
- dwr的使用
- Pipeline Pattern