this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: worldgen

+121 -44
+74 -28
src/hex.zig
··· 5 5 const sqrt_3: comptime_float = std.math.sqrt(3.0); 6 6 7 7 pub const Point = struct { x: f32, y: f32 }; 8 - pub const HexCell = struct { inner_radius: f32, outer_radius: f32, height: f32, width: f32, center: Point }; 8 + 9 + // Cubic coordinates: q + r + s = 0 constraint 10 + pub const Cubic = struct { 11 + q: i32, 12 + r: i32, 13 + s: i32, 14 + 15 + pub fn init(q: i32, r: i32) Cubic { 16 + return .{ .q = q, .r = r, .s = -q - r }; 17 + } 18 + 19 + pub fn add(self: Cubic, other: Cubic) Cubic { 20 + return .{ .q = self.q + other.q, .r = self.r + other.r, .s = self.s + other.s }; 21 + } 22 + 23 + pub fn sub(self: Cubic, other: Cubic) Cubic { 24 + return .{ .q = self.q - other.q, .r = self.r - other.r, .s = self.s - other.s }; 25 + } 26 + 27 + pub fn neighbor(self: Cubic, dir: Direction) Cubic { 28 + return self.add(direction_vectors[@intFromEnum(dir)]); 29 + } 30 + 31 + pub fn toPixel(self: Cubic, size: f32) Point { 32 + const q: f32 = @floatFromInt(self.q); 33 + const r: f32 = @floatFromInt(self.r); 34 + return .{ 35 + .x = size * (1.5 * q), 36 + .y = size * (sqrt_3 * (r + q / 2.0)), 37 + }; 38 + } 39 + 40 + pub fn toOffset(self: Cubic) Offset { 41 + const col = self.q; 42 + const row = self.r + @divFloor(self.q, 2); 43 + return .{ .col = col, .row = row }; 44 + } 45 + }; 46 + 47 + pub const Offset = struct { 48 + col: i32, 49 + row: i32, 50 + 51 + pub fn toCubic(self: Offset) Cubic { 52 + const q = self.col; 53 + const r = self.row - @divFloor(self.col, 2); 54 + return Cubic.init(q, r); 55 + } 56 + }; 57 + 58 + const direction_vectors = [6]Cubic{ 59 + .{ .q = 0, .r = -1, .s = 1 }, // top_left 60 + .{ .q = 1, .r = -1, .s = 0 }, // top 61 + .{ .q = 1, .r = 0, .s = -1 }, // top_right 62 + .{ .q = 0, .r = 1, .s = -1 }, // bottom_right 63 + .{ .q = -1, .r = 1, .s = 0 }, // bottom 64 + .{ .q = -1, .r = 0, .s = 1 }, // bottom_left 65 + }; 66 + 67 + pub const HexCell = struct { inner_radius: f32, outer_radius: f32, height: f32, width: f32, center: Point, cubic: Cubic }; 68 + pub const Cell = HexCell; 69 + 9 70 pub const HexDirections = enum { top_left, top, top_right, bottom_right, bottom, bottom_left }; 71 + pub const Direction = HexDirections; 10 72 11 73 fn calculate_outer_radius(inner_radius: f32) f32 { 12 74 return 2.0 * inner_radius / sqrt_3; ··· 26 88 return Point{ .x = center.x + x_offset, .y = center.y + y_offset }; 27 89 } 28 90 29 - pub fn new_hex(outer_radius: f32, center: Point) HexCell { 91 + pub fn new_hex(outer_radius: f32, cubic: Cubic) HexCell { 92 + const size = outer_radius; 93 + const inner = calculate_inner_radius(size); 94 + const center = cubic.toPixel(size); 95 + return HexCell{ .inner_radius = inner, .outer_radius = size, .height = sqrt_3 * size, .width = 2 * size, .center = center, .cubic = cubic }; 96 + } 97 + 98 + pub fn new_hex_at(outer_radius: f32, center: Point) HexCell { 30 99 const size = outer_radius; 31 100 const inner = calculate_inner_radius(size); 32 - return HexCell{ .inner_radius = inner, .outer_radius = size, .height = sqrt_3 * size, .width = 2 * size, .center = center }; 101 + return HexCell{ .inner_radius = inner, .outer_radius = size, .height = sqrt_3 * size, .width = 2 * size, .center = center, .cubic = Cubic.init(0, 0) }; 33 102 } 34 103 35 104 pub fn add_hex(base: HexCell, direction: HexDirections) HexCell { 36 - const x_sign: f32 = switch (direction) { 37 - .bottom_right => 1.0, 38 - .top_right => 1.0, 39 - .top => 0, 40 - .bottom => 0, 41 - .bottom_left => -1, 42 - .top_left => -1, 43 - }; 44 - 45 - const y_sign: f32 = switch (direction) { 46 - .top => -1, 47 - .top_left => -0.5, 48 - .top_right => -0.5, 49 - .bottom_left => 0.5, 50 - .bottom_right => 0.5, 51 - .bottom => 1, 52 - }; 53 - 54 - const x_offset: f32 = x_sign * 1.5 * base.outer_radius; 55 - const y_offset: f32 = y_sign * base.height; 56 - 57 - return new_hex(base.outer_radius, .{ 58 - .x = base.center.x + x_offset, 59 - .y = base.center.y + y_offset, 60 - }); 105 + const new_cubic = base.cubic.neighbor(direction); 106 + return new_hex(base.outer_radius, new_cubic); 61 107 }
+14 -16
src/main.zig
··· 43 43 //---------------------------------------------------------------------------------- 44 44 // TODO: Update your variables here 45 45 //---------------------------------------------------------------------------------- 46 - const cell = lib.hex.new_hex(50.0, .{ 47 - .x = screenWidth / 2, 48 - .y = screenHeight / 2, 49 - }); 50 - std.debug.print("cell : {}", .{cell}); 51 - 52 - const tl = lib.hex.add_hex(cell, .top_left); 53 - const tr = lib.hex.add_hex(cell, .top_right); 54 - const t = lib.hex.add_hex(cell, .top); 55 - const br = lib.hex.add_hex(cell, .bottom_right); 56 - const bl = lib.hex.add_hex(cell, .bottom_left); 57 - const b = lib.hex.add_hex(cell, .bottom); 58 - 59 - const grid = [_]lib.hex.HexCell{ cell, tl, t, tr, br, b, bl }; 46 + const template = [5][8]u1{ 47 + .{ 1, 1, 1, 1, 1, 1, 1, 1 }, 48 + .{ 1, 1, 1, 0, 0, 1, 1, 1 }, 49 + .{ 1, 1, 0, 0, 0, 0, 1, 1 }, 50 + .{ 1, 1, 1, 0, 0, 1, 1, 1 }, 51 + .{ 1, 1, 1, 1, 1, 1, 1, 1 }, 52 + }; 53 + const grid = lib.world.generateWorld(5, 8, &template, 40.0); 60 54 61 55 // Draw 62 56 //---------------------------------------------------------------------------------- ··· 65 59 66 60 rl.clearBackground(.white); 67 61 68 - for (grid) |value| { 69 - draw_hex(value); 62 + for (grid) |row| { 63 + for (row) |maybe_cell| { 64 + if (maybe_cell) |cell| { 65 + draw_hex(cell); 66 + } 67 + } 70 68 } 71 69 72 70 //rl.drawText("Congrats! You created your first window!", 190, 200, 20, .light_gray);
+1
src/root.zig
··· 1 1 //! By convention, root.zig is the root source file when making a library. 2 2 pub const hex = @import("hex.zig"); 3 + pub const world = @import("world.zig");
+32
src/world.zig
··· 1 + const std = @import("std"); 2 + const hex = @import("hex.zig"); 3 + const tst = std.testing; 4 + 5 + pub fn generateWorld(comptime H: usize, comptime W: usize, template: *const [H][W]u1, outer_radius: f32) [H][W]?hex.Cell { 6 + var grid: [H][W]?hex.Cell = undefined; 7 + 8 + for (0..H) |row| { 9 + for (0..W) |col| { 10 + if (template[row][col] == 1) { 11 + const offset = hex.Offset{ .col = @intCast(col), .row = @intCast(row) }; 12 + grid[row][col] = hex.new_hex(outer_radius, offset.toCubic()); 13 + } else { 14 + grid[row][col] = null; 15 + } 16 + } 17 + } 18 + 19 + return grid; 20 + } 21 + 22 + test "generateWorld creates grid from template" { 23 + const template = [3][3]u1{ 24 + .{ 1, 1, 0 }, 25 + .{ 1, 0, 1 }, 26 + .{ 0, 1, 1 }, 27 + }; 28 + const grid = generateWorld(3, 3, &template, 50.0); 29 + try tst.expect(grid[0][0] != null); 30 + try tst.expect(grid[0][2] == null); 31 + try tst.expect(grid[1][1] == null); 32 + }