summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/character.rs95
-rw-r--r--src/list.rs37
-rw-r--r--src/location.rs1
-rw-r--r--src/main.rs16
-rw-r--r--src/map.rs5
-rw-r--r--src/view.rs5
6 files changed, 110 insertions, 49 deletions
diff --git a/src/character.rs b/src/character.rs
index 1e68dc9..8a3cb2f 100644
--- a/src/character.rs
+++ b/src/character.rs
@@ -1,39 +1,36 @@
extern crate rand;
use character::rand::Rng;
-extern crate pathfinding;
-use self::pathfinding::astar;
use constants::Orders;
use location::Location;
#[derive(Clone)]
pub struct Character {
- pub symbol : char,
- pub color : u8,
- pub order : u8,
- pub location : Location,
- pub needs_path : bool,
+ symbol : char,
+ color : u8,
+ order : u8,
+ location : Location,
desired_location : Option<Location>,
path : Option<Vec<Location>>,
}
impl Character {
+
pub fn new(symbol : char, color : u8, location : Location) -> Character {
Character {
symbol : symbol,
color : color,
order : Orders::Wander as u8,
location : location,
- needs_path : false,
desired_location : None,
path : None,
}
}
+
pub fn action(&mut self, free_spaces : Vec<(Location,usize)>) {
if self.order == Orders::Wander as u8 {
- self.needs_path = false;
self.wander(free_spaces);
}
else if self.order == Orders::Move as u8 {
@@ -41,27 +38,47 @@ impl Character {
}
}
- pub fn calculate_path(&mut self, impassable : Vec<(Location, usize)>) {
- match self.desired_location {
- None => self.order = Orders::Wander as u8,
- Some(target) => {
- let location = self.location;
- let result = astar(&location,
- |l| l.neighbours(impassable.clone()),
- |l| l.distance(&target),
- |l| *l == target);
- self.path = match result {
- Some(mut result) => {
- result.0.reverse();
- result.0.pop();
- Some(result.0)
- }
- None => {
- self.order = Orders::Wander as u8;
- None
- }
- };
- }
+ pub fn up(&mut self) {
+ self.location.0 -= 1;
+ }
+
+ pub fn down(&mut self) {
+ self.location.0 += 1;
+ }
+
+ pub fn right(&mut self) {
+ self.location.1 += 1;
+ }
+
+ pub fn left(&mut self) {
+ self.location.1 -= 1;
+ }
+
+ pub fn get_symbol(&self) -> char {
+ self.symbol
+ }
+
+ pub fn get_color(&self) -> u8 {
+ self.color
+ }
+
+ pub fn get_location(&self) -> Location {
+ self.location
+ }
+
+ pub fn get_desired_location(&self) -> Option<Location> {
+ self.desired_location
+ }
+
+ pub fn give_path(&mut self, path : Option<Vec<Location>>) {
+ match path {
+ Some(path) => {
+ self.path = Some(path);
+ },
+ None => {
+ self.path = None;
+ self.order = Orders::Wander as u8;
+ },
}
}
@@ -70,6 +87,21 @@ impl Character {
self.order = Orders::Move as u8;
}
+ pub fn needs_path(&self) -> bool {
+ if self.order == Orders::Wander as u8 {
+ false
+ }
+ else if self.path.is_some() {
+ false
+ }
+ else if self.desired_location.is_some() && self.path.is_none() {
+ true
+ }
+ else {
+ false
+ }
+ }
+
fn wander(&mut self, free_spaces : Vec<(Location, usize)>) {
let direction = rand::thread_rng().gen_range(0, free_spaces.len());
self.location = free_spaces[direction].0;
@@ -78,9 +110,8 @@ impl Character {
fn move_along_path(&mut self, free_spaces : Vec<(Location, usize)>) {
let mut moved = false;
match self.path {
- None => self.needs_path = true,
+ None => (),
Some(ref mut calculated_path) => {
- self.needs_path = false;
if calculated_path.len() > 0 {
let next_location = calculated_path.pop().unwrap();
for free_space in free_spaces {
diff --git a/src/list.rs b/src/list.rs
index 2340385..6292a2f 100644
--- a/src/list.rs
+++ b/src/list.rs
@@ -1,5 +1,8 @@
extern crate pancurses;
+extern crate pathfinding;
+use self::pathfinding::astar;
+
use location::Location;
use character::Character;
use constants::Colors;
@@ -23,16 +26,40 @@ impl List {
pub fn action(&mut self) {
for i in 0..self.men.len() {
- let location = self.men[i].location.clone();
+ let location = self.men[i].get_location();
let free_locations = self.get_free_locations(location);
self.men[i].action(free_locations);
}
let impassable = self.get_all_impassable();
for i in 0..self.men.len() {
- if self.men[i].needs_path {
- self.men[i].calculate_path(impassable.to_vec());
+ if self.men[i].needs_path() {
+ let man = self.men[i].clone();
+ let path = self.calculate_path(man, impassable.clone());
+ self.men[i].give_path(path);
+ }
+ }
+ }
+
+ fn calculate_path(&mut self, man : Character, impassable : Vec<(Location, usize)>) -> Option<Vec<Location>> {
+ let desired_location = man.get_desired_location();
+ match desired_location {
+ Some(target) => {
+ let location = man.get_location();
+ let result = astar(&location,
+ |l| l.neighbours(impassable.clone()),
+ |l| l.distance(&target),
+ |l| *l == target);
+ match result {
+ Some(mut result) => {
+ result.0.reverse();
+ result.0.pop();
+ Some(result.0)
+ }
+ None => None,
+ }
}
+ None => None,
}
}
@@ -84,7 +111,7 @@ impl List {
potential_locations.retain(|potential_location| {
let mut keep = true;
for man in self.men.iter() {
- if potential_location.0 == man.location {
+ if potential_location.0 == man.get_location() {
keep = false;
}
}
@@ -102,7 +129,7 @@ impl List {
fn get_all_impassable(&mut self) -> Vec<(Location, usize)> {
let mut impassable = Vec::new();
for man in self.men.iter() {
- impassable.push((man.location, 1));
+ impassable.push((man.get_location(), 1));
}
for impassable_location in self.impassable_locations.iter() {
impassable.push((*impassable_location,1));
diff --git a/src/location.rs b/src/location.rs
index ca40700..a6ac623 100644
--- a/src/location.rs
+++ b/src/location.rs
@@ -5,6 +5,7 @@ impl Location {
pub fn distance(&self, other: &Location) -> usize {
(((self.0 - other.0).pow(2) + (self.1 - other.1).pow(2)) as f64).sqrt() as usize
}
+
pub fn neighbours(self, impassable : Vec<(Location, usize)>) -> Vec<(Location, usize)> {
let mut nearby = vec![Location(self.0 + 1, self.1), Location(self.0 - 1, self.1),
Location(self.0, self.1 + 1), Location(self.0, self.1 - 1),
diff --git a/src/main.rs b/src/main.rs
index 6148aac..81ce270 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -47,10 +47,10 @@ fn main() {
let command = match main.getch() {
Some(Input::Character(ch)) => {
match ch {
- 'h' => {cursor.location.1 -= 1; None}
- 'l' => {cursor.location.1 += 1; None}
- 'k' => {cursor.location.0 -= 1; None}
- 'j' => {cursor.location.0 += 1; None}
+ 'k' => {cursor.up(); None}
+ 'j' => {cursor.down(); None}
+ 'h' => {cursor.left(); None}
+ 'l' => {cursor.right();None}
'q' => break,
'o' => Some(Commands::Go),
's' => Some(Commands::Grid),
@@ -65,17 +65,17 @@ fn main() {
map.fill();
match command {
- Some(Commands::Go) => list.give_destination(cursor.location),
+ Some(Commands::Go) => list.give_destination(cursor.get_location()),
Some(Commands::Grid) => {
paused = true;
draw_box = true;
- first_location = Some(cursor.location);
+ first_location = Some(cursor.get_location());
},
Some(Commands::Finish) => {
paused = false;
draw_box = false;
match first_location {
- Some(first_location) => list.give_grid(first_location, cursor.location),
+ Some(first_location) => list.give_grid(first_location, cursor.get_location()),
None => (),
}
},
@@ -90,7 +90,7 @@ fn main() {
if draw_box {
match first_location {
- Some(first_location) => map.draw_box(first_location, cursor.location),
+ Some(first_location) => map.draw_box(first_location, cursor.get_location()),
None => (),
}
}
diff --git a/src/map.rs b/src/map.rs
index 6546917..7794d65 100644
--- a/src/map.rs
+++ b/src/map.rs
@@ -60,8 +60,9 @@ impl Map {
}
pub fn draw(&self, character : &Character) {
- self.window.attron(ColorPair(character.color));
- self.window.mvaddch(character.location.0, character.location.1, character.symbol);
+ self.window.attron(ColorPair(character.get_color()));
+ let location = character.get_location();
+ self.window.mvaddch(location.0, location.1, character.get_symbol());
}
pub fn draw_box(&self, first_location : Location, second_location : Location) {
diff --git a/src/view.rs b/src/view.rs
index d62454b..f464da9 100644
--- a/src/view.rs
+++ b/src/view.rs
@@ -23,8 +23,9 @@ impl View {
}
pub fn center(&mut self, character : Character, map_window : &pancurses::Window) {
- let c = character.location.0 - self.width/2;
- let r = character.location.1 - self.height/2;
+ let location = character.get_location();
+ let c = location.0 - self.width/2;
+ let r = location.1 - self.height/2;
let (hh, ww) = map_window.get_max_yx();