multiple goal ai
This commit is contained in:
+20
-21
@@ -10,40 +10,46 @@ pub trait AI {
|
||||
fn plan(&mut self, w: &World) {}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum AIGoal {
|
||||
Reach(Point),
|
||||
//Pickup(Point),
|
||||
//Drop(),
|
||||
Idle,
|
||||
}
|
||||
|
||||
impl AI for Ant {
|
||||
fn plan(&mut self, w: &World) {
|
||||
if self.plan.len() == 0 {
|
||||
self.plan = match self.goal {
|
||||
// check last part of plan
|
||||
if let Some(goal) = self.plan.last() {
|
||||
match goal {
|
||||
AIGoal::Reach(target) => {
|
||||
if &self.pos == &target {
|
||||
self.goal = AIGoal::Idle;
|
||||
vec![]
|
||||
} else {
|
||||
astar(&self.pos, &target)
|
||||
if self.pos == *target {
|
||||
self.plan.pop();
|
||||
}
|
||||
}
|
||||
AIGoal::Idle => vec![],
|
||||
AIGoal::Idle => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return the next move for this ant
|
||||
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand {
|
||||
let choice = match self.goal {
|
||||
|
||||
let goal = match self.plan.last() {
|
||||
Some(g) => g,
|
||||
None => &AIGoal::Idle,
|
||||
};
|
||||
|
||||
let choice = match goal {
|
||||
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
|
||||
AIGoal::Reach(target) => {
|
||||
let mut movements = astar(&self.pos, &target);
|
||||
movements.pop()
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,13 +61,6 @@ impl AI for Ant {
|
||||
w.update_occupied(&old_pos, &pos);
|
||||
} else {
|
||||
w.clear(pos);
|
||||
match self.goal {
|
||||
// push plan back because we haven't actually moved towards it
|
||||
AIGoal::Reach(_) => {
|
||||
self.plan.push(pos);
|
||||
}
|
||||
AIGoal::Idle => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -40,8 +40,7 @@ impl_downcast!(Renderable);
|
||||
pub struct Ant {
|
||||
pub pos: Point,
|
||||
pub id: u32,
|
||||
pub goal: AIGoal,
|
||||
pub plan: Vec<Point>,
|
||||
pub plan: Vec<AIGoal>,
|
||||
}
|
||||
|
||||
impl Ant {
|
||||
@@ -50,7 +49,6 @@ impl Ant {
|
||||
pos: Point(x, y),
|
||||
id: 0,
|
||||
plan: vec![],
|
||||
goal: AIGoal::Idle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -45,7 +45,9 @@ pub fn astar(start: &Point, goal: &Point) -> Vec<Point> {
|
||||
answer.push(current.clone());
|
||||
while came_from.contains_key(¤t) {
|
||||
current = came_from[¤t].clone();
|
||||
answer.push(current.clone());
|
||||
if current != *start {
|
||||
answer.push(current.clone());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+37
-5
@@ -1,8 +1,8 @@
|
||||
use antf::lib::screen::init_screen;
|
||||
use antf::lib::screen::{Screen, init_screen};
|
||||
use antf::lib::point::Point;
|
||||
use antf::lib::ai::AIGoal;
|
||||
use antf::lib::world::{World, simulate, render};
|
||||
use antf::lib::entity::{Entities, Ant};
|
||||
use antf::lib::entity::{Entities, Ant, Food, FoodGenerator};
|
||||
|
||||
use ncurses::*;
|
||||
use std::thread::sleep;
|
||||
@@ -12,7 +12,7 @@ use std::time;
|
||||
|
||||
#[test]
|
||||
fn test_reach_astar() {
|
||||
let mut board = init_screen();
|
||||
let mut board = init_screen();//Screen::new(40,40);
|
||||
let mut world = World::new();
|
||||
|
||||
let mut entities = Entities::new();
|
||||
@@ -22,9 +22,13 @@ fn test_reach_astar() {
|
||||
|
||||
let a = entities.data.get_mut(&id).unwrap();
|
||||
let ant: &mut Ant = a.downcast_mut::<Ant>().unwrap();
|
||||
ant.goal = AIGoal::Reach(Point(10,10));
|
||||
ant.plan.push(AIGoal::Reach(Point(10,10)));
|
||||
ant.plan.push(AIGoal::Reach(Point(-10,-10)));
|
||||
ant.plan.push(AIGoal::Reach(Point(10,-10)));
|
||||
ant.plan.push(AIGoal::Reach(Point(-10,10)));
|
||||
|
||||
for _ in 0..60 {
|
||||
// craps out... need to make sure unwrap() is safe
|
||||
for _ in 0..420 {
|
||||
// TODO: add way to break out of the loop by hitting a random key
|
||||
simulate(&mut entities, &mut world, &mut board);
|
||||
render(&entities, &world, &board);
|
||||
@@ -34,3 +38,31 @@ fn test_reach_astar() {
|
||||
clear();
|
||||
endwin();
|
||||
}
|
||||
|
||||
/*#[test]
|
||||
fn test_drag() {
|
||||
let mut board = init_screen();
|
||||
let mut world = World::new();
|
||||
|
||||
let mut entities = Entities::new();
|
||||
|
||||
let f = Food::new(10,10);
|
||||
let a = Ant::new(0,0);
|
||||
let fid = entities.add_entity(&f);
|
||||
let id = entities.add_entity(&a);
|
||||
|
||||
let a = entities.data.get_mut(&id).unwrap();
|
||||
let ant: &mut Ant = a.downcast_mut::<Ant>().unwrap();
|
||||
|
||||
//ant.goal =
|
||||
|
||||
for _ in 0..60 {
|
||||
// TODO: add way to break out of the loop by hitting a random key
|
||||
simulate(&mut entities, &mut world, &mut board);
|
||||
render(&entities, &world, &board);
|
||||
sleep(time::Duration::from_millis(100));
|
||||
refresh();
|
||||
}
|
||||
clear();
|
||||
endwin();
|
||||
}*/
|
||||
|
||||
Reference in New Issue
Block a user