Skip to content

Commit

Permalink
test(deadlock): refactor static deadlock calculation tests
Browse files Browse the repository at this point in the history
- Improve code readability and maintainability
  • Loading branch information
ShenMian committed Jan 14, 2025
1 parent b3b3ce9 commit 773ac9b
Show file tree
Hide file tree
Showing 6 changed files with 319 additions and 67 deletions.
236 changes: 236 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'soukoban'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=soukoban"
],
"filter": {
"name": "soukoban",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'action'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=action",
"--package=soukoban"
],
"filter": {
"name": "action",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'actions'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=actions",
"--package=soukoban"
],
"filter": {
"name": "actions",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'deadlock'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=deadlock",
"--package=soukoban"
],
"filter": {
"name": "deadlock",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'direction'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=direction",
"--package=soukoban"
],
"filter": {
"name": "direction",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'level'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=level",
"--package=soukoban"
],
"filter": {
"name": "level",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'map'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=map",
"--package=soukoban"
],
"filter": {
"name": "map",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'path_finding'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=path_finding",
"--package=soukoban"
],
"filter": {
"name": "path_finding",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'run_length'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=run_length",
"--package=soukoban"
],
"filter": {
"name": "run_length",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'solver'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=solver",
"--package=soukoban"
],
"filter": {
"name": "solver",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'utils'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=utils",
"--package=soukoban"
],
"filter": {
"name": "utils",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug benchmark 'benchmark'",
"cargo": {
"args": [
"test",
"--no-run",
"--bench=benchmark",
"--package=soukoban"
],
"filter": {
"name": "benchmark",
"kind": "bench"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}
99 changes: 54 additions & 45 deletions src/deadlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,51 +95,6 @@ pub fn is_freeze_deadlock(
true
}

/// Calculates unused floors.
pub fn calculate_unused_floors(mut map: Map) -> HashSet<Vector2<i32>> {
let mut unused_floors = HashSet::new();

// Add all floors to `unchecked_floors`
let mut unchecked_floors = VecDeque::new();
for y in 1..map.dimensions().y - 1 {
for x in 1..map.dimensions().x - 1 {
let position = Vector2::new(x, y);
if map[position] == Tiles::Floor {
unchecked_floors.push_back(position);
}
}
}

while let Some(position) = unchecked_floors.pop_front() {
// Check if the current floor is in a dead end and store the exit position in
// `neighbor_floor`
let mut neighbor_floor = None;
for direction in Direction::iter() {
let neighbor = position + &direction.into();
if !map[neighbor].intersects(Tiles::Wall) {
if neighbor_floor.is_some() {
neighbor_floor = None;
break;
}
neighbor_floor = Some(neighbor);
}
}
// If the current floor is in a dead end
if let Some(free_neighbor) = neighbor_floor {
unused_floors.insert(position);
map[position].remove(Tiles::Floor);
map[position].insert(Tiles::Wall);
// As the only floor affected by terrain changes, `free_neighbor` may become a
// new unused floor and needs to be rechecked.
if map[free_neighbor] == Tiles::Floor && !map[free_neighbor].intersects(Tiles::Wall) {
unchecked_floors.push_back(free_neighbor);
}
}
}

unused_floors
}

/// Calculates static deadlock positions independent of the player's position.
///
/// This function returns an **incomplete** set of dead positions independent
Expand Down Expand Up @@ -195,3 +150,57 @@ pub fn calculate_static_deadlocks(map: &Map) -> HashSet<Vector2<i32>> {
}
dead_positions
}

/// Calculates unused floors.
pub fn calculate_unused_floors(mut map: Map) -> HashSet<Vector2<i32>> {
let mut unused_floors = HashSet::new();

// Add all floors to `unchecked_floors`
let mut unchecked_floors = VecDeque::new();
for y in 1..map.dimensions().y - 1 {
for x in 1..map.dimensions().x - 1 {
let position = Vector2::new(x, y);
if map[position] == Tiles::Floor {
unchecked_floors.push_back(position);
}
}
}

while let Some(position) = unchecked_floors.pop_front() {
// Check if the current floor is in a dead end and store the exit position in
// `neighbor_floor`
let mut neighbor_floor = None;
for direction in Direction::iter() {
let neighbor = position + &direction.into();
if !map[neighbor].intersects(Tiles::Wall) {
if neighbor_floor.is_some() {
neighbor_floor = None;
break;
}
neighbor_floor = Some(neighbor);
}
}
// If the current floor is in a dead end
if let Some(free_neighbor) = neighbor_floor {
unused_floors.insert(position);
map[position].remove(Tiles::Floor);
map[position].insert(Tiles::Wall);
// As the only floor affected by terrain changes, `free_neighbor` may become a
// new unused floor and needs to be rechecked.
if map[free_neighbor] == Tiles::Floor && !map[free_neighbor].intersects(Tiles::Wall) {
unchecked_floors.push_back(free_neighbor);
}
}
}

unused_floors
}

// pub fn calculate_deadlocked_boxes(mut map: Map) -> Vec<Vector2<i32>> {
// map.box_positions()
// .iter()
// .filter(|&position| {
// is_freeze_deadlock(map, position, map.box_positions(), &mut HashSet::new())
// })
// .collect::<Vec<_>>()
// }
Loading

0 comments on commit 773ac9b

Please sign in to comment.