|
|
@ -1,5 +1,5 @@ |
|
|
|
use crate::lib::entity::{Ant, Egg, Queen}; |
|
|
|
use crate::lib::entity::{Ant, Egg, Queen}; |
|
|
|
use crate::lib::point::Point; |
|
|
|
use crate::lib::point::{astar, Point}; |
|
|
|
use crate::lib::screen::{BoardCommand, Screen}; |
|
|
|
use crate::lib::screen::{BoardCommand, Screen}; |
|
|
|
use crate::lib::world::World; |
|
|
|
use crate::lib::world::World; |
|
|
|
use rand::prelude::SliceRandom; |
|
|
|
use rand::prelude::SliceRandom; |
|
|
@ -8,18 +8,42 @@ use rand::thread_rng; |
|
|
|
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) -> BoardCommand; |
|
|
|
fn get_position(&self) -> Point; |
|
|
|
fn get_position(&self) -> Point; |
|
|
|
|
|
|
|
fn plan(&mut self, w: &World) {} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub enum AIGoal { |
|
|
|
|
|
|
|
Reach(Point), |
|
|
|
|
|
|
|
Idle, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl AI for Ant { |
|
|
|
impl AI for Ant { |
|
|
|
fn get_position(&self) -> Point { |
|
|
|
fn get_position(&self) -> Point { |
|
|
|
self.pos.clone() |
|
|
|
self.pos.clone() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn plan(&mut self, w: &World) { |
|
|
|
|
|
|
|
if self.plan.len() == 0 { |
|
|
|
|
|
|
|
self.plan = match self.goal { |
|
|
|
|
|
|
|
AIGoal::Reach(target) => astar(&self.pos, &target), |
|
|
|
|
|
|
|
AIGoal::Idle => vec![], |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// return the next move for this ant
|
|
|
|
// return the next move for this ant
|
|
|
|
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand { |
|
|
|
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand { |
|
|
|
let valid = w.get_valid_movements(&self.pos, b); |
|
|
|
let choice = match self.goal { |
|
|
|
let mut rng = thread_rng(); |
|
|
|
AIGoal::Idle => { |
|
|
|
|
|
|
|
let valid = w.get_valid_movements(&self.pos, b); |
|
|
|
|
|
|
|
let mut rng = thread_rng(); |
|
|
|
|
|
|
|
valid.choose(&mut rng).cloned()
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
AIGoal::Reach(_) => { |
|
|
|
|
|
|
|
let movement = self.plan.pop(); |
|
|
|
|
|
|
|
movement |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
let choice = valid.choose(&mut rng).cloned(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if !choice.is_none() { |
|
|
|
if !choice.is_none() { |
|
|
|
let pos = choice.unwrap(); |
|
|
|
let pos = choice.unwrap(); |
|
|
@ -29,8 +53,16 @@ impl AI for Ant { |
|
|
|
w.update_occupied(&old_pos, &pos); |
|
|
|
w.update_occupied(&old_pos, &pos); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
w.clear(pos); |
|
|
|
w.clear(pos); |
|
|
|
|
|
|
|
match self.goal { |
|
|
|
|
|
|
|
AIGoal::Reach(_) => { |
|
|
|
|
|
|
|
self.plan.push(pos); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
AIGoal::Idle => {} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// need to check if progress has been made towards the plan
|
|
|
|
BoardCommand::Noop |
|
|
|
BoardCommand::Noop |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|