Skip to main content
4 of 4
added 171 characters in body

How do I optimize checking adjacency within a matrix (including diagonals)? [Gamemaker Studio]

How I was checking adjacency before:


if (obj_Handle_Links.Last_Link.Matrix_Location_y = (Matrix_Location_y-1)
         || obj_Handle_Links.Last_Link.Matrix_Location_y = (Matrix_Location_y+1)
         || obj_Handle_Links.Last_Link.Matrix_Location_x = (Matrix_Location_x-1)
         || obj_Handle_Links.Last_Link.Matrix_Location_x = (Matrix_Location_x+1)) 
{
        //do stuff
}

The Problem with that:

This only checks if the object's matrix location is within an adjacent row or column, not simply if it's directly adjacent to the object. Thus, it doesn't need to actually be adjacent to the last_link. That's a problem.

The Long solution:

I could individually check for each and every individual square adjacent to the object clicked on. However, this is rather inefficient (taking a minimum of 2 checks, and up to 8, if I don't include diagonals), at least if I use matrix location x/y. And if I include diagonals, that doubles the number of checks again, and makes the if statement really long.

The Question:

How do I efficiently and with as little code as possible, and make is as easily understandable as possible? Comments are obvious inclusions for that last bit, but aside from that.

Graphical Example of how the map looks

format: x,y


0,0  1,0  2,0  3,0
0,1  1,1  2,1  3,1
0,2  1,2  2,2  3,2
0,3  1,3  2,3  3,3

Below is the requested, relevant code

obj_Handle_Links create event


Match_Length = 0;

Link_Stack = ds_stack_create();

obj_Board_Generator create event


//hardcoded height and width. could change later
Large_Width = 6
Large_Height = 6

var i = Large_Width-1
var j = Large_Height-1

repeat(Large_Width)
   {
    repeat(Large_Height)
        {
        //initialize the board by generating the objects
        //later, need to randomize.
        BoardGems[i, j]  = instance_create((i-1)*36, (j-1)*36, obj_Parent)
        BoardGems[i, j].Matrix_Location_x = i
        BoardGems[i, j].Matrix_Location_y = j
        j -= 1;
        }
    j = Large_Height-1;
    i -= 1;
   }
   

obj_Parent Create event


image_speed = 0
Linked = false
Type = "Parent"

//Matrix_Location_y = 0
//Matrix_Location_x = 0

obj_Parent left click event


if (obj_Handle_Links.Match_Length = 0) //if this would be the first in the link
{
    show_message("first to link");
    obj_Handle_Links.Match_Length +=1; //because we're increasing the length
    image_index = 1; //this should highlight
    Linked = true;
    ds_stack_push(obj_Handle_Links.Link_Stack, id) //adds the instance to the stack
    obj_Handle_Links.Last_Link = id; //makes it so this is what's seen as last link
}
else
{   
   // show_message("first else");
    //check if the target is the same type as the last Link's type
    if(obj_Handle_Links.Last_Link.Type = Type &&
        //check if it's already been linked
        (Linked = false) &&
        //check if the last link in the chain is adjacent to the target link
        //includes diagonals
         ((obj_Handle_Links.Last_Link.Matrix_Location_y = (Matrix_Location_y-1) && obj_Handle_Links.Last_Link.Matrix_Location_x = (Matrix_Location_x)) //checks up 
         || (obj_Handle_Links.Last_Link.Matrix_Location_y = (Matrix_Location_y-1) && obj_Handle_Links.Last_Link.Matrix_Location_x = (Matrix_Location_x-1)) //checks up, left
         || (obj_Handle_Links.Last_Link.Matrix_Location_y = (Matrix_Location_y-1) && obj_Handle_Links.Last_Link.Matrix_Location_x = (Matrix_Location_x+1)) //checks up, right
         || (obj_Handle_Links.Last_Link.Matrix_Location_y = (Matrix_Location_y+1) && obj_Handle_Links.Last_Link.Matrix_Location_x = (Matrix_Location_x)) //checks down
         || (obj_Handle_Links.Last_Link.Matrix_Location_y = (Matrix_Location_y+1) && obj_Handle_Links.Last_Link.Matrix_Location_x = (Matrix_Location_x-1)) //checks down, left
         || (obj_Handle_Links.Last_Link.Matrix_Location_y = (Matrix_Location_y+1) && obj_Handle_Links.Last_Link.Matrix_Location_x = (Matrix_Location_x+1)) //checks down, right
         || (obj_Handle_Links.Last_Link.Matrix_Location_x = (Matrix_Location_x-1) && obj_Handle_Links.Last_Link.Matrix_Location_y = (Matrix_Location_y)) //checks left
         || (obj_Handle_Links.Last_Link.Matrix_Location_x = (Matrix_Location_x+1) && obj_Handle_Links.Last_Link.Matrix_Location_y = (Matrix_Location_y)) //checks right
         ) //parenthesis to enclose the adjacency check
         ) //parenthesis closes conditional statement
        {
            show_message("did link");
            obj_Handle_Links.Match_Length +=1; //because we're increasing the length
            image_index = 1; //this should highlight
            Linked = true;
            ds_stack_push(obj_Handle_Links.Link_Stack, id) //adds the instance to the stack
            obj_Handle_Links.Last_Link = id; //makes it so this is what's seen as last link  
         }
    else{
        
        show_message("didn't link");
        //play sound that link failed
    }
}