|
|
@ -1,21 +1,19 @@ |
|
|
|
use crate::lib::screen::{Screen, BoardCommand}; |
|
|
|
use crate::lib::entity::{Ant, Egg, Entities, Food, Queen}; |
|
|
|
use crate::lib::point::Point; |
|
|
|
use crate::lib::point::Point; |
|
|
|
use crate::lib::entity::{Entities, Queen, Egg, Ant, Food}; |
|
|
|
use crate::lib::screen::{BoardCommand, Screen}; |
|
|
|
use std::collections::HashSet; |
|
|
|
use std::collections::HashSet; |
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone)] |
|
|
|
#[derive(Clone)] |
|
|
|
pub struct World { |
|
|
|
pub struct World { |
|
|
|
pub cleared: HashSet<Point>, |
|
|
|
pub cleared: HashSet<Point>, |
|
|
|
pub occupied: HashSet<Point>, |
|
|
|
pub food: HashSet<u32>, |
|
|
|
pub food: HashSet<u32> |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl World { |
|
|
|
impl World { |
|
|
|
pub fn new() -> World { |
|
|
|
pub fn new() -> World { |
|
|
|
World { |
|
|
|
World { |
|
|
|
cleared: HashSet::new(), |
|
|
|
cleared: HashSet::new(), |
|
|
|
occupied: HashSet::new(), |
|
|
|
food: HashSet::new(), |
|
|
|
food: HashSet::new() |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -23,23 +21,34 @@ impl World { |
|
|
|
self.cleared.insert(pos); |
|
|
|
self.cleared.insert(pos); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn is_valid_movement(&self, pos: &Point, b: &Screen) -> bool { |
|
|
|
pub fn is_valid_movement(&self, current_pos: &Point, target: &Point, b: &Screen) -> bool { |
|
|
|
b.is_in_bounds(pos) && !self.occupied.contains(pos) |
|
|
|
let mut safe = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if target.is_above(current_pos) { |
|
|
|
|
|
|
|
safe = |
|
|
|
|
|
|
|
!self.cleared.contains(&target.left()) || !self.cleared.contains(&target.right()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if target.is_adjacent(current_pos) { |
|
|
|
|
|
|
|
let target_down = target.down(); |
|
|
|
|
|
|
|
if self.cleared.contains(&target_down) { |
|
|
|
|
|
|
|
safe = !self.cleared.contains(&target_down.left()) |
|
|
|
|
|
|
|
|| !self.cleared.contains(&target_down.right()); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
safe = !self.cleared.contains(&target.down()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
b.is_in_bounds(target) && safe |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_valid_movements(&self, pos: &Point, b: &Screen) -> Vec<Point> { |
|
|
|
pub fn get_valid_movements(&self, pos: &Point, b: &Screen) -> Vec<Point> { |
|
|
|
let moves = b.get_valid_movements(pos); |
|
|
|
let moves = b.get_valid_movements(pos); |
|
|
|
moves |
|
|
|
moves |
|
|
|
.iter() |
|
|
|
.iter() |
|
|
|
.filter(|p| !self.occupied.contains(p)) |
|
|
|
.filter(|p| self.is_valid_movement(pos, p, b)) |
|
|
|
.map(|p| p.clone()) |
|
|
|
.map(|p| p.clone()) |
|
|
|
.collect() |
|
|
|
.collect() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn update_occupied(&mut self, old: &Point, new: &Point) { |
|
|
|
|
|
|
|
self.occupied.remove(old); |
|
|
|
|
|
|
|
self.occupied.insert(*new); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn render(e: &Entities, w: &World, b: &Screen) { |
|
|
|
pub fn render(e: &Entities, w: &World, b: &Screen) { |
|
|
@ -56,9 +65,9 @@ pub fn simulate(e: &mut Entities, w: &mut World, b: &mut Screen) { |
|
|
|
let cmds: Vec<BoardCommand> = e |
|
|
|
let cmds: Vec<BoardCommand> = e |
|
|
|
.data |
|
|
|
.data |
|
|
|
.values_mut() |
|
|
|
.values_mut() |
|
|
|
.map(|a| {
|
|
|
|
.map(|a| { |
|
|
|
a.plan(w); |
|
|
|
a.plan(w); |
|
|
|
a.step(b, w)
|
|
|
|
a.step(b, w) |
|
|
|
}) |
|
|
|
}) |
|
|
|
.collect(); |
|
|
|
.collect(); |
|
|
|
|
|
|
|
|
|
|
@ -83,7 +92,7 @@ pub fn simulate(e: &mut Entities, w: &mut World, b: &mut Screen) { |
|
|
|
} |
|
|
|
} |
|
|
|
BoardCommand::SpawnFood(pos) => { |
|
|
|
BoardCommand::SpawnFood(pos) => { |
|
|
|
let food = Food::new(pos.0, pos.1); |
|
|
|
let food = Food::new(pos.0, pos.1); |
|
|
|
e.add_entity(&food);
|
|
|
|
e.add_entity(&food); |
|
|
|
} |
|
|
|
} |
|
|
|
BoardCommand::Noop => {} |
|
|
|
BoardCommand::Noop => {} |
|
|
|
} |
|
|
|
} |
|
|
|