diff --git a/src/agent.rs b/src/agent.rs index db15ccd..443ce16 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -103,6 +103,18 @@ fn random_move() -> Move { .into(), ) } +fn random_move_within( + (top, right, bottom, left): (Distance, Distance, Distance, Distance), +) -> Move { + loop { + let mv = random_move(); + if let Move::TryMove(Direction { x, y }) = mv { + if top + y > 0 && bottom - y > 0 && left + x > 0 && right - x > 0 { + return mv; + } + } + } +} impl Agent for SimpleAgent { fn next_move(&self, view: WorldView) -> Move { @@ -113,10 +125,10 @@ impl Agent for SimpleAgent { .find(|(dist, id)| dist.x.abs() <= 1 && dist.y.abs() <= 1 && Some(*id) != view.tagged_by) { Some((_, other)) => Move::TryTag(*other), - None => random_move(), + None => random_move_within(view.bounds_distance), } } else { - random_move() + random_move_within(view.bounds_distance) } } } diff --git a/src/world.rs b/src/world.rs index aeaf9cf..37969bc 100644 --- a/src/world.rs +++ b/src/world.rs @@ -78,13 +78,17 @@ impl ActualWorld { self.tagged_by = Some(id); } Move::TryMove(dir) => { - // FIXME check out of bounds // 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); }); } } @@ -133,4 +137,17 @@ mod test { assert_eq!(world.tagged, 0); assert_eq!(world.tagged_by, Some(1)); } + + #[test] + #[should_panic] + fn move_out_of_bounds() { + let mut world = ActualWorld::new( + Position { x: 1, y: 1 }, + vec![( + Position { x: 0, y: 0 }, + Box::new(ScriptedAgent::new(vec![Move::TryMove((-1, -1).into())])), + )], + ); + world.do_step(); + } }