ai goal - reach works

master
Rostyslav Hnatyshyn 9 months ago
parent f148fcb901
commit d69b24dfd8
  1. 42
      src/lib/ai.rs
  2. 7
      src/lib/entity.rs
  3. 2
      src/lib/point.rs
  4. 9
      src/lib/world.rs

@ -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 choice = valid.choose(&mut rng).cloned(); let mut rng = thread_rng();
valid.choose(&mut rng).cloned()
},
AIGoal::Reach(_) => {
let movement = self.plan.pop();
movement
}
};
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
} }
} }

@ -1,6 +1,7 @@
use crate::lib::ai::AI; use crate::lib::ai::{AI, AIGoal};
use crate::lib::point::Point; use crate::lib::point::Point;
use crate::lib::screen::Screen; use crate::lib::screen::Screen;
use std::collections::HashMap; use std::collections::HashMap;
use ncurses::*; use ncurses::*;
@ -13,6 +14,8 @@ impl_downcast!(Entity);
pub struct Ant { pub struct Ant {
pub pos: Point, pub pos: Point,
pub id: u32, pub id: u32,
pub goal: AIGoal,
pub plan: Vec<Point>
} }
impl Ant { impl Ant {
@ -20,6 +23,8 @@ impl Ant {
Ant { Ant {
pos: Point(x, y), pos: Point(x, y),
id, id,
plan: vec![],
goal: AIGoal::Idle
} }
} }
} }

@ -18,7 +18,7 @@ fn manhattan(c1: &Point, c2: &Point) -> i32 {
return (c2.0 - c1.0).abs() + (c2.1 - c1.1).abs(); 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(); let mut open_set : HashSet<Point> = HashSet::new();
open_set.insert(*start); open_set.insert(*start);

@ -21,6 +21,10 @@ impl World {
self.cleared.insert(pos); 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> { pub fn get_valid_movements(&self, pos: &Point, b: &Screen) -> Vec<Point> {
let moves = b.get_valid_movements(pos); let moves = b.get_valid_movements(pos);
moves moves
@ -50,7 +54,10 @@ pub fn simulate(e: &mut Entities, w: &mut World, b: &mut Screen) {
let cmds: Vec<BoardCommand> = e let cmds: Vec<BoardCommand> = e
.data .data
.values_mut() .values_mut()
.map(|a| a.step(b, w)) .map(|a| {
a.plan(w);
a.step(b, w)
})
.collect(); .collect();
for cmd in cmds { for cmd in cmds {

Loading…
Cancel
Save