playground as one-dimensional array

I want to find the neighbored cells of a playground, represented by a one-dimensional array. There is no border, the world is donut-formed.

Is the mapping for these constraints correct? And is there a way, getting rid of the if-branches?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        int crd[8]; // for all 8 neighbor coordinates
        // right
        crd[0] = (m_coord + 1) % GRID_FIELDS;
        // left
        crd[1] = m_coord - 1;
        if( crd[1] < 0 ) crd[1] = GRID_FIELDS + crd[1];
        // top
        crd[2] = m_coord - GRID_WIDTH;
        if( crd[2] < 0 ) crd[2] = GRID_FIELDS + crd[2];
        // bottom
        crd[3] = (m_coord + GRID_WIDTH) % GRID_FIELDS;
        // upper left
        crd[4] = m_coord - GRID_WIDTH - 1;
        if( crd[4] < 0 ) crd[4] = GRID_FIELDS + crd[4];
        // upper right
        crd[5] = m_coord - GRID_WIDTH + 1;
        if( crd[5] < 0 ) crd[5] = GRID_FIELDS + crd[5];
        // lower right
        crd[6] = (m_coord + GRID_WIDTH + 1) % GRID_FIELDS;
        // lower left
        crd[7] = (m_coord + GRID_WIDTH - 1) % GRID_FIELDS;
As a start:
1. Any 2D array can be represented as a 1d array using a transform using its 2 coordinates.
2. The 8 neighbors plus border element make a 3x3 array, centered on the border element.
smoke and mirrors.


int main()
{
int pg[9] = {100,101,102,110,111,112,120,121,122};
typedef int i3[3];
i3* magic = (i3*)(pg);
cout << magic[1][1]; //address pg as if it were 2-d. we mangled it into a 3x3 here
//the reshape tricks only work on solid blocks. dynamic multi-dimensional stuff can't do
//these things.
}

be creative on losing the ifs
1) consider using an enum to name your locations. it will be easier to read crd[top] and then you don't need the comments.
2) you can iterate using these enums. for(i = top, i <= upper_right; i++) if(crd[i] < 0) crd[i]+= gridfields; or something like that. there are other ways too-- you can make what to do for true and false:
int tf[2] = {0,gridfields};
...
crd[4] += tf[crd[4] <0]; //false adds zero, true adds gridfields... no if statement.

not saying any of this is the right way to do it, but you asked. Any or all of these tricks can be useful when fixing pre c98 code, though and getting rid of if statements this way is faster in some code (not all) than using a branch.
Last edited on
Thank you, jonnin. That's a nice trick you provided getting rid of the ifs.

I found another way, using the modulo operation without coming into negative values for the coordinate system:
1
2
//left
crd[LEFT] = (m_coord - 1 + GRID_FIELDS) % GRID_FIELDS;


Sometimes it's good laying the code away and sleep a night over :-)
Last edited on
Topic archived. No new replies allowed.