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
|
||||
.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 subcmds_dev(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[]);
|
||||
|
|
|
|||
|
|
@ -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("subcmds", subcmds_subcmd, NULL);
|
||||
register_subcmd("dev", subcmds_dev, NULL);
|
||||
register_subcmd("games", games_subcmd, NULL);
|
||||
|
||||
/* if the user didn't specify a config path */
|
||||
if (!config_path) {
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ stopwatch_subcmd(void *, int argc, char *argv[])
|
|||
|
||||
if (pfd.revents & POLLIN) {
|
||||
read(pfd.fd, buf, PATH_MAX);
|
||||
ds_dll_insert(laps, (void *)(long)i);
|
||||
ds_dll_append(laps, (void *)(long)i);
|
||||
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