Skip to content

Commit

Permalink
fix: fix an issue where players could ignore obstacles when moving
Browse files Browse the repository at this point in the history
  • Loading branch information
ShenMian committed Jan 18, 2024
1 parent 364edc9 commit 3575c57
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 12 deletions.
26 changes: 26 additions & 0 deletions src/board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,32 @@ impl Board {
}
}

pub fn moveable(&self, direction: Direction) -> bool {
let player_next_position = self.level.player_position + direction.to_vector();
if self
.level
.get_unchecked(&player_next_position)
.intersects(Tile::Wall)
{
return false;
}
if self
.level
.get_unchecked(&player_next_position)
.intersects(Tile::Crate)
{
let crate_next_position = player_next_position + direction.to_vector();
if self
.level
.get_unchecked(&crate_next_position)
.intersects(Tile::Crate | Tile::Wall)
{
return false;
}
}
return true;
}

pub fn move_or_push(&mut self, direction: Direction) {
let direction_vector = direction.to_vector();
let player_next_position = self.level.player_position + direction_vector;
Expand Down
10 changes: 7 additions & 3 deletions src/solver/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ impl Solver {
}

fn minimum_push_count_to_nearest_target(&self, position: &Vector2<i32>) -> Option<usize> {
// TODO: 优化求解器最小推动数计算方法
// 从目标开始逆推, 得到全部可达位置的下界.
// 若以存在下界, 取最小值. 若已经为更小的值, 停止搜索.

if self.level.target_positions.contains(position) {
return Some(0);
}
Expand Down Expand Up @@ -207,17 +211,17 @@ impl Solver {
]
.chunks(2)
{
let neighbor = [
let neighbors = [
position + directions[0].to_vector(),
position + directions[1].to_vector(),
];
if !(self
.level
.get_unchecked(&neighbor[0])
.get_unchecked(&neighbors[0])
.intersects(Tile::Wall)
&& self
.level
.get_unchecked(&neighbor[1])
.get_unchecked(&neighbors[1])
.intersects(Tile::Wall))
{
continue;
Expand Down
1 change: 1 addition & 0 deletions src/solver/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ impl State {
continue;
}

// TODO: 检测是否会产生新的死锁
if self.can_block_crate(&new_crate_position, solver) {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/systems/auto_solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub fn update_solver(
info!(" Solution: {}", solution.lurd());

for movement in &*solution {
player_move_or_push(movement.direction, &mut player_movement);
player_move(movement.direction, &mut player_movement);
}
next_state.set(AppState::Main);
return;
Expand Down
27 changes: 19 additions & 8 deletions src/systems/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ impl Action {

pub fn player_move_to(
target: &Vector2<i32>,
board: &mut crate::board::Board,
player_movement: &mut PlayerMovement,
board: &crate::board::Board,
) {
if let Some(path) = find_path(&board.level.player_position, target, |position| {
board
Expand All @@ -235,12 +235,23 @@ pub fn player_move_to(
.windows(2)
.map(|pos| Direction::from_vector(pos[1] - pos[0]).unwrap());
for direction in directions {
player_move_or_push(direction, player_movement);
player_move(direction, player_movement);
}
}
}

pub fn player_move_or_push(direction: Direction, player_movement: &mut PlayerMovement) {
pub fn player_move(direction: Direction, player_movement: &mut PlayerMovement) {
player_movement.directions.push_front(direction);
}

pub fn player_move_with_check(
direction: Direction,
player_movement: &mut PlayerMovement,
board: &crate::board::Board,
) {
if !board.moveable(direction) {
return;
}
player_movement.directions.push_front(direction);
}

Expand Down Expand Up @@ -291,16 +302,16 @@ pub fn handle_other_action(
let board = &mut board.single_mut().board;

if action_state.just_pressed(Action::MoveUp) {
player_move_or_push(Direction::Up, &mut player_movement);
player_move_with_check(Direction::Up, &mut player_movement, board);
}
if action_state.just_pressed(Action::MoveDown) {
player_move_or_push(Direction::Down, &mut player_movement);
player_move_with_check(Direction::Down, &mut player_movement, board);
}
if action_state.just_pressed(Action::MoveLeft) {
player_move_or_push(Direction::Left, &mut player_movement);
player_move_with_check(Direction::Left, &mut player_movement, board);
}
if action_state.just_pressed(Action::MoveRight) {
player_move_or_push(Direction::Right, &mut player_movement);
player_move_with_check(Direction::Right, &mut player_movement, board);
}

if action_state.just_pressed(Action::Undo) {
Expand Down Expand Up @@ -485,7 +496,7 @@ pub fn mouse_input(
_ => unreachable!(),
}

player_move_to(&grid_position, board, &mut player_movement);
player_move_to(&grid_position, &mut player_movement, board);
}
}

Expand Down

0 comments on commit 3575c57

Please sign in to comment.