code cleanup, fixed bug with food creating home ph

sideways
Rostyslav Hnatyshyn 9 months ago
parent 9021e9e386
commit b660cdb2bf
  1. 51
      src/lib/ai.rs
  2. 46
      src/lib/entity.rs
  3. 9
      src/lib/screen.rs
  4. 4
      src/lib/world.rs
  5. 5
      src/main.rs

@ -1,13 +1,14 @@
use crate::lib::entity::{Ant, Egg, Queen};
use crate::lib::point::{Direction, Point};
use crate::lib::entity::{Ant, Egg, Food, FoodGenerator, Queen};
use crate::lib::point::Point;
use crate::lib::screen::{BoardCommand, Screen};
use crate::lib::world::{Pheremone, World};
use rand::Rng;
use rand::prelude::SliceRandom;
use rand::thread_rng;
use std::iter::zip;
pub trait AI {
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand;
fn step(&mut self, b: &Screen, w: &mut World, step: u32) -> BoardCommand;
fn plan(&mut self, b: &Screen, w: &mut World) -> BoardCommand {
BoardCommand::Noop
}
@ -29,8 +30,7 @@ impl AI for Ant {
w.drop_pheremone(&p, &self.goal);
}
self.history.clear();
self.cw();
self.cw();
self.about_face();
self.goal = AIGoal::Return;
}
BoardCommand::Noop
@ -41,8 +41,7 @@ impl AI for Ant {
w.drop_pheremone(&p, &self.goal);
}
self.history.clear();
self.cw();
self.cw();
self.about_face();
self.goal = AIGoal::Seek;
return BoardCommand::SpawnAnt;
} else {
@ -52,7 +51,7 @@ impl AI for Ant {
}
}
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand {
fn step(&mut self, b: &Screen, w: &mut World, t: u32) -> BoardCommand {
let valid = vec![
(self.dir, self.dir.relative_point(&self.pos)),
(self.dir.ccw(), self.dir.ccw().relative_point(&self.pos)),
@ -72,7 +71,7 @@ impl AI for Ant {
let r: f32 = rand::random();
let mut dir = &valid[0].0;
if r < 0.2 || ph.len() == 0 {
if r < 0.1 || ph.len() == 0 {
let mut rng = thread_rng();
let choice = valid.choose(&mut rng).unwrap();
dir = &choice.0;
@ -97,8 +96,27 @@ impl AI for Ant {
}
}
impl AI for FoodGenerator {
fn step(&mut self, b: &Screen, w: &mut World, t: u32) -> BoardCommand {
// eventually might want to use poisson disk distrib instead
if t % 600 == 0 && self.counter < 10 {
// generate random coords, if valid, spawn
// if not, try again next step
let (min, max) = b.get_dimensions();
let mut rng = rand::thread_rng();
let r_x = rng.gen_range(min.0..max.0 + 1);
let r_y = rng.gen_range(min.1..max.1 + 1);
self.counter += 1;
return BoardCommand::SpawnFood(Point(r_x, r_y));
}
BoardCommand::Noop
}
}
impl AI for Egg {
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand {
fn step(&mut self, b: &Screen, w: &mut World, t: u32) -> BoardCommand {
if self.counter > 0 {
self.counter -= 1;
return BoardCommand::Noop;
@ -109,7 +127,7 @@ impl AI for Egg {
}
impl AI for Queen {
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand {
fn step(&mut self, b: &Screen, w: &mut World, t: u32) -> BoardCommand {
let valid: Vec<Point> = self.pos.get_neighbors();
let mut rng = thread_rng();
@ -128,3 +146,14 @@ impl AI for Queen {
BoardCommand::Noop
}
}
impl AI for Food {
fn step(&mut self, b: &Screen, w: &mut World, t: u32) -> BoardCommand {
for n in self.pos.get_neighbors() {
w.drop_pheremone(&n, &AIGoal::Return);
}
w.drop_pheremone(&self.pos, &AIGoal::Return);
BoardCommand::Noop
}
}

@ -1,8 +1,6 @@
use crate::lib::ai::{AIGoal, AI};
use crate::lib::point::{Direction, Point};
use crate::lib::screen::{BoardCommand, Screen};
use crate::lib::world::World;
use rand::Rng;
use crate::lib::screen::Screen;
use std::collections::{HashMap, HashSet};
@ -75,6 +73,11 @@ impl Ant {
pub fn cw(&mut self) {
self.dir = self.dir.cw();
}
pub fn about_face(&mut self) {
self.cw();
self.cw();
}
}
impl_entity!(Ant);
@ -211,7 +214,7 @@ impl Entities {
#[derive(Clone)]
pub struct Food {
pos: Point,
pub pos: Point,
id: u32,
}
@ -224,17 +227,6 @@ impl Food {
}
}
impl AI for Food {
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand {
for n in self.pos.get_neighbors() {
w.drop_pheremone(&n, &AIGoal::Seek);
}
w.drop_pheremone(&self.pos, &AIGoal::Seek);
BoardCommand::Noop
}
}
impl Renderable for Food {
fn representation(&self) -> &str {
"f"
@ -244,10 +236,10 @@ impl Renderable for Food {
// no position, does not get rendered yet acts per turn
#[derive(Clone)]
pub struct FoodGenerator {
timer: u32,
pub timer: u32,
pos: Point,
id: u32,
counter: u32,
pub counter: u32,
}
impl FoodGenerator {
@ -261,26 +253,6 @@ impl FoodGenerator {
}
}
impl AI for FoodGenerator {
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand {
// eventually might want to use poisson disk distrib instead
if self.timer % 600 == 0 && self.counter < 10 {
// generate random coords, if valid, spawn
// if not, try again next step
let (min, max) = b.get_dimensions();
let mut rng = rand::thread_rng();
let r_x = rng.gen_range(min.0..max.0 + 1);
let r_y = rng.gen_range(min.1..max.1 + 1);
self.counter += 1;
return BoardCommand::SpawnFood(Point(r_x, r_y));
}
self.timer += 1;
BoardCommand::Noop
}
}
impl Renderable for FoodGenerator {
fn render(&self, b: &Screen) {}
}

@ -36,15 +36,6 @@ impl Screen {
(pos.0 > 0 && pos.0 < self.max_x) && (pos.1 > 0 && pos.1 < self.max_y)
}
pub fn get_valid_movements(&self, pos: &Point) -> Vec<Point> {
let binding = pos.get_neighbors();
binding
.iter()
.filter(|e| self.is_in_bounds(e))
.map(|e| e.clone())
.collect()
}
pub fn render(&self, p: &Point, char: &str) {
mvprintw(p.1, p.0, char);
}

@ -81,7 +81,7 @@ pub fn render(e: &Entities, w: &World, b: &Screen) {
pub fn simulate(e: &mut Entities, w: &mut World, b: &mut Screen, step: u32) {
let plan_cmds: Vec<BoardCommand> = e.data.values_mut().map(|a| a.plan(b, w)).collect();
let mut cmds: Vec<BoardCommand> = e.data.values_mut().map(|a| a.step(b, w)).collect();
let mut cmds: Vec<BoardCommand> = e.data.values_mut().map(|a| a.step(b, w, step)).collect();
cmds.extend(plan_cmds);
@ -115,7 +115,7 @@ pub fn simulate(e: &mut Entities, w: &mut World, b: &mut Screen, step: u32) {
}
// decay all pheremones by some amount
if step % 60 == 0 {
if step % 600 == 0 {
for ph in w.pheremones.iter_mut() {
ph.decay();
}

@ -26,9 +26,6 @@ fn main() {
let mut entities = Entities::new();
//let q = Queen::new(board.center.0,board.center.1);
//entities.add_entity(&q);
let fg = FoodGenerator::new();
entities.add_entity(&fg);
@ -38,8 +35,6 @@ fn main() {
entities.add_entity(&a);
}
//world.create_chamber(Point(board.center.0, board.center.1), 3);
let mut t = 0;
loop {
// TODO: add way to break out of the loop by hitting a random key

Loading…
Cancel
Save