Browse Source

Let all agents move at the same time

main
Adrian Heine 3 years ago
parent
commit
5e6177900e
  1. 4
      src/main.rs
  2. 85
      src/world.rs

4
src/main.rs

@ -44,11 +44,13 @@ fn main() {
.draw( .draw(
gen, gen,
world world
.state
.agent_positions .agent_positions
.get(&world.tagged)
.get(&world.state.tagged)
.map(|pos| (pos.x, pos.y)) .map(|pos| (pos.x, pos.y))
.unwrap(), .unwrap(),
world world
.state
.agent_positions .agent_positions
.iter() .iter()
.map(|(_id, pos)| (pos.x, pos.y)) .map(|(_id, pos)| (pos.x, pos.y))

85
src/world.rs

@ -1,10 +1,14 @@
use crate::agent::{Agent, AgentId, Direction, Move, Position, WorldView}; use crate::agent::{Agent, AgentId, Direction, Move, Position, WorldView};
use std::collections::hash_map::{Entry, HashMap};
use std::collections::hash_map::HashMap;
pub struct ActualWorld { pub struct ActualWorld {
size: Position, size: Position,
pub agent_positions: HashMap<AgentId, Position>,
pub agents: HashMap<AgentId, Box<dyn Agent>>, pub agents: HashMap<AgentId, Box<dyn Agent>>,
pub state: WorldState,
}
pub struct WorldState {
pub agent_positions: HashMap<AgentId, Position>,
pub tagged: AgentId, pub tagged: AgentId,
pub tagged_by: Option<AgentId>, pub tagged_by: Option<AgentId>,
} }
@ -23,12 +27,15 @@ impl ActualWorld {
agents.insert(id, agent); agents.insert(id, agent);
id += 1; id += 1;
} }
Self {
size,
let state = WorldState {
tagged_by: None, tagged_by: None,
tagged: id - 1, tagged: id - 1,
agents,
agent_positions, agent_positions,
};
Self {
size,
agents,
state,
} }
} }
@ -37,15 +44,16 @@ impl ActualWorld {
.agents .agents
.iter() .iter()
.map(|(id, agent)| { .map(|(id, agent)| {
let pos = self.agent_positions.get(id).unwrap();
let pos = self.state.agent_positions.get(id).unwrap();
( (
*id, *id,
agent.next_move(WorldView { agent.next_move(WorldView {
self_id: *id, self_id: *id,
tagged_by: self.tagged_by,
tagged: self.tagged,
tagged_by: self.state.tagged_by,
tagged: self.state.tagged,
bounds_distance: (pos.y, self.size.x - pos.x, self.size.y - pos.y, pos.x), bounds_distance: (pos.y, self.size.x - pos.x, self.size.y - pos.y, pos.x),
other_agents: self other_agents: self
.state
.agent_positions .agent_positions
.iter() .iter()
.filter(|(other_id, _)| id != *other_id) .filter(|(other_id, _)| id != *other_id)
@ -63,35 +71,54 @@ impl ActualWorld {
) )
}) })
.collect(); .collect();
let mut new_state = WorldState {
agent_positions: HashMap::with_capacity(self.state.agent_positions.len()),
tagged: self.state.tagged,
tagged_by: self.state.tagged_by,
};
for (id, mv) in moves { for (id, mv) in moves {
self.check_move(id, &mv);
//println!("{} {:?}", id, mv);
let mut new_pos = None;
match mv { match mv {
Move::Noop => {} Move::Noop => {}
Move::TryTag(other_id) => { Move::TryTag(other_id) => {
// FIXME check distance
assert_eq!(self.tagged, id);
assert_ne!(self.tagged_by, Some(other_id));
assert!(
self.agents.contains_key(&other_id),
"Trying to tag a nonexisting agent"
);
self.tagged = other_id;
self.tagged_by = Some(id);
new_state.tagged = other_id;
new_state.tagged_by = Some(id);
} }
Move::TryMove(dir) => { Move::TryMove(dir) => {
// FIXME check speed
let entry = self.agent_positions.entry(id);
let size = &self.size;
assert!(matches!(entry, Entry::Occupied(_)));
entry.and_modify(|e| {
e.x += dir.x;
assert!(e.x > 0);
assert!(e.x < size.x);
e.y += dir.y;
assert!(e.y > 0);
assert!(e.y < size.y);
});
let pos = self.state.agent_positions.get(&id).unwrap();
new_pos = Some((pos.x + dir.x, pos.y + dir.y).into());
} }
} }
new_state.agent_positions.insert(
id,
new_pos.unwrap_or_else(|| self.state.agent_positions.remove(&id).unwrap()),
);
}
self.state = new_state;
}
fn check_move(&self, id: AgentId, mv: &Move) {
match mv {
Move::Noop => {}
Move::TryTag(other_id) => {
// FIXME check distance
assert_eq!(self.state.tagged, id);
assert_ne!(self.state.tagged_by, Some(*other_id));
assert!(
self.agents.contains_key(&other_id),
"Trying to tag a nonexisting agent"
);
}
Move::TryMove(dir) => {
// FIXME check speed
let pos = self.state.agent_positions.get(&id).unwrap();
let size = &self.size;
assert!(pos.x + dir.x > 0);
assert!(pos.x + dir.x < size.x);
assert!(pos.y + dir.y > 0);
assert!(pos.y + dir.y < size.y);
}
} }
} }
} }

Loading…
Cancel
Save