Skip to main content

fire_cli_rs/
simulation.rs

1use std::time::{SystemTime, UNIX_EPOCH};
2
3pub struct Rng(u32);
4impl Rng {
5    #[inline(always)]
6    pub fn new() -> Self {
7        let nanos = SystemTime::now()
8            .duration_since(UNIX_EPOCH)
9            .unwrap()
10            .as_nanos();
11        let seed = (nanos as u32) ^ ((nanos >> 32) as u32);
12        Self(seed | 1)
13    }
14    
15    #[inline(always)]
16    pub fn next(&mut self) -> u32 {
17        self.0 ^= self.0 << 13;
18        self.0 ^= self.0 >> 17;
19        self.0 ^= self.0 << 5;
20        self.0
21    }
22}
23
24#[inline(always)]
25pub fn simulate_step(buf: &mut [u8], w: usize, h: usize, rng: &mut Rng) {
26    for _ in 0..(w / 9).max(1) {
27        let idx = (rng.next() as usize % w) + w * (h - 1);
28        if idx < buf.len() {
29            buf[idx] = 65;
30        }
31    }
32
33    let size = w * h;
34    let limit = if size + w + 1 <= buf.len() { size } else { buf.len().saturating_sub(w + 1) };
35    for i in 0..limit {
36        let sum = buf[i] as u32
37            + buf[i + 1] as u32
38            + buf[i + w] as u32
39            + buf[i + w + 1] as u32;
40        buf[i] = (sum >> 2) as u8;
41    }
42}