sideways #1
+40
-11
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+9
-37
@@ -1,8 +1,6 @@
|
|||||||
use crate::lib::ai::{AIGoal, AI};
|
use crate::lib::ai::{AIGoal, AI};
|
||||||
use crate::lib::point::{Direction, Point};
|
use crate::lib::point::{Direction, Point};
|
||||||
use crate::lib::screen::{BoardCommand, Screen};
|
use crate::lib::screen::Screen;
|
||||||
use crate::lib::world::World;
|
|
||||||
use rand::Rng;
|
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
@@ -75,6 +73,11 @@ impl Ant {
|
|||||||
pub fn cw(&mut self) {
|
pub fn cw(&mut self) {
|
||||||
self.dir = self.dir.cw();
|
self.dir = self.dir.cw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn about_face(&mut self) {
|
||||||
|
self.cw();
|
||||||
|
self.cw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_entity!(Ant);
|
impl_entity!(Ant);
|
||||||
@@ -211,7 +214,7 @@ impl Entities {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Food {
|
pub struct Food {
|
||||||
pos: Point,
|
pub pos: Point,
|
||||||
id: u32,
|
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 {
|
impl Renderable for Food {
|
||||||
fn representation(&self) -> &str {
|
fn representation(&self) -> &str {
|
||||||
"f"
|
"f"
|
||||||
@@ -244,10 +236,10 @@ impl Renderable for Food {
|
|||||||
// no position, does not get rendered yet acts per turn
|
// no position, does not get rendered yet acts per turn
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FoodGenerator {
|
pub struct FoodGenerator {
|
||||||
timer: u32,
|
pub timer: u32,
|
||||||
pos: Point,
|
pos: Point,
|
||||||
id: u32,
|
id: u32,
|
||||||
counter: u32,
|
pub counter: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FoodGenerator {
|
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 {
|
impl Renderable for FoodGenerator {
|
||||||
fn render(&self, b: &Screen) {}
|
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)
|
(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) {
|
pub fn render(&self, p: &Point, char: &str) {
|
||||||
mvprintw(p.1, p.0, char);
|
mvprintw(p.1, p.0, char);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -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) {
|
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 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);
|
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
|
// decay all pheremones by some amount
|
||||||
if step % 60 == 0 {
|
if step % 600 == 0 {
|
||||||
for ph in w.pheremones.iter_mut() {
|
for ph in w.pheremones.iter_mut() {
|
||||||
ph.decay();
|
ph.decay();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ fn main() {
|
|||||||
|
|
||||||
let mut entities = Entities::new();
|
let mut entities = Entities::new();
|
||||||
|
|
||||||
//let q = Queen::new(board.center.0,board.center.1);
|
|
||||||
//entities.add_entity(&q);
|
|
||||||
|
|
||||||
let fg = FoodGenerator::new();
|
let fg = FoodGenerator::new();
|
||||||
entities.add_entity(&fg);
|
entities.add_entity(&fg);
|
||||||
|
|
||||||
@@ -38,8 +35,6 @@ fn main() {
|
|||||||
entities.add_entity(&a);
|
entities.add_entity(&a);
|
||||||
}
|
}
|
||||||
|
|
||||||
//world.create_chamber(Point(board.center.0, board.center.1), 3);
|
|
||||||
|
|
||||||
let mut t = 0;
|
let mut t = 0;
|
||||||
loop {
|
loop {
|
||||||
// TODO: add way to break out of the loop by hitting a random key
|
// TODO: add way to break out of the loop by hitting a random key
|
||||||
|
|||||||
Reference in New Issue
Block a user