colors wow
This commit is contained in:
parent
58161aae25
commit
ef2679d872
2 changed files with 200 additions and 179 deletions
30
src/main.zig
30
src/main.zig
|
|
@ -1,6 +1,16 @@
|
|||
const std = @import("std");
|
||||
|
||||
const sand = @import("sand");
|
||||
const s = @import("sand");
|
||||
|
||||
// const colorType = packed struct {
|
||||
// r: u8,
|
||||
// g: u8,
|
||||
// b: u8,
|
||||
// };
|
||||
//
|
||||
// const sand = s.init(colorType, .{ .r = 0, .g = 0, .b = 0 });
|
||||
|
||||
const sand = s.init(u9, 0);
|
||||
|
||||
const pow = std.math.pow;
|
||||
|
||||
|
|
@ -48,6 +58,8 @@ pub fn main(init: std.process.Init) !void {
|
|||
|
||||
var placeChace: u8 = 250;
|
||||
|
||||
var slider: u9 = 1;
|
||||
|
||||
raylib.setTargetFPS(50);
|
||||
|
||||
var timeForUpdate: u64 = 0;
|
||||
|
|
@ -84,10 +96,11 @@ pub fn main(init: std.process.Init) !void {
|
|||
const drawTimer = std.Io.Clock.now(.awake, init.io);
|
||||
for (grid.arr, 0..) |line, y| {
|
||||
for (line, 0..) |cell, x| {
|
||||
texture[x + screenWidth * y] = if (cell.alive)
|
||||
raylib.Color.init(@truncate((255 * y) / screenHeight), @truncate((255 * x) / screenWidth), 0, 255)
|
||||
else
|
||||
.black;
|
||||
//texture[x + screenWidth * y] = if (!(cell == sand.dead))
|
||||
// raylib.Color.init(@truncate((255 * y) / screenHeight), @truncate((255 * x) / screenWidth), 0, 255)
|
||||
//else
|
||||
// .black;
|
||||
texture[x + screenWidth * y] = if (cell == 0) .black else raylib.Color.fromHSV(cell - 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -115,19 +128,20 @@ pub fn main(init: std.process.Init) !void {
|
|||
if (circleAsyncArray) |_| {} else circleAsyncArray = try init.gpa.alloc(std.Io.Future(void), xend - xstart);
|
||||
for (xstart..xend, 0..) |x, i| {
|
||||
circleAsyncArray.?[i] = init.io.async((struct {
|
||||
pub fn l(IP: raylib.Vector2, IS: f32, fx: usize, rand: *std.Random.DefaultPrng, gr: sand.Grid, pc: u8) void {
|
||||
pub fn l(IP: raylib.Vector2, IS: f32, fx: usize, rand: *std.Random.DefaultPrng, gr: sand.Grid, pc: u8, slid: u9) void {
|
||||
const ystart: usize = @intCast(@max(0, @as(i32, @trunc(IP.y - IS))));
|
||||
const yend: usize = @intCast(@max(0, @as(i32, @trunc(IP.y + IS))));
|
||||
for (ystart..yend) |y| {
|
||||
const dx = @as(f32, @floatFromInt(fx)) - IP.x;
|
||||
const dy = @as(f32, @floatFromInt(y)) - IP.y;
|
||||
if (fx >= screenWidth or y >= screenHeight) {} else if (pow(f32, dx, 2) + pow(f32, dy, 2) <= pow(f32, IS, 2) and rand.random().int(u8) > pc)
|
||||
gr.arr[y][fx].alive = true;
|
||||
gr.arr[y][fx] = slid;
|
||||
}
|
||||
}
|
||||
}).l, .{ IndicatorPosition, IndicatorSize, x, &random, grid, placeChace });
|
||||
}).l, .{ IndicatorPosition, IndicatorSize, x, &random, grid, placeChace, slider });
|
||||
}
|
||||
}
|
||||
slider = (slider % 361) + 1;
|
||||
}
|
||||
if (circleAsyncArray) |arr| {
|
||||
for (arr) |*a| {
|
||||
|
|
|
|||
377
src/root.zig
377
src/root.zig
|
|
@ -2,7 +2,6 @@
|
|||
const std = @import("std");
|
||||
const Io = std.Io;
|
||||
|
||||
pub const state = enum(u1) { Alive, Dead };
|
||||
pub const leaning = enum(u1) {
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
|
|
@ -10,211 +9,219 @@ pub const leaning = enum(u1) {
|
|||
return @enumFromInt(@intFromBool(self == .Left));
|
||||
}
|
||||
};
|
||||
pub const cell = struct {
|
||||
alive: bool,
|
||||
};
|
||||
//pub const cell = struct {
|
||||
// alive: state,
|
||||
//};
|
||||
|
||||
pub const position = packed struct {
|
||||
x: u16,
|
||||
y: u16,
|
||||
};
|
||||
|
||||
pub const Grid = struct {
|
||||
arr: [][]cell,
|
||||
max: position,
|
||||
leaning: leaning,
|
||||
pub fn format(self: @This(), writer: *std.Io.Writer) std.Io.Writer.Error!void {
|
||||
for (self.arr) |line| {
|
||||
for (line) |grain| {
|
||||
try writer.writeAll(if (grain.alive) "" else "");
|
||||
pub fn init(comptime cell: type, d: cell) type {
|
||||
return struct {
|
||||
pub const dead = d;
|
||||
pub const Grid = struct {
|
||||
arr: [][]cell,
|
||||
max: position,
|
||||
leaning: leaning,
|
||||
pub fn format(self: @This(), writer: *std.Io.Writer) std.Io.Writer.Error!void {
|
||||
for (self.arr) |line| {
|
||||
for (line) |grain| {
|
||||
try writer.writeAll(if (!(grain == dead)) "" else "");
|
||||
}
|
||||
try writer.writeByte('\n');
|
||||
}
|
||||
}
|
||||
try writer.writeByte('\n');
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(x: u16, y: u16, allocator: std.mem.Allocator) std.mem.Allocator.Error!Grid {
|
||||
const arr: [][]cell = try allocator.alloc([]cell, y);
|
||||
for (arr) |*line| {
|
||||
line.* = try allocator.alloc(cell, x);
|
||||
for (line.*) |*c| {
|
||||
c.* = .{ .alive = false };
|
||||
pub fn init(x: u16, y: u16, allocator: std.mem.Allocator) std.mem.Allocator.Error!Grid {
|
||||
const arr: [][]cell = try allocator.alloc([]cell, y);
|
||||
for (arr) |*line| {
|
||||
line.* = try allocator.alloc(cell, x);
|
||||
for (line.*) |*c| {
|
||||
c.* = dead;
|
||||
}
|
||||
}
|
||||
|
||||
return .{
|
||||
.max = position{
|
||||
.x = x - 1,
|
||||
.y = y - 1,
|
||||
},
|
||||
.arr = arr,
|
||||
.leaning = .Left,
|
||||
};
|
||||
}
|
||||
pub fn deinit(self: Grid, allocator: std.mem.Allocator) void {
|
||||
for (self.arr) |line| {
|
||||
allocator.free(line);
|
||||
}
|
||||
allocator.free(self.arr);
|
||||
}
|
||||
}
|
||||
|
||||
return .{
|
||||
.max = position{
|
||||
.x = x - 1,
|
||||
.y = y - 1,
|
||||
},
|
||||
.arr = arr,
|
||||
.leaning = .Left,
|
||||
pub fn updateAll(self: *Grid, allocator: std.mem.Allocator) std.mem.Allocator.Error!void {
|
||||
var newGrid: Grid = try .init(self.max.x + 1, self.max.y + 1, allocator);
|
||||
|
||||
newGrid.leaning = self.leaning.opposite();
|
||||
|
||||
for (0..self.arr.len) |y| {
|
||||
for (0..self.arr[y].len) |x| {
|
||||
update(.{ .y = @truncate(y), .x = @truncate(x) }, self.*, newGrid);
|
||||
}
|
||||
}
|
||||
switch (self.leaning) {
|
||||
.Left => for (0..self.arr.len) |y| {
|
||||
self.updateLineLeftBiased(newGrid, y);
|
||||
},
|
||||
.Right => for (0..self.arr.len) |y| {
|
||||
self.updateLineRightBiased(newGrid, y);
|
||||
},
|
||||
}
|
||||
|
||||
self.deinit(allocator);
|
||||
self.* = newGrid;
|
||||
}
|
||||
|
||||
pub fn updateLineRightBiased(s: Grid, ng: Grid, fy: usize) void {
|
||||
for (0..s.arr[fy].len) |x| {
|
||||
update(.{ .y = @truncate(fy), .x = @truncate(x) }, s, ng);
|
||||
}
|
||||
}
|
||||
pub fn updateLineLeftBiased(s: Grid, ng: Grid, fy: usize) void {
|
||||
for (0..s.arr[fy].len) |x| {
|
||||
update(.{ .y = @truncate(fy), .x = @truncate((s.arr[fy].len - x) - 1) }, s, ng);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateAllConcurrent(self: *Grid, allocator: std.mem.Allocator, io: std.Io, async: []std.Io.Future(void)) (std.mem.Allocator.Error || std.Io.ConcurrentError)!void {
|
||||
var newGrid: Grid = try .init(self.max.x + 1, self.max.y + 1, allocator);
|
||||
|
||||
newGrid.leaning = self.leaning.opposite();
|
||||
|
||||
switch (self.leaning) {
|
||||
.Left => for (0..self.arr.len) |y| {
|
||||
async[y] = try io.concurrent(Grid.updateLineLeftBiased, .{ self.*, newGrid, y });
|
||||
},
|
||||
.Right => for (0..self.arr.len) |y| {
|
||||
async[y] = try io.concurrent(Grid.updateLineRightBiased, .{ self.*, newGrid, y });
|
||||
},
|
||||
}
|
||||
|
||||
for (async) |*a| {
|
||||
a.await(io);
|
||||
}
|
||||
|
||||
self.deinit(allocator);
|
||||
self.* = newGrid;
|
||||
}
|
||||
|
||||
pub const copyError = error{wrongDimensions};
|
||||
pub fn copy(self: Grid, dest: *Grid) void {
|
||||
std.debug.assert(self.arr.len == dest.arr.len and self.arr[0].len == dest.arr[0].len);
|
||||
for (dest.arr, self.arr) |des, s| {
|
||||
@memcpy(des, s);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eql(self: Grid, dest: Grid) bool {
|
||||
if (!(self.max == dest.max)) return false;
|
||||
|
||||
for (self.arr, dest.arr) |ls, ld| {
|
||||
for (ls, ld) |cs, cd| {
|
||||
if (cs != cd) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
pub fn deinit(self: Grid, allocator: std.mem.Allocator) void {
|
||||
for (self.arr) |line| {
|
||||
allocator.free(line);
|
||||
}
|
||||
allocator.free(self.arr);
|
||||
}
|
||||
|
||||
pub fn updateAll(self: *Grid, allocator: std.mem.Allocator) std.mem.Allocator.Error!void {
|
||||
var newGrid: Grid = try .init(self.max.x + 1, self.max.y + 1, allocator);
|
||||
|
||||
newGrid.leaning = self.leaning.opposite();
|
||||
|
||||
for (0..self.arr.len) |y| {
|
||||
for (0..self.arr[y].len) |x| {
|
||||
update(.{ .y = @truncate(y), .x = @truncate(x) }, self.*, newGrid);
|
||||
}
|
||||
}
|
||||
switch (self.leaning) {
|
||||
.Left => for (0..self.arr.len) |y| {
|
||||
self.updateLineLeftBiased(newGrid, y);
|
||||
},
|
||||
.Right => for (0..self.arr.len) |y| {
|
||||
self.updateLineRightBiased(newGrid, y);
|
||||
},
|
||||
}
|
||||
|
||||
self.deinit(allocator);
|
||||
self.* = newGrid;
|
||||
}
|
||||
|
||||
pub fn updateLineRightBiased(s: Grid, ng: Grid, fy: usize) void {
|
||||
for (0..s.arr[fy].len) |x| {
|
||||
update(.{ .y = @truncate(fy), .x = @truncate(x) }, s, ng);
|
||||
}
|
||||
}
|
||||
pub fn updateLineLeftBiased(s: Grid, ng: Grid, fy: usize) void {
|
||||
for (0..s.arr[fy].len) |x| {
|
||||
update(.{ .y = @truncate(fy), .x = @truncate((s.arr[fy].len - x) - 1) }, s, ng);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateAllConcurrent(self: *Grid, allocator: std.mem.Allocator, io: std.Io, async: []std.Io.Future(void)) (std.mem.Allocator.Error || std.Io.ConcurrentError)!void {
|
||||
var newGrid: Grid = try .init(self.max.x + 1, self.max.y + 1, allocator);
|
||||
|
||||
newGrid.leaning = self.leaning.opposite();
|
||||
|
||||
switch (self.leaning) {
|
||||
.Left => for (0..self.arr.len) |y| {
|
||||
async[y] = try io.concurrent(Grid.updateLineLeftBiased, .{ self.*, newGrid, y });
|
||||
},
|
||||
.Right => for (0..self.arr.len) |y| {
|
||||
async[y] = try io.concurrent(Grid.updateLineRightBiased, .{ self.*, newGrid, y });
|
||||
},
|
||||
}
|
||||
|
||||
for (async) |*a| {
|
||||
a.await(io);
|
||||
}
|
||||
|
||||
self.deinit(allocator);
|
||||
self.* = newGrid;
|
||||
}
|
||||
|
||||
pub const copyError = error{wrongDimensions};
|
||||
pub fn copy(self: Grid, dest: *Grid) void {
|
||||
std.debug.assert(self.arr.len == dest.arr.len and self.arr[0].len == dest.arr[0].len);
|
||||
for (dest.arr, self.arr) |d, s| {
|
||||
@memcpy(d, s);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eql(self: Grid, dest: Grid) bool {
|
||||
if (!(self.max == dest.max)) return false;
|
||||
|
||||
for (self.arr, dest.arr) |ls, ld| {
|
||||
for (ls, ld) |cs, cd| {
|
||||
if (cs.alive != cd.alive) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn update(self: position, grid: Grid, newGrid: Grid) void {
|
||||
alive: switch (false) {
|
||||
false => {
|
||||
std.debug.assert(grid.max == newGrid.max);
|
||||
if (!grid.arr[self.y][self.x].alive) return;
|
||||
if (self.y == grid.max.y) continue :alive true;
|
||||
const nextline = grid.arr[self.y + 1];
|
||||
const newnextline = newGrid.arr[self.y + 1];
|
||||
|
||||
down: switch (nextline[self.x].alive) {
|
||||
pub fn update(self: position, grid: Grid, newGrid: Grid) void {
|
||||
alive: switch (false) {
|
||||
false => {
|
||||
if (@cmpxchgStrong(bool, &newnextline[self.x].alive, false, true, .seq_cst, .monotonic)) |_| {
|
||||
continue :down true;
|
||||
} else {
|
||||
@atomicStore(bool, &newGrid.arr[self.y][self.x].alive, false, .seq_cst);
|
||||
return;
|
||||
}
|
||||
},
|
||||
true => {
|
||||
if (self.x == grid.max.x) {
|
||||
if (!nextline[self.x - 1].alive) {
|
||||
if (@cmpxchgStrong(bool, &newnextline[self.x - 1].alive, false, true, .seq_cst, .monotonic)) |_| {} else {
|
||||
@atomicStore(bool, &newGrid.arr[self.y][self.x].alive, false, .seq_cst);
|
||||
std.debug.assert(grid.max == newGrid.max);
|
||||
if (grid.arr[self.y][self.x] == dead) return;
|
||||
if (self.y == grid.max.y) continue :alive true;
|
||||
const alive = grid.arr[self.y][self.x];
|
||||
const nextline = grid.arr[self.y + 1];
|
||||
const newnextline = newGrid.arr[self.y + 1];
|
||||
|
||||
down: switch (nextline[self.x] == dead) {
|
||||
true => {
|
||||
if (@cmpxchgStrong(cell, &newnextline[self.x], dead, alive, .seq_cst, .monotonic)) |_| {
|
||||
continue :down false;
|
||||
} else {
|
||||
@atomicStore(cell, &newGrid.arr[self.y][self.x], dead, .seq_cst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (self.x == 0) {
|
||||
if (!nextline[self.x + 1].alive) {
|
||||
if (@cmpxchgStrong(bool, &newnextline[self.x + 1].alive, false, true, .seq_cst, .monotonic)) |_| {} else {
|
||||
@atomicStore(bool, &newGrid.arr[self.y][self.x].alive, false, .seq_cst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (grid.leaning) {
|
||||
.Right => {
|
||||
right: switch (nextline[self.x + 1].alive) {
|
||||
false => {
|
||||
if (@cmpxchgStrong(bool, &newnextline[self.x + 1].alive, false, true, .seq_cst, .monotonic)) |_| {
|
||||
continue :right true;
|
||||
} else {
|
||||
@atomicStore(bool, &newGrid.arr[self.y][self.x].alive, false, .seq_cst);
|
||||
return;
|
||||
},
|
||||
false => {
|
||||
if (self.x == grid.max.x) {
|
||||
if (nextline[self.x - 1] == dead) {
|
||||
if (@cmpxchgStrong(cell, &newnextline[self.x - 1], dead, alive, .seq_cst, .monotonic)) |_| {} else {
|
||||
@atomicStore(cell, &newGrid.arr[self.y][self.x], dead, .seq_cst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (self.x == 0) {
|
||||
if (nextline[self.x + 1] == dead) {
|
||||
if (@cmpxchgStrong(cell, &newnextline[self.x + 1], dead, alive, .seq_cst, .monotonic)) |_| {} else {
|
||||
@atomicStore(cell, &newGrid.arr[self.y][self.x], dead, .seq_cst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (grid.leaning) {
|
||||
.Right => {
|
||||
right: switch (nextline[self.x + 1] == dead) {
|
||||
true => {
|
||||
if (@cmpxchgStrong(cell, &newnextline[self.x + 1], dead, alive, .seq_cst, .monotonic)) |_| {
|
||||
continue :right false;
|
||||
} else {
|
||||
@atomicStore(cell, &newGrid.arr[self.y][self.x], dead, .seq_cst);
|
||||
return;
|
||||
}
|
||||
},
|
||||
false => {
|
||||
if (nextline[self.x - 1] == dead) {
|
||||
if (@cmpxchgStrong(cell, &newnextline[self.x - 1], dead, alive, .seq_cst, .monotonic)) |_| {} else {
|
||||
@atomicStore(cell, &newGrid.arr[self.y][self.x], dead, .seq_cst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
true => {
|
||||
if (!nextline[self.x - 1].alive) {
|
||||
if (@cmpxchgStrong(bool, &newnextline[self.x - 1].alive, false, true, .seq_cst, .monotonic)) |_| {} else {
|
||||
@atomicStore(bool, &newGrid.arr[self.y][self.x].alive, false, .seq_cst);
|
||||
return;
|
||||
}
|
||||
.Left => {
|
||||
left: switch (nextline[self.x - 1] == dead) {
|
||||
true => {
|
||||
if (@cmpxchgStrong(cell, &newnextline[self.x - 1], dead, alive, .seq_cst, .monotonic)) |_| {
|
||||
continue :left false;
|
||||
} else {
|
||||
@atomicStore(cell, &newGrid.arr[self.y][self.x], dead, .seq_cst);
|
||||
return;
|
||||
}
|
||||
},
|
||||
false => {
|
||||
if (nextline[self.x + 1] == dead) {
|
||||
if (@cmpxchgStrong(cell, &newnextline[self.x + 1], dead, alive, .seq_cst, .monotonic)) |_| {} else {
|
||||
@atomicStore(cell, &newGrid.arr[self.y][self.x], dead, .seq_cst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
.Left => {
|
||||
left: switch (nextline[self.x - 1].alive) {
|
||||
false => {
|
||||
if (@cmpxchgStrong(bool, &newnextline[self.x - 1].alive, false, true, .seq_cst, .monotonic)) |_| {
|
||||
continue :left true;
|
||||
} else {
|
||||
@atomicStore(bool, &newGrid.arr[self.y][self.x].alive, false, .seq_cst);
|
||||
return;
|
||||
}
|
||||
},
|
||||
true => {
|
||||
if (!nextline[self.x + 1].alive) {
|
||||
if (@cmpxchgStrong(bool, &newnextline[self.x + 1].alive, false, true, .seq_cst, .monotonic)) |_| {} else {
|
||||
@atomicStore(bool, &newGrid.arr[self.y][self.x].alive, false, .seq_cst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
continue :alive true;
|
||||
},
|
||||
true => @atomicStore(cell, &newGrid.arr[self.y][self.x], grid.arr[self.y][self.x], .seq_cst),
|
||||
}
|
||||
continue :alive true;
|
||||
},
|
||||
true => @atomicStore(bool, &newGrid.arr[self.y][self.x].alive, true, .seq_cst),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub const default = init(u1, 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue