diff --git a/src/agent.rs b/src/agent.rs new file mode 100644 index 0000000..58ecea0 --- /dev/null +++ b/src/agent.rs @@ -0,0 +1,30 @@ +pub type Distance = isize; + +pub struct Position { + pub x: Distance, + pub y: Distance, +} + +pub struct Direction { + pub x: Distance, + pub y: Distance, +} + +pub type AgentId = usize; + +pub struct WorldView { + pub self_tagged: bool, + pub bounds_distance: (Distance, Distance, Distance, Distance), + pub other_agents: Vec<(Direction, AgentId)>, +} + +pub enum Move { + Noop, // Why not an Option? + TryTag(AgentId), + TryMove(Direction), +} + +pub trait Agent { + fn next_move(&self, view: WorldView) -> Move; + fn get_tagged(&mut self, by: AgentId); +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..1ad7f26 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,2 @@ +pub mod agent; +pub mod world; diff --git a/src/world.rs b/src/world.rs new file mode 100644 index 0000000..9c9dda4 --- /dev/null +++ b/src/world.rs @@ -0,0 +1,62 @@ +use crate::agent::{Agent, AgentId, Direction, Move, Position, WorldView}; +use std::collections::HashMap; + +pub struct ActualWorld { + size: Position, + pub agent_positions: HashMap, + pub agents: HashMap>, + pub tagged: AgentId, + pub tagged_by: Option, +} + +impl ActualWorld { + pub fn do_step(&mut self) { + let moves: Vec<_> = self + .agents + .iter() + .map(|(id, agent)| { + let pos = self.agent_positions.get(id).unwrap(); + ( + *id, + agent.next_move(WorldView { + self_tagged: *id == self.tagged, + bounds_distance: (pos.y, self.size.x - pos.x, self.size.y - pos.y, pos.x), + other_agents: self + .agent_positions + .iter() + .map(|(id, other_pos)| { + ( + Direction { + x: other_pos.x - pos.x, + y: other_pos.y - pos.y, + }, + *id, + ) + }) + .collect(), + }), + ) + }) + .collect(); + for (id, mv) in moves { + match mv { + Move::Noop => {} + Move::TryTag(other_id) => { + // FIXME check distance + // FIXME check tagged_by + self.agents.get_mut(&other_id).unwrap().get_tagged(other_id); + // FIXME update tagged + // FIXME update tagged_by + } + Move::TryMove(dir) => { + // FIXME check out of bounds + // FIXME matches! + self.agent_positions.entry(id).and_modify(|e| { + e.x += dir.x; + e.y += dir.y; + }); + } + } + } + } +}