0
\$\begingroup\$

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
    }
}
\$\endgroup\$
  • \$\begingroup\$ If the code above is related to an if statement, please add such along with brackets and a placeholder comment to better locate its role. E.G. if (cond) { //DoStuff }. \$\endgroup\$ – liggiorgio Jun 15 '16 at 9:15
  • \$\begingroup\$ OK. Thanks. Done. Of course, it's just a condition. It works in anything that uses a condition. \$\endgroup\$ – SangoProductions Jun 15 '16 at 11:26
1
\$\begingroup\$

You can construct an efficient test of whether a point lies within an axis-aligned rectangle with well-understood algorithms. Try this answer.

\$\endgroup\$
  • \$\begingroup\$ I think that'd work. Once I confirm that I got it to work for me, I'll mark this as my answer. \$\endgroup\$ – SangoProductions Jun 16 '16 at 4:48
0
\$\begingroup\$

You can find many articles and repos online related to this topic. User dgkanatsios on GitHub created his MatchThreeGame and included an article on his site in which he explains how to make such a game in Unity step by step. As well, did rembound with his Match-3-Game-HTML5 which was developed in JavaScript and run in a browser.

Although you're working with GM:Studio, you can still read their guide and extrapolate the algorithms they use to accomplish the various tasks to make their respective games work. The earlier article also shows a DFA state chart representing the main operations performed by the game loop routine while the game is running.

Anyway, we can't help you as much as we could, until you show us some more code or fully explain how your current algorithm works, what's the data structure you're using to deal with the game status, and so on.

\$\endgroup\$
  • \$\begingroup\$ OK. I'll add more details on the code. I just generally don't get responses unless I streamline the questions. \$\endgroup\$ – SangoProductions Jun 15 '16 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.