ants/src/WorldInit.ts

50 lines
1.6 KiB
TypeScript

import { MAT_FOOD, MAT_HOME, MAT_SAND } from "./constants";
// simple seeded PRNG for deterministic placement
function mulberry32(seed: number) {
return () => {
seed += 0x6d2b79f5;
let t = seed;
t = Math.imul(t ^ (t >>> 15), t | 1);
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
export function generateSideViewWorld(
worldSize: number,
seed: boolean,
): Float32Array {
const data = new Float32Array(worldSize * worldSize * 4);
const sandHeight = Math.floor(worldSize * 0.6);
const surfaceRow = sandHeight - 1;
// fill bottom 60% with sand
for (let y = 0; y < sandHeight; y++) {
for (let x = 0; x < worldSize; x++) {
const idx = (y * worldSize + x) * 4;
data[idx] = MAT_SAND;
}
}
// top 40% stays MAT_AIR (Float32Array is zero-initialized)
if (seed) {
const rng = mulberry32(Date.now());
// place home at random surface position (middle 60% of world width)
const margin = Math.floor(worldSize * 0.2);
const homeX = margin + Math.floor(rng() * (worldSize - 2 * margin));
const homeIdx = (surfaceRow * worldSize + homeX) * 4;
data[homeIdx] = MAT_HOME;
// place food at a different random surface position
let foodX = homeX;
while (foodX === homeX) {
foodX = margin + Math.floor(rng() * (worldSize - 2 * margin));
}
const foodIdx = (surfaceRow * worldSize + foodX) * 4;
data[foodIdx] = MAT_FOOD;
}
return data;
}