Logique derrière un jeu de type bejeweled

12

Dans un prototype que je fais, il y a un mini-jeu similaire à bejeweled. En utilisant une grille qui est un tableau 2D ( int[,]), comment puis-je savoir quand l'utilisateur a formé une correspondance? Je me soucie seulement horizontalement et verticalement.

Du haut de ma tête, je pensais que je ne ferais que regarder chaque direction. Quelque chose comme:

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

Il semble qu'il devrait y avoir une meilleure solution. Y a-t-il?


la source
Je me suis souvenu d'avoir écrit une boucle fastidieuse pour faire ça (pour une connect-n)
Ming-Tang

Réponses:

6

Parcourez chaque élément dans le même axe (x ou y), s'ils sont identiques à l'élément précédent, ils incrémentent les correspondances. Lorsque l'élément suivant devient différent, vérifiez si les correspondances sont supérieures ou égales à 3, appelez une fonction qui supprime les éléments correspondants et continuez.

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

C'est seulement pour l'axe x, pour y, la grille [col] [i] deviendrait la grille [i] [ligne], etc. Je suis sûr que vous pouvez le comprendre :)

apscience
la source
4

Je pensais juste peser avec notre expérience dans la construction d'un jeu de type match-3.

Nous avons construit un prototype pour un jeu de mots basé sur Match-3, un peu comme mélanger le scrabble et Bejeweled. Nous avons réalisé très tôt que le moteur qui fournit de nouvelles gemmes / tuiles pour remplir les espaces vides devrait être très introspectif (nous exécutons l'heuristique hybride et l'échantillonnage MonteCarlo) afin de créer de réelles opportunités pour un joueur de ficeler des lettres pour former des mots à travers le Mécanicien de match-3. C'est beaucoup plus élaboré que la description mais je suis bref car il faudrait écrire un article.

Pour répondre à l'OP - nous effectuons des vérifications de modèle pour marquer le nombre de correspondances sur un réseau donné, à l'heure actuelle, grâce à une méthode très similaire à l'extrait de code "gladoscc". Bien que cela fonctionne de manière robuste, le coût de calcul pour l'exécution de manière récursive pendant la lecture de la recherche d'arborescence devient une charge substantielle, nous sommes donc en train de réécrire cette partie de la logique et de la représentation des données avec la méthodologie de la carte à bits ( couramment implémenté dans des jeux comme les autres grilles comme les échecs, les dames, Othello, etc.) Dans les tests, nous avons montré qu'il peut fonctionner 20 fois plus rapidement dans ActionScript, et donc pour nous, la nécessité de le faire est un slam-dunk - et libère des cycles essentiels pour la réactivité, le son, l'animation, etc.

Wissam
la source
3
Votre réponse doit être une réponse et ne pas ajouter une autre question. Si vous avez une question, veuillez créer une nouvelle question en utilisant le bouton "POSER UNE QUESTION". Ce n'est pas un forum de discussion.
bummzack
1
bummzack .... merci pour cela. Mon raisonnement était que nous avions un aperçu à offrir, en particulier en ce qui concerne la performance de ce qui avait été proposé précédemment lorsque la recherche / introspection d'arbres a été ajoutée au contexte. Et cela a continué d'être pertinent car nous parlons toujours essentiellement de la "logique derrière un jeu Bejeweled". Si cela continue d'être de mauvaise forme, je serai heureux de modifier / republier selon vos conseils.
Wissam
2
C'est très bien. Mais vous devez supprimer la partie "question" de votre réponse. Les questions devraient être de nouvelles questions et ne devraient pas faire partie d'une réponse ...
bummzack
1
édité et publié la question ailleurs
Wissam
2

Récursivité, yo. C'est pour quand vous ne connaissez pas vos limites.

   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
la source
0

Vous pouvez utiliser l' algorithme de remplissage d'inondation . C'est vraiment utilisable pour ce type de problème.

ktornai
la source
1
Non, en fait, cela n'a rien à voir avec la question. L'OP demande comment détecter trois éléments correspondants dans une rangée.
Cyclops
2
Si vous commencez le remplissage avec les éléments inversés, l'algorithme passe par les éléments correspondants. Mais juste pour vérifier 3 (et pas plus) élément correspondant dans une rangée (et pas de colonnes croisées), c'est peut-être une surpuissance. Nous l'utilisons dans un jeu de type Bubble Puzzle et faisons exactement ce dont nous avons besoin.
ktornai
2
Vous devriez peut-être expliquer un peu plus que simplement «utiliser le remplissage par inondation», car j'ai été confus pendant une seconde sur la pertinence de ce problème.
jhocking