Skip to content

Commit

Permalink
refactor(level): remove Deref and DerefMut from Level struct
Browse files Browse the repository at this point in the history
  • Loading branch information
ShenMian committed Aug 2, 2024
1 parent 0588563 commit 6b11ff3
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 54 deletions.
42 changes: 15 additions & 27 deletions src/level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use std::{
collections::{HashMap, HashSet},
fmt,
ops::{Deref, DerefMut},
str::FromStr,
};

Expand Down Expand Up @@ -77,21 +76,22 @@ impl Level {
self.undo_action().unwrap();
}

let new_player_position = self.player_position() + &direction.into();
if self[new_player_position].intersects(Tiles::Wall) {
let new_player_position = self.map.player_position() + &direction.into();
if self.map[new_player_position].intersects(Tiles::Wall) {
return Err(ActionError::MoveBlocked);
}
if self[new_player_position].intersects(Tiles::Box) {
if self.map[new_player_position].intersects(Tiles::Box) {
let new_box_position = new_player_position + &direction.into();
if self[new_box_position].intersects(Tiles::Wall | Tiles::Box) {
if self.map[new_box_position].intersects(Tiles::Wall | Tiles::Box) {
return Err(ActionError::PushBlocked);
}
self.set_box_position(new_player_position, new_box_position);
self.map
.set_box_position(new_player_position, new_box_position);
self.actions.push(Action::Push(direction));
} else {
self.actions.push(Action::Move(direction));
}
self.set_player_position(new_player_position);
self.map.set_player_position(new_player_position);
self.undone_actions.clear();
Ok(())
}
Expand All @@ -100,12 +100,12 @@ impl Level {
pub fn undo_action(&mut self) -> Result<(), ActionError> {
if let Some(last_action) = self.actions.pop() {
if last_action.is_push() {
let box_position = self.player_position() + &last_action.direction().into();
let prev_box_position = self.player_position();
self.set_box_position(box_position, prev_box_position);
let box_position = self.map.player_position() + &last_action.direction().into();
let prev_box_position = self.map.player_position();
self.map.set_box_position(box_position, prev_box_position);
}
let prev_player_position = self.player_position() - &last_action.direction().into();
self.set_player_position(prev_player_position);
let prev_player_position = self.map.player_position() - &last_action.direction().into();
self.map.set_player_position(prev_player_position);
self.undone_actions.push(last_action);
Ok(())
} else {
Expand All @@ -127,7 +127,9 @@ impl Level {

/// Returns the reachable area for the player.
pub fn player_reachable_area(&self) -> HashSet<Vector2<i32>> {
reachable_area(self.player_position(), |position| self.can_move(position))
reachable_area(self.map.player_position(), |position| {
self.map.can_move(position)
})
}

/// Lazily loads levels from an XSB format string.
Expand Down Expand Up @@ -315,20 +317,6 @@ impl FromStr for Level {
}
}

impl Deref for Level {
type Target = Map;

fn deref(&self) -> &Self::Target {
&self.map
}
}

impl DerefMut for Level {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.map
}
}

fn is_xsb_string(str: &str) -> bool {
str.chars().all(is_xsb_symbol)
|| (str.chars().all(is_xsb_symbol_with_rle) && str.chars().any(is_xsb_symbol))
Expand Down
8 changes: 4 additions & 4 deletions tests/deadlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use utils::*;

#[test]
fn test_calculate_dead_positions() {
let level = load_level_from_file("assets/Microban_155.xsb", 3);
assert_eq!(calculate_static_deadlocks(&level).len(), 9);
let map = load_level_from_file("assets/Microban_155.xsb", 3).into_map();
assert_eq!(calculate_static_deadlocks(&map).len(), 9);

let level = load_level_from_file("assets/BoxWorld_100.xsb", 9);
assert_eq!(calculate_static_deadlocks(&level).len(), 17);
let map = load_level_from_file("assets/BoxWorld_100.xsb", 9).into_map();
assert_eq!(calculate_static_deadlocks(&map).len(), 17);
}
2 changes: 1 addition & 1 deletion tests/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ fn parse_map_error() {

#[test]
fn get() {
let mut map = load_level_from_file("assets/Holland_81.xsb", 9);
let mut map = load_level_from_file("assets/Holland_81.xsb", 9).into_map();
for x in 0..map.dimensions().x {
for y in 0..map.dimensions().y {
let position = Vector2::new(x, y);
Expand Down
44 changes: 22 additions & 22 deletions tests/path_finding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,55 @@ use utils::*;

#[test]
fn test_find_path() {
let level = load_level_from_file("assets/Microban II_135.xsb", 132);
let path = player_move_path(&level, Vector2::new(25, 21)).unwrap();
let map = load_level_from_file("assets/Microban II_135.xsb", 132).into_map();
let path = player_move_path(&map, Vector2::new(25, 21)).unwrap();
assert_eq!(path.len(), 41);
}

#[test]
fn test_box_move_waypoints() {
let level = load_level_from_file("assets/Microban_155.xsb", 3);
assert_eq!(box_move_waypoints(&level, Vector2::new(6, 3)).len(), 0);
let waypoints = box_move_waypoints(&level, Vector2::new(6, 2));
let map = load_level_from_file("assets/Microban_155.xsb", 3).into_map();
assert_eq!(box_move_waypoints(&map, Vector2::new(6, 3)).len(), 0);
let waypoints = box_move_waypoints(&map, Vector2::new(6, 2));
let positions: HashSet<_> = waypoints.iter().map(|((pos, _), _)| pos).collect();
assert_eq!(positions.len(), 15);

let level = load_level_from_file("assets/Microban II_135.xsb", 132);
let waypoints = box_move_waypoints(&level, Vector2::new(8, 7));
let map = load_level_from_file("assets/Microban II_135.xsb", 132).into_map();
let waypoints = box_move_waypoints(&map, Vector2::new(8, 7));
let positions: HashSet<_> = waypoints.iter().map(|((pos, _), _)| pos).collect();
let box_path = construct_box_path(Vector2::new(8, 7), Vector2::new(9, 8), &waypoints);
let player_path = construct_player_path(&level, Vector2::new(7, 6), &box_path);
let player_path = construct_player_path(&map, Vector2::new(7, 6), &box_path);
assert_eq!(positions.len(), 4 * 35);
assert_eq!(box_path.len() - 1, 110);
assert_eq!(player_path.len() - 1, 487);

let level = load_level_from_file("assets/Microban II_135.xsb", 133);
let waypoints = box_move_waypoints(&level, Vector2::new(18, 18));
let map = load_level_from_file("assets/Microban II_135.xsb", 133).into_map();
let waypoints = box_move_waypoints(&map, Vector2::new(18, 18));
let positions: HashSet<_> = waypoints.iter().map(|((pos, _), _)| pos).collect();
let box_path = construct_box_path(Vector2::new(18, 18), Vector2::new(17, 18), &waypoints);
let player_path = construct_player_path(&level, Vector2::new(16, 18), &box_path);
let player_path = construct_player_path(&map, Vector2::new(16, 18), &box_path);
assert_eq!(positions.len(), 4 * 6);
assert_eq!(box_path.len() - 1, 11);
assert_eq!(player_path.len() - 1, 618);

let level = load_level_from_file("assets/Microban II_135.xsb", 134);
let waypoints = box_move_waypoints(&level, Vector2::new(16, 34));
let map = load_level_from_file("assets/Microban II_135.xsb", 134).into_map();
let waypoints = box_move_waypoints(&map, Vector2::new(16, 34));
let box_path = construct_box_path(Vector2::new(16, 34), Vector2::new(20, 34), &waypoints);
let player_path = construct_player_path(&level, Vector2::new(18, 18), &box_path);
let player_path = construct_player_path(&map, Vector2::new(18, 18), &box_path);
assert_eq!(box_path.len() - 1, 124);
assert_eq!(player_path.len() - 1, 5037);

// FIXME:
// let level = load_level_from_file("assets/Microban II_135.xsb", 135);
// let waypoints = box_move_waypoints(&level, Vector2::new(21, 36));
// let box_path = construct_box_path(Vector2::new(21, 36), Vector2::new(21,
// 37), &waypoints); assert_eq!(box_path.len() - 1, 591);
// let player_path = construct_player_path(&level, Vector2::new(21, 38),
// &box_path); assert_eq!(player_path.len() - 1, 1108);
// let map = load_level_from_file("assets/Microban II_135.xsb", 135).into_map();
// let waypoints = box_move_waypoints(&map, Vector2::new(21, 36));
// let box_path = construct_box_path(Vector2::new(21, 36), Vector2::new(21, 37), &waypoints);
// assert_eq!(box_path.len() - 1, 591);
// let player_path = construct_player_path(&map, Vector2::new(21, 38), &box_path);
// assert_eq!(player_path.len() - 1, 1108);
}

#[test]
fn test_pushable_boxes() {
let level = load_level_from_file("assets/Microban_155.xsb", 3);
assert_eq!(pushable_boxes(&level), HashSet::from([Vector2::new(6, 2)]));
let map = load_level_from_file("assets/Microban_155.xsb", 3).into_map();
assert_eq!(pushable_boxes(&map), HashSet::from([Vector2::new(6, 2)]));
}

0 comments on commit 6b11ff3

Please sign in to comment.