Check for matching adjacent tiles in a hexagonal TileMap

Godot Version

4.1.2

Question

Essentially I have a hexagonal TileMap with various colors, red, green, blue, magenta, and yellow, and I want to check for groups of colors, like would be done in a match 3 game. Mine is more of a match 6, but same idea. If six or more tiles of the same color are touching, then that tile’s color is set to gray. I would also like to check the shape of the connected tiles, i.e. if six of them are in a straight line, a circle, or triangle, but I was planning on dealing with that after I figured out the matching in the first place. The TileMap is using sprites, not the modulate color, and I can determine the color of each tile based on the atlas coords, so detecting the color of each tile isn’t an issue, just seeing if adjacent tiles are of the same color.

if you can determine the color of each tile based on atlas coords, the current tile needs to know where to check for neighboring cells (by a offset for example) and if it finds a matching color, the chain needs to be stored and the neighbor with the matching color would then need to check its neighbors.

i would define those things first:
var neighbor_offsets = [
Vector2(1, 0), # Right
Vector2(1, -1), # Top Right
Vector2(0, -1), # Top Left
Vector2(-1, 0), # Left
Vector2(-1, 1), # Bottom Left
Vector2(0, 1) # Bottom Right
]

var matched_tiles = # this will store matched tiles

tilemap iterator:
func iterate_through_tilemap():
for x in range(tilemap.get_used_rect().size.x):
for y in range(tilemap.get_used_rect().size.y):
checkForMatches(x, y)

a function to check for matches:

func checkForMatches(x, y):
var current_tile = tilemap.get_cell(Vector2(x, y))

# List to store matching neighbors
var matching_neighbors = []

for offset in neighbor_offsets:
var neighbor_pos = Vector2(x, y) + offset

 *  a check if a cell exists AND if the cell is the same color as the current cell =*
        matching_neighbors.append(neighbor_pos)

if len(matching_neighbors) > 0:
# Mark the matching tiles for processing
for pos in matching_neighbors:
# Store the position of the matched tile
matched_tiles.append(pos)

    # Recursively check matching neighbors
    for neighbor in matching_neighbors:
        checkForMatches(neighbor.x, neighbor.y)

and at the end when no more matched tiles are found you can call a function for destroying/scoring etc:

var score = 0
for pos in matched_tiles:
# Destroy the tile at ‘pos’ (remove it from the TileMap)
tilemap.set_cell(pos, -1) # you have to do your own logic here (spawn new tiles,make the other tiles move in)
# score or whatever you like
score += 1

that was quick brainstorming as i did something similar once. the logic should be the same, how you implement it is up to you.

1 Like

If you intend to use the grid often and is open to use C#, I can only recommend the Sylves Library by BorisTheBrave. Make sure to use version 1.0.0, the docs still link to 0.4.0. You can now use hexagonal or other esoteric grid types with a similar interface.

Follow the tutorials to get a grip on the concept, and you won’t regret learning this library.

You could use get_surrounding_cells to make it simpler.

Edit: I take it back. That doesn’t help nearly as much as I thought.

I think you can use local_to_map method to get the map coordinate of the cell, and then you will be able to get surrouding cells. Maybe a for loop, checking in each direction of the cell, can be used the determined if a sequence was made.