Code: Select all
hexagon_02.bas(340) error 7: Expected ')', found ',' in 'dim as hex_layout layout = type(layout_pointy, type(30, 30), type(100, 100))'
Does anyone know how to make the compiler eat my code?
Code: Select all
'https://www.redblobgames.com/grids/hexagons
'https://www.redblobgames.com/grids/hexagons/implementation.html
'-------------------------------------------------------------------------------
#define sqrt sqr
#define max(a, b) (iif((a) > (b), (a), (b)))
#define min(a, b) (iif((a) < (b), (a), (b)))
#define lerp(a, b, t) ((a) + ((b) - (a)) * t) 'linearly interpolation
#define M_PI (atn(1) * 4)
'---------------------------- hex cube coordinates -----------------------------
type hex_cube
dim as integer x 'pointing right/up
dim as integer y 'pointing left/up
dim as integer z 'pointing down
end type
function hex_equal(a as hex_cube, b as hex_cube) as boolean
if a.x <> b.x then return false
if a.y <> b.y then return false
if a.z <> b.z then return false
return true
end function
function hex_add(a as hex_cube, b as hex_cube) as hex_cube
return type(a.x + b.x, a.y + b.y, a.z + b.z)
end function
function hex_substract(a as hex_cube, b as hex_cube) as hex_cube
return type(a.x - b.x, a.y - b.y, a.z - b.z)
end function
dim shared as const hex_cube hex_cube_direction(0 to 5) = {_
type(+1, -1, 0), type(+1, 0, -1), type(0, +1, -1), _
type(-1, +1, 0), type(-1, 0, +1), type(0, -1, +1) }
function hex_neighbor(hc as hex_cube, direction as integer) as hex_cube
return hex_add(hc, cast(hex_cube, hex_cube_direction(direction)))
end function
dim shared as const hex_cube hex_cube_diagonal(0 to 5) = {_
type(+2, -1, -1), type(+1, +1, -2), type(-1, +2, -1), _
type(-2, +1, +1), type(-1, -1, +2), type(+1, -2, +1) }
function hex_neighbor_diagonal(hc as hex_cube, direction as integer) as hex_cube
return hex_add(hc, cast(hex_cube, hex_cube_diagonal(direction)))
end function
function hex_distance(a as hex_cube, b as hex_cube) as integer
return (abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z)) \ 2
end function
'Note: cube_distance also possible with max(dx, dy, dx)
'60° rotation
function hex_rotate_left(a as hex_cube) as hex_cube
return type(-a.z, -a.x, -a.y)
end function
function hex_rotate_right(a as hex_cube) as hex_cube
return type(-a.y, -a.z, -a.x)
end function
'For 60° rotation around other hex: translate, rotate, translate back: TODO
'Use add and substract for translation
'Reflection
function hex_reflect_x(h as hex_cube) as hex_cube
return type(h.x, h.z, h.y)
end function
function hex_reflect_y(h as hex_cube) as hex_cube
return type(h.z, h.y, h.y)
end function
function hex_reflect_z(h as hex_cube) as hex_cube
return type(h.x, h.y, h.z)
end function
'--------------------------- hex axial coordinates -----------------------------
type hex_axial
dim as integer q 'pointing right/up
dim as integer r 'pointing down
end type
function hex_axial_add(a as hex_axial, b as hex_axial) as hex_axial
return type(a.q + b.q, a.r + b.r)
end function
function hex_axial_substract(a as hex_axial, b as hex_axial) as hex_axial
return type(a.q - b.q, a.r - b.r)
end function
dim shared as const hex_axial hex_axial_direction(0 to 5) = {_
type(+1, 0), type(+1, -1), type(0, -1), _
type(-1, 0), type(-1, +1), type(0, +1) }
function hex_axial_neighbor(ha as hex_axial, direction as integer) as hex_axial
return hex_axial_add(ha, cast(hex_axial, hex_axial_direction(direction)))
end function
function hex_axial_distance(a as hex_axial, b as hex_axial) as integer
return (abs(a.q - b.q) + abs(a.q + a.r - b.q - b.r) + abs(a.r - b.r)) \ 2
end function
'Note: Or convert to hex_cube first
'--------------------------- coordinate conversion -----------------------------
function hex_cube_to_axial(hc as hex_cube) as hex_axial
return type(hc.x, hc.z) 'ignore y
end function
function hex_axial_to_cube(ha as hex_axial) as hex_cube
return type(ha.q, ha.r, -(ha.q + ha.r))
end function
'------------------------- a simple hex <vextor> class -------------------------
type hex_list
private:
dim as hex_cube h(any)
public:
declare function push(h as hex_cube) as integer
declare function pop() as hex_cube
declare sub del_()
declare function size() as integer
declare function last_index() as integer
end type
'add to end of list
function hex_list.push(h_ as hex_cube) as integer
dim as integer ub = ubound(h) + 1
redim preserve h(ub)
h(ub) = h_
return ub
end function
'remove from end of list
function hex_list.pop() as hex_cube
dim as hex_cube h_
dim as integer ub = ubound(h)
if ub >= 0 then
h_ = h(ub)
if ub = 0 then
erase h
else
redim preserve h(ub - 1)
end if
end if
return h_
end function
sub hex_list.del_()
erase(h)
end sub
function hex_list.size() as integer
return ubound(h) + 1
end function
function hex_list.last_index() as integer
return ubound(h)
end function
'------------------------ a simple point <vextor> class ------------------------
type pt_dbl
dim as double x, y
end type
type pt_list
private:
dim as pt_dbl pt(any)
public:
declare function push(pt_ as pt_dbl) as integer
declare function pop() as pt_dbl
declare sub del_()
declare function size() as integer
declare function last_index() as integer
end type
'add to end of list
function pt_list.push(pt_ as pt_dbl) as integer
dim as integer ub = ubound(pt) + 1
redim preserve pt(ub)
pt(ub) = pt_
return ub
end function
'remove from end of list
function pt_list.pop() as pt_dbl
dim as pt_dbl pt_
dim as integer ub = ubound(pt)
if ub >= 0 then
pt_ = pt(ub)
if ub = 0 then
erase pt
else
redim preserve pt(ub - 1)
end if
end if
return pt_
end function
sub pt_list.del_()
erase(pt)
end sub
function pt_list.size() as integer
return ubound(pt) + 1
end function
function pt_list.last_index() as integer
return ubound(pt)
end function
'--------------------------------- hex layout ----------------------------------
type hex_orientation
dim as const double f0, f1, f2, f3
dim as const double b0, b1, b2, b3
dim as const double start_angle 'in multiples of 60°
end type
dim shared as const hex_orientation layout_pointy = type( _
sqrt(3), sqrt(3)/2, 0, 3/2, _
sqrt(3)/3, -1/3, 0, 2/3, _
0.5)
dim shared as const hex_orientation layout_flat = type( _
3/2, 0, sqrt(3)/2, sqrt(3), _
2/3, 0, -1/3, sqrt(3)/3, _
0.0)
type hex_layout
dim as const hex_orientation orientation
dim as const pt_dbl size
dim as const pt_dbl origin
end type
'Hex to Pixel
function hex_to_pixel(layout as hex_layout, h as hex_axial) as pt_dbl
dim byref as const hex_orientation M = layout.orientation
dim as double x = (M.f0 * h.q + M.f1 * h.r) * layout.size.x
dim as double y = (M.f2 * h.q + M.f3 * h.r) * layout.size.y
return type(x + layout.origin.x, y + layout.origin.y)
end function
type hex_cube_frac
dim as double x, y, z
end type
'Pixel to Hex (fractional)
function pixel_to_hex_frac(layout as hex_layout, p as pt_dbl) as hex_cube_frac
dim byref as const hex_orientation M = layout.orientation
dim as pt_dbl pt = type(_
(p.x - layout.origin.x) / layout.size.x, _
(p.y - layout.origin.y) / layout.size.y)
dim as double q = M.b0 * pt.x + M.b1 * pt.y
dim as double r = M.b2 * pt.x + M.b3 * pt.y
return type(q, r, -(q + r))
end function
'hex cube rounding
function hex_round(h as hex_cube_frac) as hex_cube
dim as integer x = int(h.x) 'is this right?
dim as integer y = int(h.y)
dim as integer z = int(h.z)
dim as double x_diff = abs(x - h.x) 'q
dim as double y_diff = abs(y - h.y) 'r
dim as double z_diff = abs(z - h.z) 's
if (x_diff > y_diff) and (x_diff > z_diff) then
x = -(y + z)
elseif (y_diff > z_diff) then
y = -(x + z)
else
z = -(x + y)
end if
return type(x, y, z)
end function
'Pixel to Hex (integer)
function pixel_to_hex_int(layout as hex_layout, p as pt_dbl) as hex_cube
return hex_round(pixel_to_hex_frac(layout, p))
end function
function hex_lerp(a as hex_cube, b as hex_cube, t as double) as hex_cube_frac
return type(lerp(a.x, b.x, t), lerp(a.y, b.y, t), lerp(a.z, b.z, t))
end function
'~ 'return list of hex (with cube coordinates)
function hex_line_list(a as hex_cube, b as hex_cube) as hex_list
dim as integer N = hex_distance(a, b)
dim as hex_list hexes
dim as double dist_step = 1.0 / max(N, 1)
for i as integer = 0 to N
hexes.push(hex_round(hex_lerp(a, b, dist_step * i)))
next
return hexes
end function
'relative corner position from hexagon center
'note: for speed, the corner positions can be precalculated (after setting size)
function hex_corner_offset(layout as hex_layout, corner as integer) as pt_dbl
dim as pt_dbl size = layout.size
dim as double angle = 2.0 * M_PI * (layout.orientation.start_angle + corner) / 6
return type(size.x * cos(angle), size.y * sin(angle))
end function
function hex_corner_list(layout as hex_layout, h as hex_axial) as pt_list
dim as pt_list corners
dim as pt_dbl center = hex_to_pixel(layout, h)
for i as integer = 0 to 5 'loop 6 corners
dim as pt_dbl offset = hex_corner_offset(layout, i)
corners.push(type(center.x + offset.x, center.y + offset.y))
next
return corners
end function
sub hex_draw_outline(layout as hex_layout, h as hex_axial, colour as ulong)
dim as pt_list corners = hex_corner_list(layout, h)
'~ for i as integer = 0 to 5
'~ dim as integer j = (i + 1) mod 6
'~ line(corners.pt(i).x, corners.pt(i).y)-_
'~ (corners.pt(j).x, corners.pt(j).y), colour
'~ next
dim as pt_dbl first = corners.pop() 'save for last loop
dim as pt_dbl b = first
for i as integer = 0 to 5
dim as pt_dbl a = b
b = iif(i = 5, first, corners.pop())
next
end sub
'-------------------------------------------------------------------------------
screenres 800, 600, 32
dim as hex_layout layout = type(layout_pointy, type(30, 30), type(100, 100))
'dim as hex_layout layout = type<hex_layout>(layout_pointy, type(30, 30), type(100, 100))
'dim as hex_layout layout = type(layout_pointy) 'is allowed
'layout.orientation = layout_pointy 'not allowed
'layout.size = type(30, 30) 'not allowed
'layout.origin
getkey()