Game Development Community

Searching Arrays for Patterns

by Dustin Sims · in Torque Game Builder · 12/19/2006 (2:50 pm) · 4 replies

Hello Everyone.

I have a game that makes use of an array of Data and I am having trouble coming up with a way to iterate through that array and find patterns such as 3-in-a-row, etc..

My game is similiar to the beJeweled style of game and I have all my objects arranged in a grid on my screen and there corresponding data(color's) in an array.

Right now I am just using (2) nested (For) Loops and I am iterating through each array position and comparing it to the last value. I increment a counter if they are the same and them take action if I find 3 in a row...
I will try and post code later if that explanation didn't make sense..

My problem is that it is slow and makes the other gameplay jerky because I have to continually schedule this function..

Is there an obvious solution for this that I am not seeing?
It is done in most every puzzle type game?

Thanks and sorry for the lousy explanations...

#1
12/19/2006 (8:34 pm)
That doesn't sound like it should be slow at all - though I hope you aren't doing all the checking every frame or something :) Depending on the game, I'm sure there are sections of the array that you don't need to check each time - and so you could only check when and what you need to.

More likely, the schedule is the problem and not the loops - are you using a really, really small schedule or something?

Posting code would probably help get this figured out faster - hope that helped a bit though ;)
#2
12/19/2006 (9:47 pm)
Thanks for the response..
I did find the problem that was making it slow and fixed that...
I had accidently put that double nested FOR LOOP that checks my array inside of another FOR LOOP that was iterating through a simset for another reason... Needless to say as I added to my simset, it just kept getting slower and slower...
It runs better now but I have ran into another problem. I'll go ahead and post my code and describe the Prob below..

%tempLastRowColor = 0;
   %BallsInARow = 1;
    for(%j = 0; %j < 10; %j++) 
      {
         %BallsInARow = 1;
         %tempLastRowColor = 0;
         %tempRowColor = 0;
                                          
            for(%k = 0; %k < 10; %k++)
               {
                  %tempobjectid = $BallArray[%k,%j];
                     if (%tempobjectid != 0)
                        {
                           %tempLastRowColor = %tempRowColor;
                           %tempRowColor = %tempobjectid.ballColor;
                             
                           
                           if (strcmp(%tempLastRowColor,%tempRowColor) == 0)
                              {
                                 echo("Last Color: "@%tempLastRowColor@" Color: " @%tempRowColor);
                                 %BallsInARow++;
                                 if (%BallsInARow==3)
                                 {
                                    echo("*** 3 in a Row ****");
                                    %tempSetCountBF = %this.Ballset.getcount();
                                    echo(%tempSetCountBF);
                                    
                                    %this.Ballset.remove(%tempobjectid);
                                    %tempobjectid.safedelete();
                                    $BallArray[%k,%j]=0;
                                    
                                    %tempobjectid = $BallArray[(%k-1),%j];
                                    %this.Ballset.remove(%tempobjectid);
                                    %tempobjectid.safedelete();
                                    $BallArray[(%k-1),%j]=0;
                                    
                                    //echo($BallArray[%k,%j]);
                                    
                                    %tempobjectid = $BallArray[(%k-2),%j];
                                    %this.Ballset.remove(%tempobjectid);
                                    %tempobjectid.safedelete();
                                    $BallArray[(%k-2),%j]=0; 
                                    
                                    %tempSetCountBF = %this.Ballset.getcount();
                                    echo(%tempSetCountBF);
                                    return;
                                 }
                              }
                           else
                           {
                              %BallsInARow = 1;
                           }
                                                  
                        }
                     else 
                        {
                           %BallsInARow = 1;
                           %tempLastRowColor = 0;
                           %tempRowColor = 0;  
                        }
                        
                        //echo("Array Pos: "@ %k @ ","@%j@ ":" @$BallArray[%k,%j]);
               }
      }


This is the Code that I'm using to look for 3 in a ROW.
I have the same code that runs again right after that to look for 3 in a COLUMN.
I now see that this is not the correct way of doing this because my ROWS always get found and deleted first.
I would like to find a block of connected objects of the same color and delete the whole connected blob..
Not just Rows and Columns independently.
Hope this makes sense.. Any help or just a good shove in the right direction would help.
I'm thinking the solution is to somehow let each object be AWARE of it's neigbor and they somehow keep track of how many neigbors are the same color ----- sorta solution ?? MAYBE ????

Thanks.
#3
12/19/2006 (10:34 pm)
This is just a simple way of how to do a match three game (at least my way).

First create a boolean data grid MatchGem[x,y] which all elements are false

Then run 2 nested loop to check matches for column and then check matches for row. Would be something like this

for ( %i = 0; %i < sizeof( "row" ) %i++ ) {
       for ( %j = 0; %j <  sizeof( "column" )-2 ; %j++ ) {
         if (gemType[%i,%j] ==gemType[%i,%j +1]  && gemType[%i,%j] ==gemType[%i,%j +2]) {
           MatchGem[%i,%j] = true;
           MatchGem[%i,%j + 1] = true;
           MatchGem[%i,%j + 2] = true;
         }
       }
     }

     for(%r = 0;%r < sizeof( "row" )-2; %r++){
       for(%c = 0;c < sizeof( "column" ); %c++){
         if (gemType[%r,%c] ==gemType[%r +1 ,%c ]  && gemType[%r,%c] ==gemType[%r+2,%c ]) {
           MatchGem[r ,c] = true;
           MatchGem[r+1,c] = true;
           MatchGem[r+2,c] = true;
         }
       }
     }

Then you run another loop to see which elements are true and calculate the score and then delete the objects

:)
Aun
#4
12/20/2006 (5:48 am)
Aun,

Great!!
I appreciate the code sample..
I beleive this will get me closer to what I am trying to do than the method I came up with...
It looks like your code should also handle rows or columns that wind up having more than 3-in-A-Row.
I like the idea of waiting until you have found them all before taking any actions (score, and deleting objects).

Thanks everyone,
And if any one else has any ideas, all are welcome of course..