terrain_forge/algorithms/
agent.rs1use crate::{Algorithm, Grid, Rng, Tile};
2
3#[derive(Debug, Clone)]
4pub struct AgentConfig {
5 pub num_agents: usize,
6 pub steps_per_agent: usize,
7 pub turn_chance: f64,
8}
9
10impl Default for AgentConfig {
11 fn default() -> Self { Self { num_agents: 5, steps_per_agent: 200, turn_chance: 0.3 } }
12}
13
14pub struct AgentBased {
15 config: AgentConfig,
16}
17
18impl AgentBased {
19 pub fn new(config: AgentConfig) -> Self { Self { config } }
20}
21
22impl Default for AgentBased {
23 fn default() -> Self { Self::new(AgentConfig::default()) }
24}
25
26impl Algorithm<Tile> for AgentBased {
27 fn generate(&self, grid: &mut Grid<Tile>, seed: u64) {
28 let mut rng = Rng::new(seed);
29 let dirs: [(i32, i32); 4] = [(0, -1), (1, 0), (0, 1), (-1, 0)];
30 let (w, h) = (grid.width() as i32, grid.height() as i32);
31
32 for _ in 0..self.config.num_agents {
33 let mut x = rng.range(1, w - 1);
34 let mut y = rng.range(1, h - 1);
35 let mut dir = rng.range_usize(0, 4);
36
37 for _ in 0..self.config.steps_per_agent {
38 grid.set(x, y, Tile::Floor);
39
40 if rng.chance(self.config.turn_chance) {
41 dir = if rng.chance(0.5) { (dir + 1) % 4 } else { (dir + 3) % 4 };
42 }
43
44 let (dx, dy) = dirs[dir];
45 let (nx, ny) = (x + dx, y + dy);
46
47 if nx > 0 && nx < w - 1 && ny > 0 && ny < h - 1 {
48 x = nx;
49 y = ny;
50 } else {
51 dir = (dir + 2) % 4;
52 }
53 }
54 }
55 }
56
57 fn name(&self) -> &'static str { "AgentBased" }
58}