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::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
}
}

@ -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
}
}
}

@ -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);

@ -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 {

Loading…
Cancel
Save