Simplicity with arrays

You must understand the Game Editor concepts, before post here.

Simplicity with arrays

Postby Fuzzy » Mon Jan 07, 2008 1:48 pm

If you havent figured out that I dont like if() by now, you are either new or living on another planet!

I do use it, but as far as I am concerned, if you can write a bit of code without it, so much the better. An if statement acts as a fork, complicating your code, making it slower, harder to find bugs..
And a lot of people just use it so they dont have to think beforehand. I know that people say computers are good at thinking for us, but if we do a little thinking beforehand, we can make our games run smoother.

A lot of games require arrays, especially if you are writing to a graphic file or have a map. One of the big problems is that you have to take special care of the cells at the edges and corners.

Lets say that we have an array that is 16x16 units defined in global code.

Code: Select all
char Tile[16][16];


It looks like this in memory...

Image

So if we want to check what is in the surrounding cells, we need to use one type of if() for the orange squares and a second type of if for the blue ones. the green corners must use both types of if. Its inefficient, and it needs to be done because we cannot refer to space outside that array without an error. We must use the if to wrap left and right together as well as top and bottom.
Image

For example, say that we are looking for the neighbours of Tile[x][y], and x = 0 and y = 0.

The neighbour just above would be Tile[x][y-1], which doesnt really exist, so we use an if to wrap around to get the cell from the bottom.

Code: Select all
if (y == 0) {....}


See what I mean? The same applies to the x value if we want x-1. To complicated. There must be an easier way.

There is. We dont use a 2D array! change the array to be like this in global code.
Code: Select all
char Tile[256];


Which is exactly the same number of tiles. Its just that they are layed out in a line now. imagine that they are numbered 1,2,3,4,5,6.... instead of a two value position. we can change it back on the fly in a bit.

So now we dont have to check with if for the left and right neighbours to keep things in bounds. We do, but only for the first and last. We'll fix that with the next step. So now we have half as many if checks. Thats a huge improvement already!

So now all we do is check to see if tile[value] is under 16 or over 238. this corresponds to these cells..
Image

If we have a value of 5 (Tile[value]) and we want to know something about its neighbour to the left, we use Tile[Value-1]. To find its neigbour above or below, we subtract or add 16. Problem is, this can get us an error if we are outside the defined limits of the array. So again, we have to use if! Arg!

So again, we need to think ahead for the computer. If we can pull this off, we can save some complication in our program.

As people, we know that the Tile[value-16], (its still value = 5) is the same as Tile[244]. Here comes the tricky part. If after our math we are outside the boundary of the array, then we should start outside the boundary and then do the math.. we will be inside then, and no error will happen. imagine that we have another row at the bottom..
Image

..Then we could do Tile[Value-16] and not get an error. We dont want want to make the array larger, just pretend. So instead of subtracting first, we add a value in, then subtract.

Code: Select all
Tile[value+256-16]


Which works out to 5+255-16 or 244! Success! so now we dont have to check if when value is under 16.

Now we have to set things so that we can add numbers without an array overflow(thats what this error is called). This is even easier. All we have to do is take the modulus of 256(the total number of cells). if the calculated value was over 255, it will now start counting at zero again. Modulus is the remainder from dividing, so its got to be 0 to 255, since we are taking it from 256.

In this example i will use a new variable and call it offset. This would be valued with -16, 16, 1 or -1 at times. it gives a neigbour offset.
Code: Select all
Tile[(value+256+offset) % 256];


We might as well substitute that 256 for a variable as well. lets call it ASize, for array size. We can set its value with a function in GE. I'll show you.

Code: Select all
ASize = sizeof(Tile);
Tile[(value+ASize+offset) % Asize];


So to sum up.. Tile is an array, value is a marker that points to a certain cell in that array, ASize is the size of the array. offset is a number that gets a neigbour based on direction. % clamps that value so it is always within the range of 0 to ASize.

To calculate a certain point in that array you can use this formula. If you know your actors x and y in the view, you can find were there are in an 1D array with this formula.

Map[y*1024+x] if the view is 1024 pixels wide.

You'll have questions then I will rewrite this..
Last edited by Fuzzy on Mon Jan 07, 2008 1:51 pm, edited 1 time in total.
Mortal Enemy of IF....THEN(and Inspector Gadget)

Still ThreeFingerPete to tekdino
User avatar
Fuzzy
 
Posts: 1068
Joined: Thu Mar 03, 2005 9:32 am
Location: Plymostic Programmer
Score: 95 Give a positive score

Re: Simplicity with arrays

Postby Bee-Ant » Mon Jan 07, 2008 1:50 pm

:shock: beautiful codes :shock:
User avatar
Bee-Ant
 
Posts: 3723
Joined: Wed Apr 11, 2007 12:05 pm
Location: http://www.instagram.com/bee_ant
Score: 210 Give a positive score


Return to Advanced Topics

Who is online

Users browsing this forum: No registered users and 1 guest