Logica dietro un gioco ingioiellato


12

In un prototipo che sto realizzando, c'è un minigioco simile a Bejeweled. Usando una griglia che è un array 2d ( int[,]) come posso sapere quando l'utente ha formato una corrispondenza? Mi interessa solo in orizzontale e in verticale.

Dalla parte superiore della mia testa stavo pensando che avrei semplicemente guardato in ogni direzione. Qualcosa di simile a:

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

Sembra che ci dovrebbe essere un modo migliore. È lì?


Mi sono ricordato di aver scritto noioso per loop per farlo (per un connect-n)
Ming-Tang,

Risposte:


6

Passa attraverso ciascun elemento nello stesso asse (xo y), se sono uguali all'elemento precedente a cui corrispondono gli incrementi. Quando l'elemento successivo diventa diverso, controlla se le corrispondenze sono o superiori a 3, chiama una funzione che rimuove gli elementi corrispondenti e continua.

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

Questo è solo per l'asse x, per y, la griglia [col] [i] diventerebbe griglia [i] [riga], ecc. Sono sicuro che puoi capirlo :)


4

Ho solo pensato di tener conto della nostra esperienza nella costruzione di un gioco simile a Match-3.

Abbiamo creato un prototipo per un gioco di parole basato su Match 3, un po 'come unire scrabble e Bejeweled. Ci siamo resi conto molto presto che il motore che fornisce nuove gemme / tessere per riempire gli spazi vuoti avrebbe dovuto essere altamente introspettivo (eseguiamo l'euristica ibrida e il campionamento MonteCarlo) al fine di creare reali opportunità per un giocatore di mettere insieme le lettere per formare parole attraverso Meccanico match-3. È molto più elaborato della descrizione, ma lo sto tenendo breve perché dovremmo scrivere un documento.

Per rispondere all'OP - stiamo facendo dei controlli di modello per segnare quante partite ci sono su una data gird, al momento attuale, attraverso un metodo molto simile allo snippet di codice "gladoscc". Mentre funziona in modo robusto, il costo computazionale per l'esecuzione in modo ricorsivo durante il playout della ricerca dell'albero diventa un onere sostanziale, quindi stiamo riscrivendo questa parte della logica e la rappresentazione dei dati con la metodologia della scheda bit ( comunemente implementato in giochi di altre griglie come scacchi, dama, Otello, ecc.) Nei test abbiamo dimostrato che può funzionare 20 volte più veloce in ActionScript, e quindi per noi la necessità di farlo è una schiacciata - e libera cicli essenziali per reattività, suono, animazione, ecc.


3
La tua risposta dovrebbe essere una risposta e non aggiungere un'altra domanda. Se hai una domanda, crea una nuova domanda utilizzando il pulsante "RICHIEDI DOMANDA". Questo non è un forum di discussione.
bummzack,

1
bummzack .... grazie per quello. La mia logica era che avevamo un'intuizione da offrire, soprattutto per quanto riguarda le prestazioni di ciò che era stato proposto in precedenza quando la ricerca / introspezione degli alberi veniva aggiunta al contesto. E ha continuato ad essere rilevante dal momento che stiamo ancora parlando essenzialmente della "Logica dietro un gioco Bejeweled". Se il problema persiste, sarò felice di modificarlo / inviarlo di nuovo secondo i tuoi consigli.
Wissam,

2
Va bene. Ma dovresti rimuovere la parte "domanda" dalla tua risposta. Le domande dovrebbero essere nuove domande e non parte di una risposta ...
bummzack,

1
modificato e pubblicato la domanda altrove
Wissam il

2

Ricorsione, yo. È per quando non conosci i tuoi confini.

   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

È possibile utilizzare l' algoritmo di riempimento flood . È davvero utilizzabile per questo tipo di problema.


1
No, in realtà non ha nulla a che fare con la domanda. L'OP chiede come rilevare tre elementi corrispondenti in una riga.
Ciclope,

2
Se si avvia il riempimento con gli elementi capovolti, l'algoritmo passa attraverso gli elementi corrispondenti. Ma solo per controllare 3 (e non più) elementi corrispondenti in una riga (e senza colonne incrociate), è forse un eccesso. Lo usiamo in un gioco Bubble Puzzle come, e fa esattamente ciò di cui abbiamo bisogno.
Ktornai,

2
Forse dovresti spiegare un po 'più di un semplice "uso del riempimento" perché sono stato confuso per un secondo su quanto sia rilevante per questo problema.
derisione del
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.