“宝石迷阵”中游戏算法实现

【qboy】原创 2013年3月10日

  最近有一个想法就是把以前做过我东西都把他以博客的形式写出来,不管对不对,让各位大牛们指点指点。本来想先写”水管猫“的,后来想想先写”宝石迷阵“吧。

一、游戏背景

  玩过《宝石迷阵》游戏的人都知道,这其实是一款很简单的游戏。通过交换相临的两个元素(或者叫宝石,以下统一为元素),以便实现在行或者列中达到相同元素在3个或者3个以上,从迷阵中消去,并补充消去元素,这就是《宝石迷阵》类游戏的核心玩法。所有的该类游戏的玩法都是以上的变形,例如增加道具消去一行一纵、消去相同类元素等,这就看各个游戏策划人员如何去策划了。

  下图就是一个简单的《宝石迷阵》,用数字代表不同的元素。

二、游戏中的算法

  我不是一个游戏的策划人员,游戏的外围在此我就不多说了。

     整个游戏的流程应该如下图所示:

整个游戏的核心都在那几次判断中。接下去我一把这几次的判断方法进行描述:
1、是否在在可消去元素
     这只要在游戏地图中(用二维数组表示),遍历每行和每列是否存在相邻元素达到三个或者三个以上的。为了避免重复,我们规定只向右和向下判断。代码如下:
-(NSMutableArray *)getWinStoneInMap
{
    NSMutableArray *arr=[NSMutableArray array];
    
    for (int i = 0; i<hCount; i++) {
        for (int j = 0; j<wCount;j++) {
            StoneSprite * curStone = stoneArr[i][j];
            StoneType curType =curStone.StoneType;
            //向右
            int k = j+1;
            if (k<wCount) {
                for (; k<wCount; k++) {
                    if (curType != stoneArr[i][k].StoneType) {
                        break;
                    }
                }
                if (k-j>=3) {//相同的元素是否大于3个
                    for (int m = j; m<k; m++) {
                        if (![arr containsObject:stoneArr[i][m]]) {
                            [arr addObject:stoneArr[i][m]];
                        }
                    }
                }
            }
            
            //向下
            k = i+1;
            
            if(k<hCount)
            {
                for (; k<hCount; k++) {
                    if (curType !=stoneArr[k][j].StoneType) {
                        break;
                    }
                }
                if (k-i>=3) {
                    for (int n = i; n<k; n++) {
                        if (![arr containsObject:stoneArr[n][j]]) {
                            [arr addObject:stoneArr[n][j]];
                        }
                    }
                }
            }
        }
    }
    return arr;
}
 
2、判断是否存在可移动元素
 
在这个方法中,当初为了简单,只是对上面的方法进行了一下调用。首先交换一下相邻元素,再调用上面的方法,有则返回true,无则继续。
-(bool)checkHasMove
{
    StoneSprite *temp;
    
    bool hasmove = false;
    for (int i = 0; i<hCount && !hasmove; i++) {
        for (int j = 0; j<wCount &&!hasmove; j++) {
            if (j<wCount-1) {//与右边的进行交换
                temp = stoneArr[i][j];
                stoneArr[i][j]=stoneArr[i][j+1];
                stoneArr[i][j+1] = temp;
                
                NSMutableArray *arr = [self getWinStoneInMap]; 
                
                temp = stoneArr[i][j];
                stoneArr[i][j]=stoneArr[i][j+1];
                stoneArr[i][j+1] = temp;
                
                if ([arr count] > 0) {
                    hasmove = YES;
                    break;
                }
            }
            if (i<hCount-1) {//与下面的进行交换
                temp = stoneArr[i][j];
                stoneArr[i][j]=stoneArr[i+1][j];
                stoneArr[i+1][j] = temp;
                
                NSMutableArray *arr = [self getWinStoneInMap]; 
                
                temp = stoneArr[i][j];
                stoneArr[i][j]=stoneArr[i+1][j];
                stoneArr[i+1][j] = temp;
                
                if ([arr count] > 0) {
                    hasmove = YES;
                    break;
                }
            }
        }
    }
    
    return hasmove;
}
三、不完善之处
 
        在整个游戏中,很多地方都进行了整个游戏地图的遍历。但是这有些时候并没有必要这么做,比如在交换之后,我们只需要判断交换元素所在的行与列,这对游戏的遍历效率应该会有很大的提高。
posted @ 2013-03-10 14:42  qboy2010  阅读(1562)  评论(1编辑  收藏  举报