迷幻游戏背后的逻辑


12

在我正在做的原型中,有一个类似于宝石迷阵的迷你游戏。使用二维数组(int[,])的网格,如何知道用户何时形成比赛?我只关心水平和垂直方向。

我想着从头顶上往各个方向看。就像是:

int item = grid[x,y];
if(grid[x-1,y]==item)
{
    int step=x;
    int matches =2;
    while(grid[step-1,y]==item)
    {
        step++;
        matches++
    }
    if(matches>2)
        //remove all matching items
}
else if(grid[x+1,y]==item
    //....
else if(grid[x,y-1==item)
    //...
else if(grid[x,y+1]==item)
    //...

似乎应该有更好的方法。在那儿?


我记得我写了乏味的for循环来做到这一点(对于connect-n)
Ming-Tang

Answers:


6

循环遍历同一轴(x或y)中的每个项目,如果它们与上一个项目相同,则它们增量匹配。当下一项变得不同时,检查匹配项是否大于或等于3,调用一个删除匹配项的函数,然后继续。

AS3代码:

var grid:Array = [[2,3,2,2,2,4],
                  [ .. ]]; //multidimensional array
var matches:uint;
var gemType:uint;
for(col = 0; col < grid.length; col++){
    matches = 0;        
    gemType = 0; //Reserve 0 for the empty state. If we make it a normal gem type, then only 2 are needed to match for the start.
    for(i = 0; i < grid[0].length; i++){
        if(grid[col][i] == gemType){
            matches++;
        }
        if(grid[col][i] != gemType || i == grid[0].length - 1){ //subtract 1 because arrays start at 0
            if(matches >= 3){
                removeMatches(blah);
            }
            gemType = grid[col][i];
            matches = 1;
        }
    }
}

这仅适用于x轴,对于y,grid [col] [i]会变成grid [i] [row]等。我敢肯定,您可以弄清楚这一点:)


4

只是以为我会结合我们在开发类似Match-3的游戏中的经验。

我们为基于Match-3的文字游戏构建了原型,有点像将拼字游戏和Bejeweled混在一起。我们很早就意识到,提供新的宝石/瓷砖填充空白空间的引擎必须具有高度的内省性(我们运行混合启发法和MonteCarlo采样),以便为玩家创造实际的机会,使他们通过三消技工。它比描述要复杂得多,但是我要保持简短,因为我们必须写一篇论文。

为了回答OP问题,我们正在通过非常类似于“ gladoscc”代码段的方法,对模式进行检查,以对当前任何给定电网上的匹配项进行评分。尽管它运行稳定,但在树状搜索播放期间递归运行的计算成本成为一个沉重的负担,因此我们正在使用位板方法重写这部分逻辑和数据表示(通常在象棋,跳棋,奥赛罗等其他网格游戏中实现。)在测试中,我们证明了它在ActionScript中的运行速度可以提高20倍以上,因此对我们来说,这是灌篮-并释放了响应,声音,动画等基本循环。


3
您的答案应该是答案,而不是添加其他问题。如果您有任何疑问,请使用“提问”按钮创建一个新问题。这不是讨论论坛。
bummzack 2012年

1
bummzack ....谢谢你。我的理由是,我们有一个见识可以提供,特别是它与将树搜索/自省添加到上下文中时所提出的性能有关。由于我们仍在本质上谈论“宝石迷阵游戏背后的逻辑”,因此它仍然很重要。如果这种情况仍然很糟糕,我们将很乐意根据您的建议进行编辑/重新发布。
Wissam 2012年

2
没关系。但是您应该从答案中删除“问题”部分。问题应该是新问题,而不是答案的一部分……
bummzack 2012年

1
编辑和其他地方张贴的问题
的Wissam

2

递归,哟。当您不知道自己的界限时。

   public int getHMatchSize(int row, int column)
    {
        int returnMe = getMatchValue(row, 0, column, 1);

        if (returnMe < 3)
        {
            return 0;
        }
        else return returnMe;
    }


    public int getVMatchSize(int row, int column)
    {
        int returnMe = getMatchValue(row, 1, column, 0);

        if (returnMe < 3)
        {
            return 0;
        }
        else return returnMe;
    }

    /// <summary>
    /// I return the match size.
    /// </summary>
    /// <param name="row"></param>
    /// <param name="rowDelta">1 means look vertically.  Dont set both deltas to 1.</param>
    /// <param name="column"></param>
    /// <param name="columnDelta">1 means look horizontally.  Dont set both deltas to 1.</param>
    /// <returns>The number of contiguous matching things</returns>
    public int getMatchValue(int row, int rowDelta, int column, int columnDelta)
    {
        int[] start = getEndItem(row, -1 * rowDelta, column, -1 * columnDelta);
        int[] end = getEndItem(row, rowDelta, column, columnDelta);

        int returnMe = 0;
        returnMe += end[0] - start[0];
        returnMe += end[1] - start[1];
        return returnMe;
    }

    /// <summary>
    /// I will return the end of a sequence of matching items.
    /// </summary>
    /// <param name="row">start here</param>
    /// <param name="column">start here</param>
    private int[] getEndItem(int row, int rowDelta, int column, int columnDelta)
    {
        Gem matchGem = new Gem(-1);
        int[] returnMe = new int[2];

        if (boardSpace[row + rowDelta][column + columnDelta] == boardSpace[row][column])
        {
            return getEndItem(row + rowDelta, rowDelta, column + columnDelta, columnDelta);
        }
        else
        {
            returnMe[0] = row;
            returnMe[1] = column;
            return returnMe;
        }
    }

0

您可以使用洪水填充算法。这种类型的问题确实有用。


1
不,实际上与问题无关。OP正在询问如何连续检测三个匹配项。
独眼巨人

2
如果从翻转的元素开始填充,则算法将遍历匹配的元素。但是仅检查连续3个(并且没有更多)匹配元素(并且没有交叉列),这可能是一个过大的杀伤力。我们在诸如游戏之类的泡泡拼图中使用它,并且完全满足我们的需求。
ktornai 2011年

2
您可能应该解释的不只是“使用洪水填充”,因为我困惑了一秒钟,这与这个问题有何关系。
2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.