ai goal - reach works
This commit is contained in:
+37
-5
@@ -1,5 +1,5 @@
|
||||
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::world::World;
|
||||
use rand::prelude::SliceRandom;
|
||||
@@ -8,18 +8,42 @@ use rand::thread_rng;
|
||||
pub trait AI {
|
||||
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand;
|
||||
fn get_position(&self) -> Point;
|
||||
fn plan(&mut self, w: &World) {}
|
||||
}
|
||||
|
||||
pub enum AIGoal {
|
||||
Reach(Point),
|
||||
Idle,
|
||||
}
|
||||
|
||||
impl AI for Ant {
|
||||
fn get_position(&self) -> Point {
|
||||
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
|
||||
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand {
|
||||
let valid = w.get_valid_movements(&self.pos, b);
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let choice = valid.choose(&mut rng).cloned();
|
||||
let choice = match self.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
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if !choice.is_none() {
|
||||
let pos = choice.unwrap();
|
||||
@@ -29,8 +53,16 @@ impl AI for Ant {
|
||||
w.update_occupied(&old_pos, &pos);
|
||||
} else {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -1,6 +1,7 @@
|
||||
use crate::lib::ai::AI;
|
||||
use crate::lib::ai::{AI, AIGoal};
|
||||
use crate::lib::point::Point;
|
||||
use crate::lib::screen::Screen;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use ncurses::*;
|
||||
@@ -13,6 +14,8 @@ impl_downcast!(Entity);
|
||||
pub struct Ant {
|
||||
pub pos: Point,
|
||||
pub id: u32,
|
||||
pub goal: AIGoal,
|
||||
pub plan: Vec<Point>
|
||||
}
|
||||
|
||||
impl Ant {
|
||||
@@ -20,6 +23,8 @@ impl Ant {
|
||||
Ant {
|
||||
pos: Point(x, y),
|
||||
id,
|
||||
plan: vec![],
|
||||
goal: AIGoal::Idle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ fn manhattan(c1: &Point, c2: &Point) -> i32 {
|
||||
return (c2.0 - c1.0).abs() + (c2.1 - c1.1).abs();
|
||||
}
|
||||
|
||||
fn astar(start: &Point, goal: &Point) -> Vec<Point> {
|
||||
pub fn astar(start: &Point, goal: &Point) -> Vec<Point> {
|
||||
let mut open_set : HashSet<Point> = HashSet::new();
|
||||
open_set.insert(*start);
|
||||
|
||||
|
||||
+8
-1
@@ -21,6 +21,10 @@ impl World {
|
||||
self.cleared.insert(pos);
|
||||
}
|
||||
|
||||
pub fn is_valid_movement(&self, pos: &Point, b: &Screen) -> bool {
|
||||
b.is_in_bounds(pos) && !self.occupied.contains(pos)
|
||||
}
|
||||
|
||||
pub fn get_valid_movements(&self, pos: &Point, b: &Screen) -> Vec<Point> {
|
||||
let moves = b.get_valid_movements(pos);
|
||||
moves
|
||||
@@ -50,7 +54,10 @@ pub fn simulate(e: &mut Entities, w: &mut World, b: &mut Screen) {
|
||||
let cmds: Vec<BoardCommand> = e
|
||||
.data
|
||||
.values_mut()
|
||||
.map(|a| a.step(b, w))
|
||||
.map(|a| {
|
||||
a.plan(w);
|
||||
a.step(b, w)
|
||||
})
|
||||
.collect();
|
||||
|
||||
for cmd in cmds {
|
||||
|
||||
Reference in New Issue
Block a user