# fastest way to check for surrounding tiles

I'm working on a tile map where each type of tiles has 12 states with 12 different sprites associated with it, what I'm trying to say is that whenever I place a tile let's say a road tile, that tile should adjust itself automatically according to the 4 tiles surrounding it, so for example if the tile above it is a road tile and the tile below it is also a road tile, it should automatically adjust itself into a vertical road tile... there is 12 states a tile can have:

1-closed(not surrounded by any similar tile)

2-horizontal(similar tiles up and down)

3-vertical(similar tiles right and left)

4-open from up and left(similar tiles to the left and above)

5-open from left and down(...)

6-open from down and right(...)

7-open from right and up(...)

8-open from up & left & down(3 similar tiles up, left and down)

9-open from left & down & right(...)

10-open from down & right & up(...)

11-open from right & up & left(...)

12-open from all 4 directions(all surrounding tiles are similar)

the problem is that I don't know how to check for surrounding tiles and choose the right tile state without having a huge mess of if statements and performance waste, and I don't have enough experience with algorithms and data structures to figure it out myself.

how can check all 12 states the fastest way possible ?

thanks!

Use a binary mapping:

• Assign the directions N/E/S/W to the numbers 1/2/4/8
• Use the resulting number as the tile image.

The map tiles will need to be in the corresponding order. No adjacent roads is tile 0, and 4 adjacent roads is tile 15. If your sprite sheet is laid out correctly this can be coded in a concise and elegant way.

Your 12 states are missing the case where there is a single adjacent road. You need to decide what happens with that, if it's a possible game state (duplicate the closed tile?).

Here's an example from one of my old projects:

var tileMap = new Array(9, 10, 13, 16, 12, 11, 17, 21, 15, 18, 14, 23, 19, 24, 22, 20);
var mapDressing = 0;

function getTileImage(x, y) {
//in: x,y location of tile
//out: number of tile for that location
//known: global tile map
if (!isWall(getTile(x,y))) {
return (mapDressing * 54) + 4;
}

var tileAbove = getTile(x, y-1);
var tileBelow = getTile(x, y+1);
var tileLeft = getTile(x-1, y);
var tileRight = getTile(x+1, y);

var tileAboveContent = 0;
var tileBelowContent = 0;
var tileLeftContent = 0;
var tileRightContent = 0;

if (isWall(tileAbove)) {
tileAboveContent = 1;
}
if (isWall(tileBelow)) {
tileBelowContent = 1;
}
if (isWall(tileLeft)) {
tileLeftContent = 1;
}
if (isWall(tileRight)) {
tileRightContent = 1;
}

var tileIndex = tileRightContent + tileBelowContent*2 + tileLeftContent*4 + tileAboveContent * 8;

return (mapDressing * 54) + tileMap[tileIndex];
}

• This is the bit manipulation I was talking about for checking at runtime and/or storing the index value at construction, but you still have to iterate through all the neighbors to calculate the index value. Nov 28, 2020 at 6:38
• Since your values are multiples of 2 you can use bit shifting and you get a little more efficient: tileAboveContent = 1 << 0, tileRightContent = 1 << 1, tileBelowContent = 1 << 2, tileLeftContent = 1 << 3, then bitwise OR the values together: var tileIndex = tileAboveContent | tileRightContent | tileBelowContent | tileLeftContent; Nov 28, 2020 at 6:47

If you want to change the state of a tile based on its neighbors, you pretty much have to do this. You can calculate the cost up-front during construction if the map doesn't change during the game but it's almost unavoidable to have to iterate through all the neighbors and keep a count.

There are small improvements that can be made using bit manipulation techniques for instant checking, but again, the value representing the neighbors' state still needs to be calculated somehow.

• well I guess you're right, I couldn't find any solution after 2 days of thinking after all, alright thank you Casey
– VoId
Nov 14, 2020 at 23:42
• @VoId If this satisfies your question, please mark the question as Answered by clicking the check mark to the left. Nov 14, 2020 at 23:52