Skip to content

Commit

Permalink
fix(solver): fix tunnel detection
Browse files Browse the repository at this point in the history
  • Loading branch information
ShenMian committed Jan 21, 2024
1 parent b39737e commit 3800148
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 61 deletions.
122 changes: 64 additions & 58 deletions src/solver/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,29 @@ use std::time::{Duration, Instant};

#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum Strategy {
/// Find any solution
/// Speed priority
Fast,

/// Balanced speed and steps
Mixed,

/// Find move optimal solutions with best pushes
// FIXME: 结果非最优解, 可能是由于遇到答案就直接返回忽略剩余状态导致的
OptimalMovePush,

/// Find push optimal solutions with best moves
OptimalPushMove,

Mixed,
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum LowerBoundMethod {
/// Minimum push count to nearest target
PushCount,

/// Minimum move count to nearest target
MoveCount,

/// Manhattan distance to nearest target
ManhattanDistance,
}

Expand Down Expand Up @@ -201,18 +207,18 @@ impl Solver {
}

fn calculate_tunnels(&self) -> HashSet<(Vector2<i32>, Direction)> {
let mut tunels = HashSet::new();
let mut tunnels = HashSet::new();
for x in 1..self.level.dimensions.x - 1 {
for y in 1..self.level.dimensions.y - 1 {
let position = Vector2::new(x, y);
if !self.level.get_unchecked(&position).intersects(Tile::Floor)
|| self.level.get_unchecked(&position).intersects(Tile::Target)
let player_position = Vector2::new(x, y);
if !self
.level
.get_unchecked(&player_position)
.intersects(Tile::Floor)
{
continue;
}

// #$#
// #@#
for (up, right, _down, left) in [
Direction::Up,
Direction::Right,
Expand All @@ -225,83 +231,83 @@ impl Solver {
.iter()
.tuple_windows::<(_, _, _, _)>()
{
// #$#
// #@#
if self
.level
.get_unchecked(&(position + left.to_vector()))
.get_unchecked(&(player_position + left.to_vector()))
.intersects(Tile::Wall)
&& self
.level
.get_unchecked(&(position + right.to_vector()))
.get_unchecked(&(player_position + right.to_vector()))
.intersects(Tile::Wall)
&& self
.level
.get_unchecked(&(position + up.to_vector() + left.to_vector()))
.get_unchecked(&(player_position + up.to_vector() + left.to_vector()))
.intersects(Tile::Wall)
&& self
.level
.get_unchecked(&(position + up.to_vector() + right.to_vector()))
.get_unchecked(&(player_position + up.to_vector() + right.to_vector()))
.intersects(Tile::Wall)
&& self
.level
.get_unchecked(&(position + up.to_vector()))
.get_unchecked(&(player_position + up.to_vector()))
.intersects(Tile::Floor)
&& !self
.level
.get_unchecked(&(player_position + up.to_vector()))
.intersects(Tile::Target)
{
tunels.insert((position, *up));
tunnels.insert((player_position, *up));
}
}

// #$_ _$#
// #@# #@#
// FIXME: Microban #11
/*
for (up, right, _down, left) in [
Direction::Up,
Direction::Right,
Direction::Down,
Direction::Left,
Direction::Up,
Direction::Right,
Direction::Down,
]
.iter()
.tuple_windows::<(_, _, _, _)>()
{
if self
// #$_ _$#
// #@# #@#
if self
.level
.get_unchecked(&(player_position + left.to_vector()))
.intersects(Tile::Wall)
&& self
.level
.get_unchecked(&(position + left.to_vector()))
.get_unchecked(&(player_position + right.to_vector()))
.intersects(Tile::Wall)
&& (self
.level
.get_unchecked(&(player_position + up.to_vector() + right.to_vector()))
.intersects(Tile::Wall)
&& self
.level
.get_unchecked(&(position + right.to_vector()))
.intersects(Tile::Wall)
&& ((self
.get_unchecked(
&(player_position + up.to_vector() + left.to_vector()),
)
.intersects(Tile::Floor)
|| self
.level
.get_unchecked(&(position + up.to_vector() + left.to_vector()))
.intersects(Tile::Wall)
.get_unchecked(
&(player_position + up.to_vector() + right.to_vector()),
)
.intersects(Tile::Floor)
&& self
.level
.get_unchecked(&(position + up.to_vector() + right.to_vector()))
.intersects(Tile::Floor))
|| (self
.level
.get_unchecked(&(position + up.to_vector() + left.to_vector()))
.intersects(Tile::Floor)
&& self
.level
.get_unchecked(&(position + up.to_vector() + right.to_vector()))
.intersects(Tile::Wall)))
&& self
.level
.get_unchecked(&(position + up.to_vector()))
.intersects(Tile::Floor)
{
tunels.insert((position, *up));
}
.get_unchecked(
&(player_position + up.to_vector() + left.to_vector()),
)
.intersects(Tile::Wall))
&& self
.level
.get_unchecked(&(player_position + up.to_vector()))
.intersects(Tile::Floor)
&& !self
.level
.get_unchecked(&(player_position + up.to_vector()))
.intersects(Tile::Target)
{
tunnels.insert((player_position, *up));
}
*/
}
}
}
tunels
tunnels
}

#[allow(dead_code)]
Expand Down
5 changes: 2 additions & 3 deletions src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ mod tests {
&levels,
0..155,
&[
35, 87, 92, 96, 97, 98, 107, 108, 110, 113, 116, 121, 122, 137, 138, 142, 144,
145, 149, 150, 152, 154
35, 92, 97, 107, 108, 110, 113, 116, 121, 138, 142, 144, 145, 149, 150, 152,
154
],
15 * 2
) == 0
Expand All @@ -78,7 +78,6 @@ mod tests {
&levels,
0..100,
&[
15, //
17, 20, 22, 23, 25, 26, 27, 29, 32, 33, 35, 37, 38, 39, 41, 42, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 66, 67, 68, 70, 71, 72, 73, 75,
78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 92, 93, 94, 95, 96, 97, 98, 99,
Expand Down

0 comments on commit 3800148

Please sign in to comment.