3 changed files with 94 additions and 0 deletions
			
			
		- 
					30src/agent.rs
- 
					2src/lib.rs
- 
					62src/world.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);
 | |||
| }
 | |||
| @ -0,0 +1,2 @@ | |||
| pub mod agent;
 | |||
| pub mod world;
 | |||
| @ -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<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;
 | |||
|           });
 | |||
|         }
 | |||
|       }
 | |||
|     }
 | |||
|   }
 | |||
| }
 | |||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue