|
|
@ -1,13 +1,14 @@ |
|
|
|
use crate::lib::entity::{Ant, Egg, Queen}; |
|
|
|
use crate::lib::entity::{Ant, Egg, Food, FoodGenerator, Queen}; |
|
|
|
use crate::lib::point::{Direction, Point}; |
|
|
|
use crate::lib::point::Point; |
|
|
|
use crate::lib::screen::{BoardCommand, Screen}; |
|
|
|
use crate::lib::screen::{BoardCommand, Screen}; |
|
|
|
use crate::lib::world::{Pheremone, World}; |
|
|
|
use crate::lib::world::{Pheremone, World}; |
|
|
|
|
|
|
|
use rand::Rng; |
|
|
|
use rand::prelude::SliceRandom; |
|
|
|
use rand::prelude::SliceRandom; |
|
|
|
use rand::thread_rng; |
|
|
|
use rand::thread_rng; |
|
|
|
use std::iter::zip; |
|
|
|
use std::iter::zip; |
|
|
|
|
|
|
|
|
|
|
|
pub trait AI { |
|
|
|
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 { |
|
|
|
fn plan(&mut self, b: &Screen, w: &mut World) -> BoardCommand { |
|
|
|
BoardCommand::Noop |
|
|
|
BoardCommand::Noop |
|
|
|
} |
|
|
|
} |
|
|
@ -29,8 +30,7 @@ impl AI for Ant { |
|
|
|
w.drop_pheremone(&p, &self.goal); |
|
|
|
w.drop_pheremone(&p, &self.goal); |
|
|
|
} |
|
|
|
} |
|
|
|
self.history.clear(); |
|
|
|
self.history.clear(); |
|
|
|
self.cw(); |
|
|
|
self.about_face(); |
|
|
|
self.cw(); |
|
|
|
|
|
|
|
self.goal = AIGoal::Return; |
|
|
|
self.goal = AIGoal::Return; |
|
|
|
} |
|
|
|
} |
|
|
|
BoardCommand::Noop |
|
|
|
BoardCommand::Noop |
|
|
@ -41,8 +41,7 @@ impl AI for Ant { |
|
|
|
w.drop_pheremone(&p, &self.goal); |
|
|
|
w.drop_pheremone(&p, &self.goal); |
|
|
|
} |
|
|
|
} |
|
|
|
self.history.clear(); |
|
|
|
self.history.clear(); |
|
|
|
self.cw(); |
|
|
|
self.about_face(); |
|
|
|
self.cw(); |
|
|
|
|
|
|
|
self.goal = AIGoal::Seek; |
|
|
|
self.goal = AIGoal::Seek; |
|
|
|
return BoardCommand::SpawnAnt; |
|
|
|
return BoardCommand::SpawnAnt; |
|
|
|
} else { |
|
|
|
} 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![ |
|
|
|
let valid = vec![ |
|
|
|
(self.dir, self.dir.relative_point(&self.pos)), |
|
|
|
(self.dir, self.dir.relative_point(&self.pos)), |
|
|
|
(self.dir.ccw(), self.dir.ccw().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 r: f32 = rand::random(); |
|
|
|
|
|
|
|
|
|
|
|
let mut dir = &valid[0].0; |
|
|
|
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 mut rng = thread_rng(); |
|
|
|
let choice = valid.choose(&mut rng).unwrap(); |
|
|
|
let choice = valid.choose(&mut rng).unwrap(); |
|
|
|
dir = &choice.0; |
|
|
|
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 { |
|
|
|
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 { |
|
|
|
if self.counter > 0 { |
|
|
|
self.counter -= 1; |
|
|
|
self.counter -= 1; |
|
|
|
return BoardCommand::Noop; |
|
|
|
return BoardCommand::Noop; |
|
|
@ -109,7 +127,7 @@ impl AI for Egg { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl AI for Queen { |
|
|
|
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 valid: Vec<Point> = self.pos.get_neighbors(); |
|
|
|
let mut rng = thread_rng(); |
|
|
|
let mut rng = thread_rng(); |
|
|
|
|
|
|
|
|
|
|
@ -128,3 +146,14 @@ impl AI for Queen { |
|
|
|
BoardCommand::Noop |
|
|
|
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 |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|