use crate::{Screen, BoardCommand}; use crate::Point; use crate::{Entities, Queen}; use std::collections::HashSet; #[derive(Clone)] pub struct World { pub cleared: HashSet, pub occupied: HashSet, } impl World { pub fn new() -> World { World { cleared: HashSet::new(), occupied: HashSet::new(), } } pub fn clear(&mut self, pos: Point) { self.cleared.insert(pos); } pub fn get_valid_movements(&self, pos: &Point, b: &Screen) -> Vec { let moves = b.get_valid_movements(pos); moves .iter() .filter(|p| !self.occupied.contains(p)) .map(|p| p.clone()) .collect() } } pub fn render(e: &Entities, w: &World, b: &Screen) { for c in w.cleared.iter() { b.render(c, "x"); } for a in e.data.values() { a.render(b); } } pub fn simulate(e: &mut Entities, w: &mut World, b: &mut Screen) { let cmds: Vec = e .data .values_mut() .map(|a| a.step(b, &w)) .collect(); for cmd in cmds { match cmd { BoardCommand::Move(old_pos, pos) => { // still makes no difference // occupied needs to be updated as soon as the move is made... w.occupied.remove(&old_pos); w.occupied.insert(pos); } BoardCommand::Dig(pos) => { w.clear(pos); } BoardCommand::LayEgg(pos, id) => { e.add_egg(pos.0, pos.1, id); } BoardCommand::Hatch(egg_id, queen_id) => { let egg = e.data.remove(&egg_id); let pos = egg.unwrap().get_position(); let q = e.data.get_mut(&queen_id).unwrap(); let queen: &mut Queen = q.downcast_mut::().unwrap(); queen.egg_count -= 1; e.add_ant(pos.0, pos.1); } BoardCommand::Noop => {} } } }