Логика игры, похожей на драгоценности

12

В прототипе, который я делаю, есть мини-игра, похожая на bejeweled. Используя сетку, которая является двумерным массивом ( 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)
    //...

Кажется, должен быть лучший способ. Есть?


источник
Я вспомнил, что написал утомительный цикл, чтобы сделать это (для connect-n)
Ming-Tang

Ответы:

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] и т. Д. Я уверен, что вы можете понять это :)

apscience
источник
4

Подумал, что я подумаю о нашем опыте создания игры в стиле Match-3.

Мы создали прототип для основанной на Match-3 игры в слова, немного напоминающей скрэббл и Bejeweled. Мы очень рано поняли, что движок, который поставляет новые драгоценные камни / плитки для заполнения пустых пространств, должен быть очень интроспективным (мы запускаем гибридную эвристику и выборку по методу Монте-Карло), чтобы дать игроку реальную возможность струнных букв формировать слова через слова. Матч-3 механик. Это намного сложнее, чем описание, но я держу его кратким, потому что нам нужно написать статью.

Чтобы ответить на OP - мы выполняем проверки шаблонов, чтобы подсчитать, сколько совпадений имеется в любом заданном наборе в текущий момент, с помощью метода, очень похожего на фрагмент кода "gladoscc". Хотя он работает надежно, вычислительные затраты на рекурсивный запуск во время воспроизведения поиска по дереву становятся существенным бременем, поэтому мы находимся в процессе переписывания этой части логики и представления данных с помощью методологии «битовая доска» ( обычно реализуется в других сетках, таких как игры, такие как шахматы, шашки, Отелло и т. д.) В тестах мы показали, что он может работать в 20 раз быстрее в ActionScript, и поэтому для нас это нужно делать - это хлопотник - и освобождает необходимые циклы для отзывчивости, звука, анимации и т. д.

Виссам
источник
3
Ваш ответ должен быть ответом, а не добавлять другой вопрос. Если у вас есть вопрос, создайте новый вопрос, используя кнопку «ЗАДАТЬ ВОПРОС». Это не дискуссионный форум.
Bummzack
1
бумзак .... спасибо за это. Мое обоснование состояло в том, что у нас было понимание, особенно в том, что касается производительности того, что было предложено ранее, когда в контекст был добавлен поиск по дереву / самоанализ. И это продолжало быть актуальным, поскольку мы по-прежнему говорим по существу о «логике игры Bejeweled». Если это по-прежнему будет дурным тоном, я буду рад отредактировать / повторно опубликовать его согласно вашему совету.
Wissam
2
Все в порядке. Но вы должны удалить часть «вопрос» из вашего ответа. Вопросы должны быть новыми, а не частью ответа ...
bummzack
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;
        }
    }
Arconom
источник
0

Вы можете использовать алгоритм заливки . Это действительно полезно для такого типа проблемы.

ktornai
источник
1
Нет, на самом деле это не имеет ничего общего с Вопросом. ОП спрашивает, как обнаружить три подходящих элемента подряд.
Циклоп
2
Если вы начнете заливку с перевернутого элемента (ов), алгоритм пройдет через соответствующие элементы. Но просто проверить 3 (и не более) совпадающих элемента подряд (и не пересекая столбцы), это может быть излишним. Мы используем это в Bubble Puzzle, как игра, и делаем именно то, что нам нужно.
ktornai
2
Возможно, вам следует объяснить немного больше, чем просто «использовать заливку», потому что я на секунду смутился, как это относится к этой проблеме.
jhocking