From 5e6177900e79b1388b7d6ccca16c8cf81f508a66 Mon Sep 17 00:00:00 2001 From: Adrian Heine Date: Thu, 22 Jul 2021 15:42:52 +0200 Subject: [PATCH] Let all agents move at the same time --- src/main.rs | 4 ++- src/world.rs | 85 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/src/main.rs b/src/main.rs index b97c267..eb212b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,11 +44,13 @@ fn main() { .draw( gen, world + .state .agent_positions - .get(&world.tagged) + .get(&world.state.tagged) .map(|pos| (pos.x, pos.y)) .unwrap(), world + .state .agent_positions .iter() .map(|(_id, pos)| (pos.x, pos.y)) diff --git a/src/world.rs b/src/world.rs index 37969bc..9c1ecc4 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,10 +1,14 @@ 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 { size: Position, - pub agent_positions: HashMap, pub agents: HashMap>, + pub state: WorldState, +} + +pub struct WorldState { + pub agent_positions: HashMap, pub tagged: AgentId, pub tagged_by: Option, } @@ -23,12 +27,15 @@ impl ActualWorld { agents.insert(id, agent); id += 1; } - Self { - size, + let state = WorldState { tagged_by: None, tagged: id - 1, - agents, agent_positions, + }; + Self { + size, + agents, + state, } } @@ -37,15 +44,16 @@ impl ActualWorld { .agents .iter() .map(|(id, agent)| { - let pos = self.agent_positions.get(id).unwrap(); + let pos = self.state.agent_positions.get(id).unwrap(); ( *id, agent.next_move(WorldView { 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), other_agents: self + .state .agent_positions .iter() .filter(|(other_id, _)| id != *other_id) @@ -63,35 +71,54 @@ impl ActualWorld { ) }) .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 { + self.check_move(id, &mv); + //println!("{} {:?}", id, mv); + let mut new_pos = None; match mv { Move::Noop => {} 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) => { - // 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); + } } } }