Quoting TheRealWarpstorm,
Quoting tetleytea, reply 18
Sorry, but I'm calling BS on that one. You may be able to represent a hex grid in a 2-D array--just not a 2-D array of squares.
Sure you can. You stagger every other row (or column if you want the other grain as shown in this image) by half a square. War games have been doing this on the computer for decades.
It's not that bad from a coding perspective either, you can represent hexes as a 2d array, it's just an array where only half the diagonals are considered adjacent.
So in a 4-direction square grid, (1,1) is adjacent to:
{ (0,1), (1,0), (1,2), (2,1) }
If it's an 8-direction grid, i.e. squares with diagonal movement allowed, you get the above points plus the diagonals:
{ (0,0), (0,1), (0,2), (1,0), (1,2), (2,0), (2,1), (2,2) }
A "hex" or 6-direction grid is just one where you allow half the diagonals - you can go up+right, or down+left, but not down+right or up+left for example:
{ (0,0), (0,1), (1,0), (1,2), (2,1), (2,2) }
Visually you can think of this as a square grid with half the diagonals drawn in, only the ones that go up+right i.e. positive slope (closest to the way the code actually deals with it), or a hex grid or an offset square grid as above (which make more sense visually to a human, but are functionally identical). I wish I could draw a pretty picture like Warpstorm did, but I'm bored at work with nothing except ms paint to work with.
As far as actual code, it does add a few extra checks, but it's not too horrible. Say you've got a "tile" class that includes, among other things, int x and int y variables to describe its position on this hypothetical grid. Now you want to add a testAdjacency method to your class that, provided a second tile t, returns a boolean telling you if the two are adjacent. Note I left out a check to make sure the two tiles aren't identical (I'm sure you can imagine how that works, it'd be the same in each case anyway), and the xdif/ydif variables aren't strictly necessary but just to improve readability.
8-direction method, the easiest actually:
boolean testAdjacency( tile t )
{
int xdif = t.x - this.x;
int ydif = t.y - this.y;
if( math.abs( xdif ) <= 1 && math.abs( ydif ) <= 1 )
return true;
return false;
}
4-direction method, a little more complicated:
boolean testAdjacency( tile t )
{
int xdif = t.x - this.x;
int ydif = t.y - this.y;
if( ydif == 0 && math.abs( xdif ) <= 1 )
return true; //adjacent if t is right or left of this tile
if( xdif == 0 && math.abs( ydif ) <= 1 )
return true; //adjacent if t is up or down from this tile
return false;
}
And 6-direction i.e. hex method (this uses the up+right or down+left convention above, you could just as easily do it the other way):
boolean testAdjacency( tile t )
{
int xdif = t.x - this.x;
int ydif = t.y - this.y;
if( xdif <= 1 && xdif >= 0 && ydif <= 1 && ydif >= 0 )
return true; //adjacent if t is right, up, or up+right from this tile
if( xdif >= -1 && xdif <= 0 && ydif >= -1 && ydif <= 0 )
return true; //adjacent if t is left, down, or down+left from this tile
return false;
}
Apologize for shameless thread derailing. I like hexes.
Edit: bugfixing! gah.