From 37f1bb8022e434d3f0c8b430710d347282de78bc Mon Sep 17 00:00:00 2001 From: Rostyslav Hnatyshyn Date: Tue, 2 Jan 2024 15:54:33 -0700 Subject: [PATCH] collisions but queen can't spawn more than 3 --- src/main.rs | 108 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 39 deletions(-) diff --git a/src/main.rs b/src/main.rs index a833a04..2184a42 100644 --- a/src/main.rs +++ b/src/main.rs @@ -67,33 +67,49 @@ impl World { fn get_valid_movements(&self, pos: &Point, b: &Board) -> Vec { let moves = b.get_valid_movements(pos); - moves.iter().filter(|p| !self.occupied.contains(p)).map(|p| p.clone()).collect() + moves + .iter() + .filter(|p| !self.occupied.contains(p)) + .map(|p| p.clone()) + .collect() } } trait Entity: AI + Renderable {} struct Colony { - ants: HashMap>, + ants: HashMap>, + id_counter: u32, } impl Colony { fn new() -> Colony { Colony { ants: HashMap::new(), + id_counter: 0, } } - fn add_entity(&mut self, pos: &Point, e: T) { - self.ants.insert(*pos, Box::new(e)); + fn add_entity(&mut self, e: T) { + self.ants.insert(self.id_counter, Box::new(e)); + self.id_counter += 1; } } trait AI { - fn step(&mut self, pos: &Point, b: &Board, w: &World) -> BoardCommand; + fn step(&mut self, id: u32, b: &Board, w: &World) -> BoardCommand; + fn get_position(&self) -> Point; } -struct Ant {} +struct Ant { + pos: Point, +} + +impl Ant { + fn new(x: i32, y: i32) -> Ant { + Ant { pos: Point(x, y) } + } +} impl Entity for Ant {} @@ -104,6 +120,7 @@ impl Renderable for Ant { } struct Queen { + pos: Point, egg_count: u8, } @@ -120,13 +137,17 @@ trait Renderable { } impl Queen { - fn new() -> Queen { - Queen { egg_count: 0 } + fn new(x: i32, y: i32) -> Queen { + Queen { + pos: Point(x, y), + egg_count: 0, + } } } #[derive(Debug)] struct Egg { + pos: Point, counter: u8, } @@ -137,34 +158,43 @@ impl Renderable for Egg { } impl Egg { - fn new() -> Egg { - Egg { counter: 10 } + fn new(x: i32, y: i32) -> Egg { + Egg { + pos: Point(x, y), + counter: 10, + } } } impl AI for Egg { - fn step(&mut self, p: &Point, b: &Board, w: &World) -> BoardCommand { + fn step(&mut self, id: u32, b: &Board, w: &World) -> BoardCommand { if self.counter > 0 { self.counter -= 1; return BoardCommand::Noop; } else { - BoardCommand::Hatch(*p) + BoardCommand::Hatch(id) } } + + fn get_position(&self) -> Point { + self.pos.clone() + } } enum BoardCommand { - Move(Point, Point), Dig(Point), LayEgg(Point), - Hatch(Point), + Hatch(u32), Noop, } impl AI for Ant { + fn get_position(&self) -> Point { + self.pos.clone() + } // return the next move for this ant - fn step(&mut self, p: &Point, b: &Board, w: &World) -> BoardCommand { - let valid = w.get_valid_movements(p, b); + fn step(&mut self, id: u32, b: &Board, w: &World) -> BoardCommand { + let valid = w.get_valid_movements(&self.pos, b); let mut rng = thread_rng(); let choice = valid.choose(&mut rng).cloned(); @@ -174,7 +204,8 @@ impl AI for Ant { } else { let pos = choice.unwrap(); if w.cleared.contains(&pos) { - return BoardCommand::Move(*p, pos); + self.pos = pos; + return BoardCommand::Noop; } else { return BoardCommand::Dig(pos); } @@ -186,9 +217,13 @@ impl Entity for Queen {} impl Entity for Egg {} impl AI for Queen { - fn step(&mut self, p: &Point, b: &Board, w: &World) -> BoardCommand { - let valid: Vec = w.get_valid_movements(p, b); + fn get_position(&self) -> Point { + self.pos.clone() + } + fn step(&mut self, id: u32, b: &Board, w: &World) -> BoardCommand { + let valid: Vec = w.get_valid_movements(&self.pos, b); let mut rng = thread_rng(); + let choice = valid.choose(&mut rng).cloned(); if choice.is_none() { @@ -201,7 +236,8 @@ impl AI for Queen { self.egg_count += 1; return BoardCommand::LayEgg(pos); } else { - return BoardCommand::Move(*p, pos); + self.pos = pos; + return BoardCommand::Noop; } } else { return BoardCommand::Noop; @@ -215,7 +251,8 @@ fn render(c: &Colony, w: &World, b: &Board) { mvprintw(c.1 + b.center.1, c.0 + b.center.0, "x"); } - for (pos, a) in c.ants.iter() { + for a in c.ants.values() { + let pos = a.get_position(); mvprintw(pos.1 + b.center.1, pos.0 + b.center.0, a.render()); } } @@ -239,35 +276,26 @@ mod tests { } fn simulate(c: &mut Colony, w: &mut World, b: &mut Board) { - let cmds: Vec = c - .ants - .iter_mut() - .map(|(p, a)| { - a.step(&p, b, &w) - }) - .collect(); + let cmds: Vec = c.ants.iter_mut().map(|(id, a)| a.step(*id, b, &w)).collect(); for cmd in cmds { match cmd { - BoardCommand::Move(old_pos, pos) => { - let a = c.ants.remove(&old_pos).unwrap(); - c.ants.insert(pos, a); - } BoardCommand::Dig(pos) => { w.clear(pos); } BoardCommand::LayEgg(pos) => { - c.add_entity(&pos, Egg::new()); + c.add_entity(Egg::new(pos.0, pos.1)); } - BoardCommand::Hatch(pos) => { - c.ants.remove(&pos); - c.add_entity(&pos, Ant {}); + BoardCommand::Hatch(egg_id) => { + let egg = c.ants.remove(&egg_id); + let pos = egg.unwrap().get_position(); + c.add_entity(Ant::new(pos.0, pos.1)); } BoardCommand::Noop => {} } } w.occupied.clear(); - let _ = c.ants.keys().map(|p| w.occupied.insert(*p)); + let _ = c.ants.values().map(|p| w.occupied.insert(p.get_position())); } fn main() { @@ -285,7 +313,11 @@ fn main() { let mut board = Board::new(max_x, max_y); let mut world = World::new(); + + let q = Queen::new(0,0); + let mut colony = Colony::new(); + colony.add_entity(q); for i in -3..3 { for j in -3..3 { @@ -293,8 +325,6 @@ fn main() { } } - colony.add_entity(&Point(0, 0), Queen::new()); - loop { // TODO: add way to break out of the loop by hitting a random key simulate(&mut colony, &mut world, &mut board);