连连看算法

来源:互联网 发布:混沌之戒3修改存档数据 编辑:程序博客网 时间:2024/05/22 03:33

以前玩连连看游戏的时候就很好奇连连看的实现,后来一直没去深入研究过。最近正好看了看一些连连看游戏的小Demo,记录一下连连看的算法,以后用起来的时候也好找。

这里用的资源图片是从泰然网下载的游戏源码中的图片,将链接放上来,以免被追究责任。。。。。

http://bbs.tairan.com/forum.php?mod=viewthread&tid=8723&extra=page%3D1%26filter%3Dtypeid%26typeid%3D143


连连看游戏的玩法就是查看2个方块之间是否能够用3根以内的直线连接起来(直线上没有任何方块阻碍)。


连连看的算法简单说起来就是3步:

1. 看A和B之间是否能够用一条直线连接,假设check_line(A, B)函数就是查看是否能够一条直线连接的。

那么check_line的伪代码大概就是这样:

bool check_line(A, B)
{
    if (A.x == B.x)
    {
        for (C = A.y to B.y)
        {
            if (!isEmpty(C))
            {
                return false;
            }
        }
    }
    else if (A.y == B.y)
    {
        for (C = A.x to B.x)
        {
            if (!isEmpty(C))
            {
                return false;
            }
        }
    }
    return false;
}

就是说A和B的x和y坐标至少有一个相同,然后遍历A和B之间的所有方块,如果每一个都是空的,那么A和B就能够消除,否则就不能消除。

如图:



2. 看A和B之间是否存在C,C点没有方块,并且A和C、B和C之间都能够直线连接,如图:


因为C和A、B要直线连接,所以C必须在AB组成的矩形的另外两个角上,即上图的C和D的位置。

check_two_line()伪代码如下:

bool check_two_line(A, B)
{
    C = (A.x, B.y);
    if (check_line(A, C) and check_line(B, C))
    {
        return true;
    }
    D = (B.x, A.y);
    if (check_line(A, D) and check_line(B, D))
    {
        return true;
    }
    return false;
}

3. 从A的上下左右四个方向中的一个方向查找,如果遇到空方块,就查看该点C是否能和点B两线连接,即check_two_line(B, C)。如果遇到方块不是空的,那么就结束该方向的查找。

这样依次遍历上下左右四个方向,如果有任一一个方块满足,就能够消除。

check_three_line()伪代码如下:

bool check_three_line(A, B)
{
    for (C = A in direction x+)
    {
        if (!isEmpty(C))
        {
            break;
        }
        else
        {
            if (check_two_line(B, C))
            {
                return true;
            }
        }
    }
    
    for (C = A in direction x-)
    {
        if (!isEmpty(C))
        {
            break;
        }
        else
        {
            if (check_two_line(B, C))
            {
                return true;
            }
        }
    }
    
    for (C = A in direction y+)
    {
        if (!isEmpty(C))
        {
            break;
        }
        else
        {
            if (check_two_line(B, C))
            {
                return true;
            }
        }
    }
    
    for (C = A in direction y-)
    {
        if (!isEmpty(C))
        {
            break;
        }
        else
        {
            if (check_two_line(B, C))
            {
                return true;
            }
        }
    }
}

下图是从x-方向遍历,查找到C的情况:



注意,这里还有个小技巧,像上图的A、B方块是在整个图的最边沿上,A的x-方向没有方块了怎么办?

一般在连连看的所有可见方块的最外层,有一层空方块,那样就保证了看起来最外层的方块(实际上不是最外层)还能向上下左右4个方向延伸。

如下图所示:


0 0