#ifndef HEXLIB_H_ #define HEXLIB_H_ 1 /* * this library implements a generic library for hexgrids for games. * it avoids display issues, other than some general provisions * for data * * This file is written by Nathan Wagner and dedicated to the * public domain. */ /* max size for cantor numbers is 16383, or 32767 if non-negative, * assuming a 32 bit int */ /* map from cartesian coordinates to hex coords */ /* cartesian coordinates are positive Y up, hex coords * are positive Y down. You may need to pass in the * negative of your Y coordinate * * width is the distance from one hexside to the opposite * hexside. i and j are the cartesian coordinates of the hex * the x,y point falls in. If a point happens to fall exactly * on a hex boundary, the result will depend on how the machine * does the floating point math, but should be consistent. */ int HL_hexbin(double width, double x, double y, int *i, int *j); /* generate the cantor mapping of a hexes x,y coordinate. * See http://en.wikipedia.org/wiki/Cantor_pairing_function. * We modify the basic formula to support negative coordinates * * The cantor mapping is *not* a contiguous mapping, as it maps * onto a triangle, so you can't use the cantor mapping as * an index into an array. Or, you can, but the array * will be (I think) twice as large as it needs to be * * See also http://mathworld.wolfram.com/PairingFunction.html * for a reference to a square mapping by Stein that doesn't * have this problem, at least for square maps. * * We use the cantor mapping so that the generated integer * is independent of the size of the grid. */ /* Cartesian functions */ int HL_cantor_xy(int x, int y); int HL_cantor_xyp(int *xy); int HL_cantor_x(int cantor); int HL_cantor_y(int cantor); /* Isometric functions */ int HL_cantor_ijk(int i, int j, int k); int HL_cantor_ijkp(int *ijk); int HL_cantor_i(int cantor); int HL_cantor_k(int cantor); int HL_cantor_j(int cantor); int HL_cantor_bin(double x, double y); /* A general decode function */ int HL_cantor_decode(int can, int *x, int *y, int *i, int *j, int *k); int HL_cantor_arrays(int can, int *xy, int *ijk); /* * layout assistance functions * * HL_center_x(int cantor) returns the cartesian X coordinate * of a given hex, assuming a width of 1.0. Scaling can * be done by the caller. * * Similarly for HL_center_y() and HL_hexcenter() */ double HL_center_x(int cantor); double HL_center_y(int cantor); int HL_hexcenter(int cantor, double *x, double *y); /* how far is it on the hex grid */ int HL_distance(int from_cantor, int to_cantor); /* returns 0 for <0 or >5 */ int HL_adjacent_hex(int start, int dir); /* module direction */ int HL_adjhex(int start, int dir); int HL_hexes_at_range(int hex, int range, int *list, int size); int HL_hexes_within_range(int hex, int range, int *list, int size); typedef double (*HL_costfunc)(int start, int finish); /* writes up to len cantors to path. returns last * value written * perhaps it should return the last value not written, if the * path is incomplete? * either way, it can then be used in a loop */ int HL_path(int start, int end, int *path, int len); int HL_map_bounds_ok(int xdim, int ydim); int HL_map_max_dimension(void); /* * Plotting support */ void HL_trianglefan(int cantor, double *); struct HL_hex { int x,y; /* hmm. would be nice to be able to just point to a generic */ }; /* * Pathfinding */ struct HL_astar_hex { int hex; double f, g, h; struct HL_astar_hex *parent; int open; struct HL_astar_hex *next; struct HL_astar_hex *prev; }; struct HL_astar { int start, goal; int pathlen; double (*metric)(int,int); double (*heuristic)(int,int); int (*neighbor)(int,int); int nodes, allocated; struct HL_astar_hex *sets; struct HL_astar_hex *open; struct HL_astar_hex *closed; struct HL_astar_hex *from, *to; int known, index; int error, malloced; }; int HL_findpath(struct HL_astar *s, int loops); void HL_astar_free(struct HL_astar *s); struct HL_astar *HL_astar_clear(struct HL_astar *s); struct HL_astar *HL_astar_init(struct HL_astar *s); extern double HL_fand[16]; extern float HL_fanf[16]; extern double HL_hfand[16]; /* horizontal grids */ extern float HL_hfanf[16]; /* horizontal grids */ extern double HL_square; #endif