Logika gry podobnej do bejeweled

12

W prototypie, który robię, jest mini-gra podobna do bejeweled. Używając siatki, która jest tablicą 2d ( int[,]), skąd mam wiedzieć, kiedy użytkownik utworzył dopasowanie? Dbam tylko o poziomo i pionowo.

Z czubka głowy myślałem, że po prostu spojrzę w każdym kierunku. Coś jak:

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)
    //...

Wydaje się, że powinien istnieć lepszy sposób. Jest tu?


źródło
Pamiętam, że napisałem żmudną pętlę, aby to zrobić (dla połączenia-n)
Ming-Tang

Odpowiedzi:

6

Pętlę przez każdy element na tej samej osi (x lub y), jeśli są one takie same jak poprzedni element, zwiększają liczbę pasujących elementów. Gdy następny element stanie się inny, sprawdź, czy dopasowania są większe niż 3, wywołaj funkcję, która usuwa pasujące elementy i kontynuuj.

Kod 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;
        }
    }
}

To jest tylko dla osi x, dla y, grid [col] [i] zmieni się w grid [i] [row] itp. Jestem pewien, że możesz to rozgryźć :)

apscience
źródło
4

Pomyślałem, że skorzystam z naszego doświadczenia w tworzeniu gry typu „Dopasuj 3”.

Zbudowaliśmy prototyp gry słownej opartej na dopasowaniu 3, trochę jak zebranie scrabble i Bejeweled. Bardzo wcześnie zdaliśmy sobie sprawę, że silnik, który dostarcza nowe klejnoty / kafelki do wypełnienia pustych miejsc, musiałby być wysoce introspektywny (prowadzimy heurystykę hybrydową i próbkowanie MonteCarlo), aby stworzyć graczowi rzeczywiste możliwości ciągnięcia liter w celu tworzenia słów przez Mechanik Match-3. Jest o wiele bardziej skomplikowany niż opis, ale krótko mówiąc, bo musielibyśmy napisać artykuł.

Aby odpowiedzieć na OP - przeprowadzamy sprawdzanie wzorca, aby ocenić, ile pasowań jest w danym momencie, za pomocą metody bardzo podobnej do fragmentu kodu „gladoscc”. Choć działa solidnie, koszt obliczeniowy związany z uruchomieniem rekurencyjnym podczas odtwarzania wyszukiwania drzewa staje się znaczącym obciążeniem, dlatego jesteśmy w trakcie przepisywania tej części logiki i reprezentacji danych przy użyciu metodologii tablicy bitów ( powszechnie zaimplementowane w grach innych niż grid, takich jak szachy, warcaby, Othello itp.) W testach pokazaliśmy, że może on działać ponad 20 razy szybciej w ActionScript, więc dla nas potrzeba wykonania tego jest bardzo prosta - i uwalnia niezbędne cykle dla reakcji, dźwięku, animacji itp.

Wissam
źródło
3
Twoja odpowiedź powinna być odpowiedzią i nie dodawać kolejnego pytania. Jeśli masz pytanie, utwórz nowe pytanie za pomocą przycisku „ZADAJ PYTANIE”. To nie jest forum dyskusyjne.
bummzack
1
bummzack .... dziękuję za to. Moim uzasadnieniem było to, że mieliśmy wgląd w to, co dotyczy, zwłaszcza, że ​​odnosi się ono do wydajności tego, co zaproponowano wcześniej, gdy do kontekstu dodano wyszukiwanie drzewa / introspekcję. I nadal było to istotne, ponieważ nadal mówimy zasadniczo o „Logice stojącej za grą Bejeweled”. Jeśli nadal będzie to zły format, z przyjemnością dokonam edycji / ponownej publikacji zgodnie z twoją radą.
Wissam
2
W porządku. Ale powinieneś usunąć część odpowiedzi na pytanie. Pytania powinny być nowymi pytaniami, a nie częścią odpowiedzi ...
bummzack,
1
zredagował i opublikował pytanie w innym miejscu
Wissam,
2

Rekurencja, yo. Jest tak, gdy nie znasz swoich granic.

   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
źródło
0

Możesz użyć algorytmu wypełniania zalania . Jest to naprawdę przydatne w tego rodzaju problemach.

ktornai
źródło
1
Nie, w rzeczywistości nie ma to nic wspólnego z pytaniem. OP pyta, jak wykryć trzy pasujące elementy z rzędu.
Cyklop
2
Jeśli zaczniesz wypełniać przerzuconymi elementami, algorytm przejdzie przez pasujące elementy. Ale aby sprawdzić 3 (i nie więcej) pasujący element w rzędzie (i bez krzyżowania kolumn), może to być przesada. Używamy tego w grze typu Bubble Puzzle i robi dokładnie to, czego potrzebujemy.
ktornai
2
Być może powinieneś wyjaśnić coś więcej niż tylko „skorzystaj z wypełnienia powodziowego”, ponieważ przez chwilę byłem zdezorientowany, w jaki sposób ma to związek z tym problemem.
jhocking