promet-sim/src/areas.zig
2025-07-21 08:22:12 +02:00

73 lines
2.4 KiB
Zig

const std = @import("std");
const rl = @import("raylib");
const spawn_area = @import("spawn-area.zig");
const structures = @import("structures.zig");
pub const Areas = struct {
allocator: std.mem.Allocator,
areas: []spawn_area.SpawnArea,
pub fn init(allocator: std.mem.Allocator, size: usize) !Areas {
const values = std.enums.values(structures.AreaLocation);
var max_areas = size;
if (size > values.len) max_areas = values.len;
var used_areas = std.ArrayList(structures.AreaLocation).init(allocator);
defer used_areas.deinit();
var prng = std.Random.DefaultPrng.init(blk: {
var seed: u64 = undefined;
try std.posix.getrandom(std.mem.asBytes(&seed));
break :blk seed;
});
const rand = prng.random();
const area_data = try allocator.alloc(spawn_area.SpawnArea, size);
for (area_data) |*area| {
// give us all valid values we can use for AreaLocation
const valid_values = try getEnumValuesMinusUsed(allocator, used_areas, values);
defer allocator.free(valid_values);
const num = rand.intRangeAtMost(usize, 0, valid_values.len - 1); // random number
// here we create new spawnarea
area.* = spawn_area.SpawnArea.init(valid_values[num]);
try used_areas.append(valid_values[num]);
}
return Areas{
.allocator = allocator,
.areas = area_data,
};
}
pub fn deinit(self: *Areas) void {
self.allocator.free(self.areas);
}
pub fn draw(self: *const Areas) void {
for (self.areas) |area| {
area.draw();
}
}
fn getEnumValuesMinusUsed(allocator: std.mem.Allocator, used_values: std.ArrayList(structures.AreaLocation), values: []const structures.AreaLocation) ![]structures.AreaLocation {
var valuesToRandomise = try allocator.alloc(structures.AreaLocation, values.len - used_values.items.len);
var i: usize = 0;
outer: for (values) |value| {
for (used_values.items) |used_val| {
if (value == used_val) {
continue :outer;
}
}
// this value is clean and can get put into values good for randomisation
valuesToRandomise[i] = value;
i += 1;
}
return valuesToRandomise;
}
};