Calculating Hex Distance and movement.

Started by
3 comments, last by mjessick 16 years, 11 months ago
I have a basic game where I need to calculate the distance between elements on a hex map. If Player A is at 0,0 on a hex map (vertically aligned grid) and Player B is at 3,0 (three hexes due north of Player A) what formula can I use to tell me that? I found a few hex math examples on th web but their math was suspect (hexes clearly two spaces apart would generate a result of 4 in the posted examples). I ultimately need a fairly "infinite" hex map as players can move at will around the map and I need to be able to allow them to move without running "off the map". Calculating everything from 0,0 seemed like a good way to go about this. Now I just need to get the formula right. An excel version of this for me to play with would be most helpful to understand. ----------- I think I got the distance worked out. The next item I need to figure out is related to line of sight but not quite the same thing (then again, maybe it is). In my game the facing is key. If you're in hex 0,0 and facing north you can interact with players up to 3 hexes away in the direction you're facing. In this case hexes 1,0 2,0 and 3,0. What's a good way to quickly figure out if there is another player in those hexes? Later I'll need to limit it only to the one closest in case two or three players are there (you can only interact with the one you closest to you). Any help with this would be greatly appreciated. Lastly, is there a simple way to calculate movement? (or a link to where this is discussed?) If Player A is at 0,0 facing north and wants to move north 1 hex and then NW one hex, is there a simple way to calculate that move to generate the new location or must I manually step through each piece of that movement? [Edited by - RichH on April 7, 2007 2:43:40 AM]
Advertisement
It's trivial to determine a hex's neighbors. I'm not really seeing your problem. If you want to see which hex is three steps away to the northwest, you just find your northwest neighbor, than that hex's northwest neighbor, and so on. It seems almost painfully simple to me.

Oh, and, there's no reason you can't run A* on a hex grid.
Having never done this before it wasn't as obvious to me. Was it really necessary to post nothing of use but to point out how painfully simple this all is? Thanks for that.

Anyway, I think I've figured out most of this but still would love to hear from others with experience on how best to do the above things.

For example, keeping track of the facing (which direction I'm pointing in the hex) I can apply a simple table to both movement and locating neighboring squares. In the above case it would be:

If F=0 then X=X+1
If F=1 then X=X+1, Y=Y+1
If F=2 then Y=Y+1
If F=3 then X=X-1
If F=4 then X=X-1, Y=Y-1
If F=5 then Y=Y-1

This works. I'm just wondering if it's the best way.

Again, I realize that to most of you, this is simple stuff but recall what it's like the first time you encounter something like this. The problem before you looks more daunting than it is. Getting to the formula to calculate the distances between two players was extremely complicated and that gave the impression that much else with this might be too.

Lastly what is A* exactly and how will it help here? I read a couple posts about it and didn't think it was needed.

[Edited by - RichH on April 7, 2007 11:44:32 AM]
You're table might be correct if it matches how your hexes are laid out, but it will only work for either even or odd rows or columns, again depending on how your hexes are laid out. Your use of the example 'north' suggests you are using horizontal hexes (points on the right and left) as vertical hexes don't have a northern neighbor. You need to select a different lookup table depending for odd columns than even ones.

This is my direction code for horizontal hex maps.
TileCoordinate neighbor(TileCoordinate of, unsigned int direction)			{				if (is_odd(of.x))				{					switch (direction)					{					case Directions::NORTHWEST :						return of + TileCoordinate(-1,0);					case Directions::NORTH :						return of + TileCoordinate(0,-1);					case Directions::NORTHEAST :						return of + TileCoordinate(1,0);					case Directions::EAST :						return of;					case Directions::SOUTHEAST :						return of + TileCoordinate(1,1);					case Directions::SOUTH :						return of + TileCoordinate(0,1);					case Directions::SOUTHWEST :						return of + TileCoordinate(-1,1);					case Directions::WEST :						return of;					default :						return of;					}				}				else				{					switch (direction)					{					case Directions::NORTHWEST :						return of + TileCoordinate(-1,-1);					case Directions::NORTH :						return of + TileCoordinate(0,-1);					case Directions::NORTHEAST :						return of + TileCoordinate(1,-1);					case Directions::EAST :						return of;					case Directions::SOUTHEAST :						return of + TileCoordinate(1,0);					case Directions::SOUTH :						return of + TileCoordinate(0,1);					case Directions::SOUTHWEST :						return of + TileCoordinate(-1,0);					case Directions::WEST :						return of;					default :						return of;					}				}			}


Quote:Having never done this before it wasn't as obvious to me. Was it really necessary to post nothing of use but to point out how painfully simple this all is?
Yes.

Quote:Lastly what is A* exactly and how will it help here? I read a couple posts about it and didn't think it was needed.
A* is a path finding algorithm. Use it to find the intermediate hexes along the path from some hex to another.
Hi Rich:

In the dark ages, I developed a hex grid coordinate system (two non-orthogonal axes 120 deg apart) and a hex grid "Mathematics" system for moving on a particular style of hex grid. ("SPI" style paper wargame grid with hexes arranged vertically and even columns displaced "down and to the right", using integers for column and row identifiers.)

If you can use C++ code, I would be happy to email a C++ class. This would provide an example for tasks like calculating the by-hex distance between two hexes very far apart, maintaining states (hex and hexside facing), and commanding moves via strings such as "FFRR" for move forward twice then rotate right 120 degrees, etc.

email using my forum username above: username@verizon.net

This topic is closed to new replies.

Advertisement