playground as one-dimensional array

Aug 22, 2020 at 9:26pm
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;
Aug 23, 2020 at 3:50am
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.
Aug 23, 2020 at 3:07pm
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 Aug 23, 2020 at 3:23pm
Aug 24, 2020 at 10:38am
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 Aug 24, 2020 at 10:51am
Topic archived. No new replies allowed.