const std = @import("std"); pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); // const allocator = gpa.allocator(); // var input = Wire{ .digital = false, .analog = 1.0 }; // var input_buffer = Not{ .invert_output = false, .input = &input }; // // analog in // var wire1 = Wire{}; // var wire2 = Wire{}; // var wire3 = Wire{}; // // orange battery // var wire4 = Wire{}; // var wire5 = Wire{}; // var wire6 = Wire{}; // // cblueorange battery // var wire7 = Wire{}; // var wire8 = Wire{}; // var wire9 = Wire{}; // // red battery // var wire10 = Wire{}; // var wire11 = Wire{}; // // grey OR gates // var wire12 = Wire{}; // var wire13 = Wire{}; // var wire14 = Wire{}; // var wire15 = Wire{}; // // pink OR gates // var wire16 = Wire{}; // var wire17 = Wire{}; // var wire18 = Wire{}; // // right side flippity floppities // var wire19 = Wire{}; // var wire20 = Wire{}; // var wire21 = Wire{}; // var wire22 = Wire{}; // var wire23 = Wire{}; // var battery1 = Battery{ .value = -0.5 }; // var battery2 = Battery{ .value = 0.5 }; // var battery3 = Battery{ .value = -1.0 }; // var or1_inputs = [_]*Wire{ &wire1, &wire2, &wire3 }; // var or1 = Or{ .inputs = &or1_inputs }; // var or2_inputs = [_]*Wire{ &}; // var or2 = Or{ .inputs = &or2_inputs }; // var or3_inputs = [_]*Wire{}; // var or3 = Or{ .inputs = &or3_inputs }; // var or4_inputs = [_]*Wire{}; // var or4 = Or{ .inputs = &or4_inputs }; // var or5_inputs = [_]*Wire{}; // var or5 = Or{ .inputs = &or5_inputs }; // var or6_inputs = [_]*Wire{}; // var or6 = Or{ .inputs = &or6_inputs }; // var and1 = And{}; // var or7_inputs = [_]*Wire{}; // var or7 = Or{ .inputs = &or7_inputs }; // var and2 = And{}; // var or8_inputs = [_]*Wire{}; // var or8 = Or{ .inputs = &or8_inputs }; // std.debug.print("{}\n", .{wire3}); } pub const Component = struct { x: u16 = 0, y: u16 = 0, processFn: *const fn (*Component) void, }; pub const Circuit = struct { width: u16 = 8, height: u16 = 8, components: std.ArrayList(Component), }; pub const Battery = struct { component: Component = .{ .processFn = process }, value: f32, pub fn process(component: *Component, inputs: []*Signal) []Signal { _ = inputs; const self: *Battery = @fieldParentPtr("component", component); return &[_]Signal{.{ .digital = std.math.sign(self.value), .analog = self.value, }}; } }; pub const Signal = struct { digital: i2 = 0, analog: f32 = 0.0, color: u24 = 0, }; // pub const Wire = struct { // digital: bool = false, // analog: f32 = 0.0, // pub fn format(self: Wire, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { // _ = .{ fmt, options }; // try writer.print("Wire({s} | {d:0>1.4})", .{ // if (self.digital) "1" else "0", // self.analog, // }); // } // fn analogSet(self: *Wire, value: f32) void { // self.analog = std.math.clamp(value, 0.0, 1.0); // } // }; // pub const Battery = struct { // // component: Component = .{}, // output: *Wire, // value: f32, // invert_output: bool = false, // pub fn process(self: *Battery) void { // if (self.invert_output) { // self.output.digital = self.value != 0.0; // self.output.analogSet(self.value); // } else { // self.output.digital = self.value == 0.0; // self.output.analogSet(1.0 - @abs(self.value)); // } // } // }; // pub const Not = struct { // // component: Component = .{}, // input: *Wire, // output: *Wire, // invert_output: bool = true, // pub fn process(self: *Not) void { // if (self.invert_output) { // self.output.digital = !self.input.digital; // self.output.analogSet(1.0 - @abs(self.input.analog)); // } else { // self.output.digital = self.input.digital; // self.output.analogSet(self.input.analog); // TODO does the output get clamped here? // } // } // }; // pub const And = struct { // // component: Component, // inputs: []*Wire, // output: *Wire, // // if false, is in Minimum Input mode // // if true, is in Multiply Inputs mode // arithmetic_mode: bool = false, // // TODO check implementation // pub fn process(self: *And) void { // if (self.arithmetic_mode) { // self.output.digital = self.inputs[0].digital; // self.output.analog = self.inputs[0].analog; // for (self.inputs[1..]) |input| { // self.output.digital = self.output.digital and input.digital; // self.output.analog *= input.analog; // } // } else { // self.output.digital = self.inputs[0].digital; // self.output.analog = self.inputs[0].analog; // for (self.inputs[1..]) |input| { // self.output.digital = self.output.digital and input.digital; // self.output.analog = @min(self.output.analog, input.analog); // } // } // self.output.analog = std.math.clamp(self.output.analog, 0.0, 1.0); // // var digital = self.inputs[0].digital; // // if (digital) for (1..self.inputs.len - 1) |i| if (!self.inputs[i].digital) { // // digital = false; // // break; // // }; // // self.output.digital = digital; // // var best = self.inputs[0].analog; // // for (self.inputs[1..]) |input| best = @min(best, input.analog); // // self.output.analog = best; // } // }; // pub const Or = struct { // // component: Component, // inputs: []*Wire, // output: *Wire, // // if false, is in Maximum Input mode // // if true, is in Add Inputs mode // arithmetic_mode: bool = false, // // TODO check implementation // pub fn process(self: *Or) void { // if (self.arithmetic_mode) { // self.output.digital = self.inputs[0].digital; // self.output.analog = self.inputs[0].analog; // for (self.inputs[1..]) |input| { // self.output.digital = self.output.digital and input.digital; // self.output.analog += input.analog; // } // } else { // self.output.digital = self.inputs[0].digital; // self.output.analog = self.inputs[0].analog; // for (self.inputs[1..]) |input| { // self.output.digital = self.output.digital and input.digital; // self.output.analog = @max(self.output.analog, input.analog); // } // } // self.output.analog = std.math.clamp(self.output.analog, 0.0, 1.0); // // self.output.digital = 1; // // for (self.inputs) |input| if (input.digital) { // // self.output.digital = true; // // break; // // }; // } // };