sideways #1
+16
-23
@@ -12,7 +12,7 @@ pub trait AI {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum AIGoal {
|
pub enum AIGoal {
|
||||||
Reach(Point),
|
Seek,
|
||||||
//Pickup(Point),
|
//Pickup(Point),
|
||||||
//Drop(),
|
//Drop(),
|
||||||
Idle,
|
Idle,
|
||||||
@@ -23,8 +23,9 @@ impl AI for Ant {
|
|||||||
// check last part of plan
|
// check last part of plan
|
||||||
if let Some(goal) = self.plan.last() {
|
if let Some(goal) = self.plan.last() {
|
||||||
match goal {
|
match goal {
|
||||||
AIGoal::Reach(target) => {
|
AIGoal::Seek => {
|
||||||
if self.pos == *target {
|
// if we reach food, we change state
|
||||||
|
if w.food.contains(&self.pos) {
|
||||||
self.plan.pop();
|
self.plan.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,31 +41,23 @@ impl AI for Ant {
|
|||||||
None => &AIGoal::Idle,
|
None => &AIGoal::Idle,
|
||||||
};
|
};
|
||||||
|
|
||||||
let choice = match goal {
|
let valid = w.get_valid_movements(&self.pos, b, true);
|
||||||
AIGoal::Idle => {
|
let mut rng = thread_rng();
|
||||||
// valid_movements does not return any diggables!
|
let choice = valid.choose(&mut rng).cloned();
|
||||||
let valid = w.get_valid_movements(&self.pos, b, true);
|
|
||||||
let mut rng = thread_rng();
|
|
||||||
valid.choose(&mut rng).cloned()
|
|
||||||
}
|
|
||||||
AIGoal::Reach(target) => {
|
|
||||||
// here astar only produces a path between the target & pos without digging
|
|
||||||
let result = astar(&self.pos, &target, Some(w), Some(b));
|
|
||||||
let mut movements = match result {
|
|
||||||
Ok(m) => m,
|
|
||||||
Err(_) => vec![]
|
|
||||||
};
|
|
||||||
movements.pop()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if !choice.is_none() {
|
if !choice.is_none() {
|
||||||
let pos = choice.unwrap();
|
let pos = choice.unwrap();
|
||||||
if w.cleared.contains(&pos) {
|
if w.cleared.contains(&pos) {
|
||||||
self.pos = pos;
|
self.pos = pos;
|
||||||
} else {
|
} else {
|
||||||
if w.is_safe_to_dig(&pos, &b) {
|
|
||||||
w.clear(pos);
|
match goal {
|
||||||
|
AIGoal::Seek => {
|
||||||
|
if w.is_safe_to_dig(&pos, &b) {
|
||||||
|
w.clear(pos);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
AIGoal::Idle => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ impl FoodGenerator {
|
|||||||
|
|
||||||
impl AI for FoodGenerator {
|
impl AI for FoodGenerator {
|
||||||
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand {
|
fn step(&mut self, b: &Screen, w: &mut World) -> BoardCommand {
|
||||||
|
// eventually might want to use poisson disk distrib instead
|
||||||
if self.timer % 600 == 0 && self.counter < 10 {
|
if self.timer % 600 == 0 && self.counter < 10 {
|
||||||
// generate random coords, if valid, spawn
|
// generate random coords, if valid, spawn
|
||||||
// if not, try again next step
|
// if not, try again next step
|
||||||
|
|||||||
+22
-19
@@ -6,7 +6,7 @@ use std::collections::HashSet;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct World {
|
pub struct World {
|
||||||
pub cleared: HashSet<Point>,
|
pub cleared: HashSet<Point>,
|
||||||
pub food: HashSet<u32>,
|
pub food: HashSet<Point>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl World {
|
impl World {
|
||||||
@@ -22,27 +22,27 @@ impl World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_chamber(&mut self, center: Point, radius: i32) {
|
pub fn create_chamber(&mut self, center: Point, radius: i32) {
|
||||||
let cx = center.0;
|
let cx = center.0;
|
||||||
let cy = center.1;
|
let cy = center.1;
|
||||||
|
|
||||||
for i in cx-radius..cx+radius {
|
for i in cx - radius..cx + radius {
|
||||||
for j in cy-radius..cy+radius {
|
for j in cy - radius..cy + radius {
|
||||||
self.clear(Point(i,j));
|
self.clear(Point(i, j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_valid_movement(&self, current: &Point, target: &Point, b: &Screen) -> bool {
|
pub fn is_valid_movement(&self, current: &Point, target: &Point, b: &Screen) -> bool {
|
||||||
// should allow down movements always
|
// should allow down movements always
|
||||||
|
|
||||||
let safe = target.is_below(*current) || (
|
let safe = target.is_below(*current)
|
||||||
!self.cleared.contains(&target.down())
|
|| (!self.cleared.contains(&target.down())
|
||||||
|| !self.cleared.contains(&target.left())
|
|| !self.cleared.contains(&target.left())
|
||||||
|| !self.cleared.contains(&target.right())
|
|| !self.cleared.contains(&target.right())
|
||||||
|| !self.cleared.contains(&target.bldiag())
|
|| !self.cleared.contains(&target.bldiag())
|
||||||
|| !self.cleared.contains(&target.uldiag())
|
|| !self.cleared.contains(&target.uldiag())
|
||||||
|| !self.cleared.contains(&target.brdiag())
|
|| !self.cleared.contains(&target.brdiag())
|
||||||
|| !self.cleared.contains(&target.urdiag()));
|
|| !self.cleared.contains(&target.urdiag()));
|
||||||
|
|
||||||
// of course, its only a valid move if you can walk there!
|
// of course, its only a valid move if you can walk there!
|
||||||
b.is_in_bounds(target) && self.cleared.contains(target) && safe
|
b.is_in_bounds(target) && self.cleared.contains(target) && safe
|
||||||
@@ -55,7 +55,7 @@ impl World {
|
|||||||
pub fn is_safe_to_dig(&self, target: &Point, b: &Screen) -> bool {
|
pub fn is_safe_to_dig(&self, target: &Point, b: &Screen) -> bool {
|
||||||
let mut hypothetical_world = self.clone();
|
let mut hypothetical_world = self.clone();
|
||||||
hypothetical_world.clear(*target);
|
hypothetical_world.clear(*target);
|
||||||
let result = astar(target, &Point(0, 0), Some(&hypothetical_world), Some(b));
|
let result = astar(target, &b.center, Some(&hypothetical_world), Some(b));
|
||||||
b.is_in_bounds(target) && result.is_ok()
|
b.is_in_bounds(target) && result.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,10 +82,12 @@ impl World {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if return_diggables {
|
if return_diggables {
|
||||||
ans.extend(self.get_diggable(b, pos));
|
let digs = self.get_diggable(b, pos);
|
||||||
|
ans.extend(digs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ans
|
ans
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +133,7 @@ pub fn simulate(e: &mut Entities, w: &mut World, b: &mut Screen) {
|
|||||||
BoardCommand::SpawnFood(pos) => {
|
BoardCommand::SpawnFood(pos) => {
|
||||||
let food = Food::new(pos.0, pos.1);
|
let food = Food::new(pos.0, pos.1);
|
||||||
e.add_entity(&food);
|
e.add_entity(&food);
|
||||||
|
w.food.insert(pos);
|
||||||
}
|
}
|
||||||
BoardCommand::Noop => {}
|
BoardCommand::Noop => {}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-3
@@ -17,16 +17,24 @@ mod lib {
|
|||||||
use lib::point::Point;
|
use lib::point::Point;
|
||||||
use lib::screen::init_screen;
|
use lib::screen::init_screen;
|
||||||
use lib::world::{World, simulate, render};
|
use lib::world::{World, simulate, render};
|
||||||
use lib::entity::{Entities, Queen};
|
use lib::entity::{Entities, Ant, FoodGenerator};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut board = init_screen();
|
let mut board = init_screen();
|
||||||
let mut world = World::new();
|
let mut world = World::new();
|
||||||
|
|
||||||
let mut entities = Entities::new();
|
let mut entities = Entities::new();
|
||||||
let q = Queen::new(board.center.0,board.center.1);
|
|
||||||
entities.add_entity(&q);
|
|
||||||
|
|
||||||
|
//let q = Queen::new(board.center.0,board.center.1);
|
||||||
|
//entities.add_entity(&q);
|
||||||
|
|
||||||
|
let fg = FoodGenerator::new();
|
||||||
|
entities.add_entity(&fg);
|
||||||
|
|
||||||
|
let mut a = Ant::new(board.center.0, board.center.1);
|
||||||
|
a.plan.push(lib::ai::AIGoal::Seek);
|
||||||
|
entities.add_entity(&a);
|
||||||
|
|
||||||
world.create_chamber(Point(board.center.0, board.center.1), 3);
|
world.create_chamber(Point(board.center.0, board.center.1), 3);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
Reference in New Issue
Block a user