A simple actor-based simulation of tag, implemented in rust.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
1.6 KiB

use crate::agent::{Agent, AgentId, Direction, Move, Position, WorldView};
use std::collections::HashMap;
pub struct ActualWorld {
size: Position,
pub agent_positions: HashMap<AgentId, Position>,
pub agents: HashMap<AgentId, Box<dyn Agent>>,
pub tagged: AgentId,
pub tagged_by: Option<AgentId>,
}
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;
});
}
}
}
}
}