`

Android游戏开发之连连看算法

阅读更多

因为有朋友在站内信中问到连连看的具体算法,所以我就把算法post出来,这个算法也是参考网上Flash游戏的算法改写的,原来的参考信息已经找不到了,不过非常感谢那些无私的朋友。

 

改写的连连看算法如下:

前置条件:用一二维数组存放Map,-1表示没有图案可以连通,非-1表示不同的图案。

首先是横向检测:

 

	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,直接返回false
	            if(map[a.x][x] != -1){
	                return false;
	            }
	        return true;
	    }

 其次是纵向检测:

 

    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两点。其中C点的横坐标和A相同,纵坐标与B相同,D的横坐标与B相同,纵坐标与A相同。

 

    private boolean oneCorner(Point a, Point b)
    {
        Point c = new Point(a.x, b.y);
        Point d = new Point(b.x, a.y);
        if(map[c.x][c.y] == -1)
        {
            boolean method1 = horizon(a, c) && vertical(b, c);
                return method1;
        }
        if(map[d.x][d.y] == -1)
        {
            boolean method2 = vertical(a, d) && horizon(b, d);
            return method2;
        } else
        {
            return false;
        }
    }

 两个拐角的检测:

这个比较复杂,如果两个拐角能连通的话,则必须存在图中所示的连线,这些连线夹在A、B的横、纵坐标之间,这样的线就以下这个类存储,direct是线的方向,用0、1表示不同的方向

LIne类结构如下:

 

class Line
    {
        public Point a;
        public Point b;
        public int direct;

        public Line()
        {
        }

        public Line(int direct, Point a, Point b)
        {
            this.direct = direct;
            this.a = a;
            this.b = b;
        }
    }

 

从A、B点的横纵两个方向进行扫描,就是Scan函数做的事情,把合适的线用LinkList存起来。

 

	private LinkedList scan(Point a, Point b)
	    {
	        ll = new LinkedList<Line>();
	        //Point c = new Point(a.x, b.y);
	        //Point d = new Point(b.x, a.y);
	        for(int y = a.y; y >= 0; y--)
	            if(map[a.x][y] == -1 && map[b.x][y] == -1 && vertical(new Point(a.x, y), new Point(b.x, y)))
	                ll.add(new Line(0, new Point(a.x, y), new Point(b.x, y)));
	
	        for(int y = a.y; y < map.row; y++)
	            if(map[a.x][y] == -1 && map[b.x][y] == -1 && vertical(new Point(a.x, y), new Point(b.x, y)))
	                ll.add(new Line(0, new Point(a.x, y), new Point(b.x, y)));
	
	        for(int x = a.x; x >= 0; x--)
	            if(map[x][a.y] == -1 && map[x][b.y] == -1 && horizon(new Point(x, a.y), new Point(x, b.y)))
	                ll.add(new Line(1, new Point(x, a.y), new Point(x, b.y)));
	
	        for(int x = a.x; x < map.column; x++)
	            if(map[x][a.y] == -1 && map[x][b.y] == -1 && horizon(new Point(x, a.y), new Point(x, b.y)))
	                ll.add(new Line(1, new Point(x, a.y), new Point(x, b.y)));
	
	        return ll;
	  }

 最后是两个拐角的算法:

 取出LinkList里面的线,测试A与B到该线的两点是否连通。

    private boolean twoCorner(Point a, Point b)
    {
        ll = scan(a, b);
        if(ll.isEmpty())
            return false;
        for(int index = 0; index < ll.size(); index++){
            Line line = (Line)ll.get(index);
            if(line.direct == 1){
                if(vertical(a, line.a) && vertical(b, line.b)){
                    return true;
                }

            } else
            if(horizon(a, line.a) && horizon(b, line.b)){
                return true;
            }
        }
        return false;
    }

 前面的函数有以下这个总的调用函数来调用,传入两个点,就可以判断这两个点是否符合连连看的算法了:

	public boolean checkLink(Point a,Point b){
		if(map[a.x][a.y] != map[b.x][b.y])//如果图案不同,直接为false
            return false;
        if(a.x == b.x && horizon(a, b))
            return true;
        if(a.y == b.y && vertical(a, b))
            return true;
        if(oneCorner(a, b))
            return true;
        else
            return twoCorner(a, b);
	}

 

分享到:
评论
23 楼 lujl1988 2010-09-15  
假如你的地图是8*10的,
sinye 写道
楼主,你的那个横向检测方法,在其中取x值范围区间的时候,我看的有些不明白。横向检测的时候,A点和B点的y坐标是相同的,是否应该
int x_start = a.x <= b.x ?a.x : b.x;  
int x_end = a.x <= b.x ? b.x : a.x;
这样横向时,可以取得A点和B点中间的点的坐标!望指导一二!

我也有同样的疑问,还望楼主指点一二
22 楼 dxq530610286 2010-04-16  
太激动了  好东西啊   回去也学习写一个
21 楼 sinye 2010-04-02  
楼主,你的那个横向检测方法,在其中取x值范围区间的时候,我看的有些不明白。横向检测的时候,A点和B点的y坐标是相同的,是否应该
int x_start = a.x <= b.x ?a.x : b.x;  
int x_end = a.x <= b.x ? b.x : a.x;
这样横向时,可以取得A点和B点中间的点的坐标!望指导一二!
20 楼 HEXLee 2009-10-14  
BZ写的很细致,我也写了一个连连看算法,BZ也到我的博客去看看哈~
我也喜欢游戏制作,希望加我好友QQ81539637
19 楼 wtotal 2009-10-10  
bengan 写道
raymondlueng 写道
bengan 写道
可以介紹下連連看遊戲場景生成的算法嘛?怎麼確保生成遊戲場景不是一出來就是死胡同

假如你的地图是8*10的,游戏中一共有80个图案,又假如图案的种类有10种,则可以定义每种图案8个的8*10的二维数组,然后将数组打乱,那这样的生成的场景就是可配对的了。
另外,有可能生成的地图刚好每一个都不能连通的,这就要做一个CheckAvailable()函数,因为连连看中都会有提示功能,CheckAvailable()函数调用提示功能的函数,利用其返回值就可以知道游戏能不能玩了,能玩就继续,不能玩就以某种方式对地图重新排列。

能否再講解一下CheckAvailable()函数的實現呢。我怕會有這樣一種情況,地圖連第一個是可以一直到了第10個才發現到了死胡同,這種情況你現在是怎麼處理呢?


到第10个发现玩不下去可以gameover或重排嘛。
18 楼 bengan 2009-10-07  
raymondlueng 写道
bengan 写道
可以介紹下連連看遊戲場景生成的算法嘛?怎麼確保生成遊戲場景不是一出來就是死胡同

假如你的地图是8*10的,游戏中一共有80个图案,又假如图案的种类有10种,则可以定义每种图案8个的8*10的二维数组,然后将数组打乱,那这样的生成的场景就是可配对的了。
另外,有可能生成的地图刚好每一个都不能连通的,这就要做一个CheckAvailable()函数,因为连连看中都会有提示功能,CheckAvailable()函数调用提示功能的函数,利用其返回值就可以知道游戏能不能玩了,能玩就继续,不能玩就以某种方式对地图重新排列。

能否再講解一下CheckAvailable()函数的實現呢。我怕會有這樣一種情況,地圖連第一個是可以一直到了第10個才發現到了死胡同,這種情況你現在是怎麼處理呢?
17 楼 raymondlueng 2009-10-02  
变精华帖了,太感动了!
16 楼 xuhuiflygo 2009-09-30  
真的很不错。
15 楼 tedeyang 2009-09-30  
留名待查。。。。。
14 楼 raymondlueng 2009-09-30  
bengan 写道
可以介紹下連連看遊戲場景生成的算法嘛?怎麼確保生成遊戲場景不是一出來就是死胡同

假如你的地图是8*10的,游戏中一共有80个图案,又假如图案的种类有10种,则可以定义每种图案8个的8*10的二维数组,然后将数组打乱,那这样的生成的场景就是可配对的了。
另外,有可能生成的地图刚好每一个都不能连通的,这就要做一个CheckAvailable()函数,因为连连看中都会有提示功能,CheckAvailable()函数调用提示功能的函数,利用其返回值就可以知道游戏能不能玩了,能玩就继续,不能玩就以某种方式对地图重新排列。
13 楼 bengan 2009-09-30  
可以介紹下連連看遊戲場景生成的算法嘛?怎麼確保生成遊戲場景不是一出來就是死胡同
12 楼 zst504 2009-09-30  
谢谢楼主了!!
11 楼 hehawjq 2009-09-30  
多谢分享……
10 楼 lzyzizi 2009-09-30  
我记得我们站有个JS的连连看,那个算法好像也不错,有兴趣的可以参考下。
9 楼 superhanliu 2009-09-30  
不错。。学习学习。。谢谢分享。。
8 楼 lovesun723 2009-09-30  
楼主新帖,学习来了
7 楼 DoubleEO 2009-09-29  
谢谢,正在学习
6 楼 alexma 2009-09-29  
楼主,看了一下算法,感觉 two corner 的逻辑其实已经包含了 one corner 的情况了。总控函数只要调用一次 twocorner 就够了吧。
5 楼 lucane 2009-09-29  
两个拐角的检测就弄不明白了
4 楼 mikeshi 2009-09-29  
收藏了,以后有空仔细看看,谢谢楼主的无私奉献

相关推荐

    Android小游戏连连看源码

    本文将深入探讨Android版连连看的源码,帮助初学者理解Android游戏开发的基本流程和关键技术。 连连看游戏的核心在于其逻辑算法,主要包括两部分:游戏初始化和游戏逻辑判断。首先,源码中的`GameActivity`通常会...

    Android开发连连看游戏

    在Android平台上开发一款连连看游戏,需要掌握一系列的编程技术和设计思路。连连看游戏的核心玩法是寻找并消除一对相同的图片,直到所有配对都被消除。下面将详细讲解开发这样一款游戏涉及的关键知识点。 1. **...

    android 连连看算法

    根据提供的信息,我们可以深入探讨“连连看”游戏中的核心算法,并着重分析其在Android平台上的实现方式。连连看是一款非常受欢迎的休闲益智类游戏,玩家的目标是通过连接两个相同图案的方块来消除它们,而连接的...

    android游戏连连看源码

    本文将深入探讨一款基于Android开发的“连连看”游戏的源码,帮助读者理解Android游戏开发的基本流程和核心技术。 连连看,作为一款深受玩家喜爱的经典休闲游戏,其核心玩法是通过寻找并消除两个相同图案的方块,...

    Android项目源码动物连连看

    本项目是一款android连连看游戏,应该说这个游戏太强大了,能触屏连连看,过关。用到技术很多,有小算法,相同的icon就会消掉项目中代码层次分明,大部分方法都加了详细的注释。(项目采用GBK编码)。之前也有很多...

    Android成语连连看游戏项目源代码

    在Android开发中,一个完整的应用通常包括以下几个部分:UI设计、逻辑处理、数据存储以及资源管理等。对于"Android成语连连看",我们可以深入探讨以下关键知识点: 1. **UI设计**:游戏界面通常采用XML布局文件来...

    android系统开发的小游戏,连连看

    以下是对Android系统开发连连看游戏的一些关键知识点的详细解释: 1. **Android Studio和SDK**: 开发Android应用的基础是使用Android Studio,这是一个集成开发环境(IDE),包含了必要的工具和库。开发者需要安装...

    android开发的海贼王连连看游戏

    《Android开发的海贼王连连看游戏》 在Android平台上,开发一款海贼王主题的连连看游戏,是一项集趣味性、技术性于一体的挑战。这款游戏中,开发者将海贼王的角色、元素融入到了传统的连连看玩法中,为玩家带来了...

    Android连连看游戏源码

    虽然游戏界面相对简洁,但其核心逻辑和算法设计是完整的,为开发者提供了一个良好的学习起点,特别是对于那些想要了解Android游戏开发或者对连连看游戏逻辑感兴趣的程序员。 首先,我们要理解连连看游戏的基本规则...

    Android 连连看源码

    总的来说,通过研究这个"Android 连连看源码",开发者不仅可以提升Android应用开发的技能,还能深入学习到游戏开发的相关知识,如图形界面设计、算法实现、资源管理以及时间同步等,这对于个人技术成长和项目实践...

    android连连看游戏实现

    开发连连看游戏,首先要设计游戏的用户界面(UI)。在Android中,UI通常由XML布局文件定义,可以使用LinearLayout、RelativeLayout、GridLayout等布局管理器来排列各个游戏元素,如游戏棋盘、计时器、分数显示等。...

    Android游戏连连看源代码

    本文将深入探讨一款基于Android平台的“连连看”游戏的源代码,帮助开发者了解Android游戏开发的基本原理和技巧。 首先,我们要明白“连连看”是一款简单却极具挑战性的益智游戏,它的核心玩法是寻找并消除两个相同...

    android 游戏类似于连连看Android源码

    在Android开发中,源代码是开发者探索和理解软件工作原理的直接途径。通过对源代码的学习,开发者可以了解到如何在Android平台上构建游戏,如何使用Java或Kotlin编程语言实现游戏逻辑,以及如何利用Android SDK中的...

    水果连连看Android游戏源码

    总的来说,分析"水果连连看"Android游戏源码,可以帮助我们深入理解Android应用开发中的图形用户界面设计、事件处理、数据结构、算法应用、多线程通信以及性能优化等多个方面,对于提升Android开发技能具有很高的...

    android连连看游戏代码

    在Android平台上,开发一款连连看游戏可以为用户提供轻松娱乐的体验。这个名为"android连连看游戏代码"的项目,是基于Rokon游戏引擎构建的。Rokon是一款开源的游戏开发框架,它允许开发者使用Java语言快速创建2D游戏...

    Android水果连连看游戏源码

    通过深入研究这个Android水果连连看游戏源码,你可以全面提升Android开发技能,从基本的UI设计到复杂的逻辑实现,再到用户体验的优化,都能得到实战经验。同时,对于毕业设计或项目练习,这是一个很好的起点。

    android连连看游戏源码

    通过对"android连连看游戏源码"的分析,我们可以学习到Android游戏开发的基本框架、图形界面设计、事件处理以及算法应用等多个方面的知识。 首先,Android游戏开发通常基于Java语言,结合Android SDK和Android ...

    android游戏-连连看

    下面,我们将深入探讨在Android环境下开发连连看游戏的相关知识点。 首先,我们需要了解Android Studio,这是Google官方推荐的Android应用开发集成开发环境(IDE)。Android Studio提供了丰富的工具和库,方便...

    Android游戏-疯狂连连看

    总的来说,"疯狂连连看"作为一款Android游戏,涵盖了Android开发的多个方面,包括但不限于UI设计、游戏逻辑实现、音视频处理、数据存储和性能优化。对于初、中级程序员来说,学习这款游戏的源码将是一次全面深入的...

Global site tag (gtag.js) - Google Analytics