switch to zig build system and add conways game of life
This commit is contained in:
parent
408de3a337
commit
f219f0c5ce
12 changed files with 227 additions and 73 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,2 +1,4 @@
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
.cache
|
.cache
|
||||||
|
.zig-cache
|
||||||
|
zig-out
|
||||||
|
|
|
||||||
9
.gitmodules
vendored
9
.gitmodules
vendored
|
|
@ -1,9 +0,0 @@
|
||||||
[submodule "lib/log.c"]
|
|
||||||
path = lib/log.c
|
|
||||||
url = https://github.com/rxi/log.c
|
|
||||||
[submodule "lib/ds"]
|
|
||||||
path = lib/ds
|
|
||||||
url = https://git.squi.bid/squibid/ds
|
|
||||||
[submodule "lib/cargs"]
|
|
||||||
path = lib/cargs
|
|
||||||
url = https://github.com/likle/cargs
|
|
||||||
81
build.zig
Normal file
81
build.zig
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const ds = b.dependency("ds", .{});
|
||||||
|
const cargs = b.dependency("cargs", .{});
|
||||||
|
const log = b.dependency("log.c", .{});
|
||||||
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "wom",
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.link_libc = true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const games = b.addLibrary(.{
|
||||||
|
.name = "games",
|
||||||
|
.linkage = .static,
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.root_source_file = b.path("src/subcmds/games.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.link_libc = true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
games.pie = true;
|
||||||
|
|
||||||
|
exe.root_module.addCSourceFiles(.{
|
||||||
|
.files = &.{
|
||||||
|
"src/main.c",
|
||||||
|
"src/conf.c",
|
||||||
|
"src/api.c",
|
||||||
|
|
||||||
|
"src/subcmds/clock.c",
|
||||||
|
"src/subcmds/dev.c",
|
||||||
|
"src/subcmds/motd.c",
|
||||||
|
"src/subcmds/project.c",
|
||||||
|
"src/subcmds/subcmds.c",
|
||||||
|
|
||||||
|
"src/lua/wom.c",
|
||||||
|
"src/lua/wom_fs.c",
|
||||||
|
},
|
||||||
|
.flags = &.{
|
||||||
|
"-DVERSION=\"hi\"",
|
||||||
|
"-std=c23",
|
||||||
|
"-D_GNU_SOURCE",
|
||||||
|
"-MJ compile_commands.json",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exe.root_module.linkLibrary(games);
|
||||||
|
exe.root_module.linkSystemLibrary("lua", .{});
|
||||||
|
|
||||||
|
exe.root_module.addIncludePath(b.path("include"));
|
||||||
|
exe.root_module.addLibraryPath(ds.path("."));
|
||||||
|
exe.root_module.addLibraryPath(cargs.path("src"));
|
||||||
|
exe.root_module.addLibraryPath(log.path("src"));
|
||||||
|
|
||||||
|
exe.addCSourceFile(.{ .file = ds.builder.path("./ds.c") });
|
||||||
|
exe.addCSourceFile(.{ .file = cargs.builder.path("src/cargs.c") });
|
||||||
|
exe.addCSourceFile(.{ .file = log.builder.path("./src/log.c") });
|
||||||
|
|
||||||
|
exe.root_module.addIncludePath(ds.path("."));
|
||||||
|
exe.root_module.addIncludePath(cargs.path("include"));
|
||||||
|
exe.root_module.addIncludePath(log.path("src"));
|
||||||
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
const run_cmd = b.addRunArtifact(exe);
|
||||||
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
|
||||||
|
if (b.args) |args| {
|
||||||
|
run_cmd.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
}
|
||||||
20
build.zig.zon
Normal file
20
build.zig.zon
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
.{
|
||||||
|
.name = .womblic,
|
||||||
|
.version = "0.15.2",
|
||||||
|
.dependencies = .{
|
||||||
|
.ds = .{
|
||||||
|
.url = "git+https://git.squi.bid/squibid/ds#758edf9d3049c61aa0036c8239f9fa922905a387",
|
||||||
|
.hash = "N-V-__8AALpEAACaGIC6yceiHvUlUJ-DX3QMaZ9I6uiDgclh",
|
||||||
|
},
|
||||||
|
.cargs = .{
|
||||||
|
.url = "git+https://github.com/likle/cargs#0698c3f90333446d0fc2745c1e9ce10dd4a9497a",
|
||||||
|
.hash = "N-V-__8AAPD5AQDYgLFfeI5K_q70qlurwjhY_e403fseMs3O",
|
||||||
|
},
|
||||||
|
.@"log.c" = .{
|
||||||
|
.url = "git+https://github.com/rxi/log.c#f9ea34994bd58ed342d2245cd4110bb5c6790153",
|
||||||
|
.hash = "N-V-__8AAJ8jAAAVkKD-RFvNLcnmi3SJZWigTFePQTb0sG-u",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.paths = .{""},
|
||||||
|
.fingerprint = 0x9cc5d26802316aa6,
|
||||||
|
}
|
||||||
|
|
@ -9,4 +9,5 @@ void timer_subcmd(void *, int argc, char *argv[]);
|
||||||
void stopwatch_subcmd(void *, int argc, char *argv[]);
|
void stopwatch_subcmd(void *, int argc, char *argv[]);
|
||||||
void subcmds_dev(void *, int argc, char *argv[]);
|
void subcmds_dev(void *, int argc, char *argv[]);
|
||||||
void motd_subcmd(void *, int argc, char *argv[]);
|
void motd_subcmd(void *, int argc, char *argv[]);
|
||||||
|
void games_subcmd(void *, int argc, char *argv[]);
|
||||||
void subcmds_subcmd(void *, int argc, char *argv[]);
|
void subcmds_subcmd(void *, int argc, char *argv[]);
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 0698c3f90333446d0fc2745c1e9ce10dd4a9497a
|
|
||||||
1
lib/ds
1
lib/ds
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 5e4ae41113e63004bd131010853e5265b31302d3
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit f9ea34994bd58ed342d2245cd4110bb5c6790153
|
|
||||||
60
meson.build
60
meson.build
|
|
@ -1,60 +0,0 @@
|
||||||
project('womblic', 'c',
|
|
||||||
version: '0.0.1',
|
|
||||||
license: 'GPLv3')
|
|
||||||
|
|
||||||
add_project_arguments([
|
|
||||||
'-DVERSION="@0@"'.format(meson.project_version()),
|
|
||||||
'-DLOG_USE_COLOR' # enable colored logs
|
|
||||||
], language: 'c')
|
|
||||||
|
|
||||||
# get all the source files for the executable
|
|
||||||
luafiles = files(
|
|
||||||
'src/lua/wom.c',
|
|
||||||
'src/lua/wom_fs.c'
|
|
||||||
)
|
|
||||||
|
|
||||||
subcmds = files(
|
|
||||||
'src/subcmds/clock.c',
|
|
||||||
'src/subcmds/dev.c',
|
|
||||||
'src/subcmds/motd.c',
|
|
||||||
'src/subcmds/project.c',
|
|
||||||
'src/subcmds/subcmds.c',
|
|
||||||
)
|
|
||||||
|
|
||||||
srcfiles = files(
|
|
||||||
'src/main.c',
|
|
||||||
'src/api.c',
|
|
||||||
'src/conf.c'
|
|
||||||
) + luafiles + subcmds
|
|
||||||
|
|
||||||
cc = meson.get_compiler('c')
|
|
||||||
math_dep = cc.find_library('m', required: true)
|
|
||||||
|
|
||||||
# build the executable
|
|
||||||
executable('wom', srcfiles,
|
|
||||||
dependencies: [
|
|
||||||
dependency('lua', version: '>=5.1 <6.0'),
|
|
||||||
math_dep,
|
|
||||||
],
|
|
||||||
include_directories: [
|
|
||||||
include_directories('include'),
|
|
||||||
|
|
||||||
include_directories('lib/log.c/src'),
|
|
||||||
include_directories('lib/ds'),
|
|
||||||
include_directories('lib/cargs/include'),
|
|
||||||
],
|
|
||||||
link_with: [
|
|
||||||
static_library('ds', 'lib/ds/ds.c',
|
|
||||||
include_directories: 'lib/ds'),
|
|
||||||
|
|
||||||
static_library('log.c', 'lib/log.c/src/log.c',
|
|
||||||
include_directories: 'lib/log.c/src'),
|
|
||||||
|
|
||||||
static_library('cargs', 'lib/cargs/src/cargs.c',
|
|
||||||
include_directories: 'lib/cargs/include'),
|
|
||||||
],
|
|
||||||
install: true
|
|
||||||
)
|
|
||||||
install_data('completions/_wom.zsh',
|
|
||||||
install_dir: '/usr/local/share/zsh/site-functions/'
|
|
||||||
)
|
|
||||||
|
|
@ -100,6 +100,7 @@ main(int argc, char *argv[])
|
||||||
register_subcmd("stopwatch", stopwatch_subcmd, NULL);
|
register_subcmd("stopwatch", stopwatch_subcmd, NULL);
|
||||||
register_subcmd("subcmds", subcmds_subcmd, NULL);
|
register_subcmd("subcmds", subcmds_subcmd, NULL);
|
||||||
register_subcmd("dev", subcmds_dev, NULL);
|
register_subcmd("dev", subcmds_dev, NULL);
|
||||||
|
register_subcmd("games", games_subcmd, NULL);
|
||||||
|
|
||||||
/* if the user didn't specify a config path */
|
/* if the user didn't specify a config path */
|
||||||
if (!config_path) {
|
if (!config_path) {
|
||||||
|
|
|
||||||
|
|
@ -344,7 +344,7 @@ stopwatch_subcmd(void *, int argc, char *argv[])
|
||||||
|
|
||||||
if (pfd.revents & POLLIN) {
|
if (pfd.revents & POLLIN) {
|
||||||
read(pfd.fd, buf, PATH_MAX);
|
read(pfd.fd, buf, PATH_MAX);
|
||||||
ds_dll_insert(laps, (void *)(long)i);
|
ds_dll_append(laps, (void *)(long)i);
|
||||||
up++;
|
up++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
121
src/subcmds/games.zig
Normal file
121
src/subcmds/games.zig
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const gpa = std.heap.page_allocator;
|
||||||
|
|
||||||
|
const Conway = struct {
|
||||||
|
generation: u64 = 0,
|
||||||
|
width: u64,
|
||||||
|
height: u64,
|
||||||
|
world: [][]*Cell,
|
||||||
|
|
||||||
|
const Cell = struct {
|
||||||
|
/// storage of neighbors
|
||||||
|
/// ? 0 ?
|
||||||
|
/// 1 x 2
|
||||||
|
/// ? 3 ?
|
||||||
|
/// instead of storing all 8 neighbors I've decided to contact them
|
||||||
|
/// through our other neighbors.
|
||||||
|
neighbors: [4]?*Cell = .{ null, null, null, null },
|
||||||
|
/// the state on the current generation
|
||||||
|
alive: bool = false,
|
||||||
|
/// the state on the next generation
|
||||||
|
will_live: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(width: u64, height: u64) !Conway {
|
||||||
|
var self: Conway = .{
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
.world = undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
// create the world and the cells
|
||||||
|
self.world = try gpa.alloc([]*Cell, width);
|
||||||
|
for (self.world, 0..) |col, i| {
|
||||||
|
self.world[i] = try gpa.alloc(*Cell, height);
|
||||||
|
for (col, 0..) |_, j| {
|
||||||
|
if (j >= height) break;
|
||||||
|
self.world[i][j] = try gpa.create(Cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize all the cell properties
|
||||||
|
for (self.world, 0..) |col, i| for (col, 0..) |cell, j| {
|
||||||
|
// the top row has nothing above it
|
||||||
|
cell.neighbors[0] = if (j == 0) null else self.world[i][j - 1];
|
||||||
|
// the left column has nothing on the left
|
||||||
|
cell.neighbors[1] = if (i == 0) null else self.world[i - 1][j];
|
||||||
|
// the right row has nothing on the right
|
||||||
|
cell.neighbors[2] = if (i == width - 1) null else self.world[i + 1][j];
|
||||||
|
// the bottom row has nothing below it
|
||||||
|
cell.neighbors[3] = if (j == height - 1) null else self.world[i][j + 1];
|
||||||
|
cell.alive = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn step(self: *Conway) void {
|
||||||
|
for (self.world) |col| for (col) |cell| {
|
||||||
|
var alive_neighbors: u4 = 0;
|
||||||
|
|
||||||
|
// count the neighbors
|
||||||
|
for (cell.neighbors, 0..) |n, i| {
|
||||||
|
if (n == null) continue;
|
||||||
|
if (i == 0 or i == 3) {
|
||||||
|
if (n.?.neighbors[1]) |nn| if (nn.alive) {
|
||||||
|
alive_neighbors += 1;
|
||||||
|
};
|
||||||
|
if (n.?.neighbors[2]) |nn| if (nn.alive) {
|
||||||
|
alive_neighbors += 1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (n.?.alive) alive_neighbors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rules
|
||||||
|
if (cell.alive) {
|
||||||
|
cell.will_live = switch (alive_neighbors) {
|
||||||
|
2, 3 => true,
|
||||||
|
else => false
|
||||||
|
};
|
||||||
|
} else if (alive_neighbors == 3) cell.will_live = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (self.world) |col| for (col) |cell| {
|
||||||
|
cell.alive = cell.will_live;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print(self: *Conway) void {
|
||||||
|
for (self.world) |col| {
|
||||||
|
for (col) |cell| {
|
||||||
|
std.debug.print("{s}", .{if (cell.alive) "x" else " "});
|
||||||
|
}
|
||||||
|
std.debug.print("\n", .{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub export fn games_subcmd(_: *anyopaque, argc: c_int, argv: [*c]u8) callconv(.c) void {
|
||||||
|
_ = argc;
|
||||||
|
_ = argv;
|
||||||
|
|
||||||
|
var con = Conway.init(40, 40) catch unreachable;
|
||||||
|
con.world[4][2].alive = true;
|
||||||
|
con.world[4][3].alive = true;
|
||||||
|
con.world[4][4].alive = true;
|
||||||
|
con.world[4][5].alive = true;
|
||||||
|
con.world[4][6].alive = true;
|
||||||
|
con.world[4][7].alive = true;
|
||||||
|
con.world[5][2].alive = true;
|
||||||
|
con.world[5][3].alive = true;
|
||||||
|
con.world[5][4].alive = true;
|
||||||
|
con.world[5][5].alive = true;
|
||||||
|
con.world[5][6].alive = true;
|
||||||
|
|
||||||
|
while (true) : (con.step()) {
|
||||||
|
con.print();
|
||||||
|
std.posix.nanosleep(0, 250000000);
|
||||||
|
std.debug.print("\x1B[{}A", .{con.height});
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue