Accessing the 8 elements surrounding an index in a 2D grid array

When attempting to do things such as implementing a 2D path-finding algorithm, you are required at times to access the 8 surrounding tiles of the tile you are currently working on and get or set properties of those tiles. This is easy, right? Increment/decrement x and y index values of the array as needed, e.g., increment x by one, increment y by one, increment x and y by one etc.

This is illustrated in the professionally drawn picture below:

DSC_0112

The first (terrible) method of achieving this that comes to mind is to just use 8 statements to check each element individually like so (I will just use C# syntax but this can, of course work in any other language):

//mapArr is the 2D array that we are working with here for illustrative purposes
//left tile
mapArr[unit_x-1,unit_y];
//right tile
mapArr[unit_x+1,unit_y];
//top tile
mapArr[unit_x,unit_y-1];
//bottom tile
mapArr[unit_x,unit_y+1];
//top left tile
mapArr[unit_x-1,unit_y-1];
//top right tile
mapArr[unit_x+1,unit_y-1];
//bottom left tile
mapArr[unit_x-1,unit_y+1];
//bottom right tile
mapArr[unit_x+1,unit_y+1];

Just typing that without any of the “if statement checking” that would likely need to accompany this is TIRING and TEDIOUS.

Other than that though, what is so terrible about doing this?

1) It’s very easy to make a mistake while copy-pasting the same line over and over again and then editing it.
2) it looks TERRIBLE and makes your code far longer than it needs to be.
3) If you need to make a change to this code at a later point, you will have to go and make changes at each one of these 8 chunks…

A better solution would be to use a nested for loop:

for (int x = -1; x < 2; x++)
   for (int y = -1; y < 2; y++)
   {
       mapArr[unit_x + x, unit_y + y];
   }

See how nice and clean that looks?

The only potential problem with this is that it does not only access the 8 surrounding tiles. It also accesses the central tile (when both x and y are equal to zero). This may or may not be a problem. If it is, you can simply add an if statement to check for that scenario:

for (int x = -1; x < 2; x++)
   for (int y = -1; y < 2; y++)
  {
       if( !(x == 0 && y == 0);
       mapArr[unit_x + x, unit_y + y];  
  }
Share

Smoothing with an auto-tiling algorithm

Ok, so my latest experiment was implementing a 2D auto-tiling or smoothing algorithm without using any actual tile sets.

You can see it in action here:
http://stonium.co.za/smoothing/

As I used no tile sets, all tiles are drawn solely via a couple of Processing’s basic drawing functions. Namely rect() and quad().
I’ve left the grid view on so that one can more clearly see the effect that placing a tile has on the surrounding tiles quadrants.

The algorithm that I implemented can be seen here:
http://www.codeproject.com/Articles/106884/Implementing-Auto-tiling-Functionality-in-a-Tile-M

This algorithm makes smoothing easy!

Share

Random Draw

First experimental type thing complete!

–Click To See Random Draw–

I decided to mess around with the random function in Processing and see just how random it is and if it is “equally” random (you’ll see what I mean just now).


User Interaction

I wanted to make it slightly more interesting by allowing the user to affect the graphical output without affecting the purpose of the sketch.
Users can use the mouse scroll wheel to dynamically change the size of the circles that are drawn to screen.
They can also click on the “Change Mode” button to change how the circles are drawn to the screen.
In one mode they are drawn uniformly to the screen in rows, in another they are drawn to random x,y co-ordinates and in yet another they are drawn at the location of the mouse cursor.

Once the user is done messing around with it they can click the “Submit” button which stops the process and sends all the data to the database.

What It Does

So what this sketch does is it generates circles in random colours and then draws them onto the screen in a variety of ways.
Each colour consists of Red, Green and Blue (RGB) components. Now these individual R, G and B values are generated by Processing’s random() function. Each component randomed individually for every circle.
The program then checks to see which colour component of the circle was the largest (R,G or B) and increments the appropriate counter.
e.g.
A circle is drawn with R(200), G(164) and B(234). Blue has the highest value so the blue counter is incremented.
There are counters for Red, Green, Blue, Shades of grey, Black and white.
Shades of grey are colours where all 3 RGB values are equal but not equal to 0 or 255.
When they are all 0 it means a black circle will be drawn and the black counter is incremented and when they are all 255 a white circle is drawn and the white counter is incremented.

It is interesting to note how rarely the pure black and pure white colours are generated.
So far the R, G and B counters seem to always be relatively equal which of course should be the case statistically.

Share