fix logic bug to make level 1 playable
This commit is contained in:
parent
37425edfe1
commit
17dfebda6c
4 changed files with 55 additions and 16 deletions
|
@ -1,4 +1,4 @@
|
||||||
use std::collections::{HashSet, HashMap};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::enums::Board;
|
use crate::enums::Board;
|
||||||
|
|
|
@ -16,7 +16,7 @@ impl From<i32> for Board {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum Orientation {
|
pub enum Orientation {
|
||||||
None = 0,
|
None = 0,
|
||||||
Horizontal = 1,
|
Horizontal = 1,
|
||||||
|
|
|
@ -178,6 +178,7 @@ impl Level {
|
||||||
);
|
);
|
||||||
let segment_loc = (segment.position.0, segment.position.1, segment.board);
|
let segment_loc = (segment.position.0, segment.position.1, segment.board);
|
||||||
let target = segment_loc + direction;
|
let target = segment_loc + direction;
|
||||||
|
println!(" - target: {:?}", target);
|
||||||
|
|
||||||
// is the target actually in the map?
|
// is the target actually in the map?
|
||||||
if target.0 < 0
|
if target.0 < 0
|
||||||
|
@ -212,30 +213,44 @@ impl Level {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut segment_pos = segment.position;
|
let mut segment_pos = segment.position;
|
||||||
|
|
||||||
|
if segment_pos == (segment_loc.0, segment_loc.1) {
|
||||||
|
current_occupant = Some((i, segment.shape, block.orientation));
|
||||||
|
}
|
||||||
|
|
||||||
segment_pos.0 += offset.0;
|
segment_pos.0 += offset.0;
|
||||||
segment_pos.1 += offset.1;
|
segment_pos.1 += offset.1;
|
||||||
|
|
||||||
if segment_pos == (segment_loc.0, segment_loc.1) {
|
|
||||||
current_occupant = Some((i, segment.shape));
|
|
||||||
}
|
|
||||||
if segment_pos == (target.0, target.1) {
|
if segment_pos == (target.0, target.1) {
|
||||||
target_occupant = Some((Entity::Block(i), segment.shape));
|
target_occupant = Some((Entity::Block(i), segment.shape, block.orientation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// check if the target occupant is actually a player
|
||||||
|
if let None = target_occupant {
|
||||||
|
if segment.board == Board::Left && self.player1.position == (target.0, target.1) {
|
||||||
|
target_occupant =
|
||||||
|
Some((Entity::Player(Board::Left), Shape::Full, Orientation::None));
|
||||||
|
} else if segment.board == Board::Right && self.player2.position == (target.0, target.1)
|
||||||
|
{
|
||||||
|
target_occupant =
|
||||||
|
Some((Entity::Player(Board::Right), Shape::Full, Orientation::None));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
" occupants: {:?} | {:?}",
|
" - occupants: current={:?} | target={:?}",
|
||||||
current_occupant, target_occupant
|
current_occupant, target_occupant
|
||||||
);
|
);
|
||||||
|
|
||||||
// handle special pushes
|
// handle special pushes
|
||||||
if let Some((other_block, other_shape)) = current_occupant {
|
if let Some((other_block, other_shape, other_orientation)) = current_occupant {
|
||||||
// are both shapes triangles?
|
// are both shapes triangles?
|
||||||
let both_triangles = match (segment.shape, other_shape) {
|
let both_triangles = match (segment.shape, other_shape) {
|
||||||
(Shape::Full, Shape::Full) => false,
|
(Shape::Full, Shape::Full) => false,
|
||||||
|
(Shape::Full, _) => unreachable!("invalid to have triangle + full"),
|
||||||
|
(_, Shape::Full) => unreachable!("invalid to have triangle + full"),
|
||||||
_ => true,
|
_ => true,
|
||||||
// TODO: enumerate them to get rid of invalid states
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if both_triangles {
|
if both_triangles {
|
||||||
|
@ -247,23 +262,42 @@ impl Level {
|
||||||
Shape::BottomRight => [PushDir::Right, PushDir::Down],
|
Shape::BottomRight => [PushDir::Right, PushDir::Down],
|
||||||
Shape::Full => unreachable!("already eliminated this possibility"),
|
Shape::Full => unreachable!("already eliminated this possibility"),
|
||||||
};
|
};
|
||||||
|
println!(" - possible directions: {:?}", possible_directions);
|
||||||
|
|
||||||
// does the direction we're pushing appear in this list?
|
// does the direction we're pushing appear in this list?
|
||||||
if possible_directions.contains(&direction) {
|
if possible_directions.contains(&direction) {
|
||||||
// the other shape goes in the other direction
|
// the other shape goes in the other direction
|
||||||
let other_direction = {
|
let other_direction = match other_orientation {
|
||||||
let mut set = possible_directions.iter().collect::<HashSet<_>>();
|
Orientation::None => unreachable!("already eliminated this possibility"),
|
||||||
set.remove(&direction);
|
Orientation::Vertical => [PushDir::Up, PushDir::Down],
|
||||||
*set.into_iter().next().unwrap()
|
Orientation::Horizontal => [PushDir::Left, PushDir::Right],
|
||||||
|
Orientation::Both => unimplemented!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
return self.block_can_move(other_block, other_direction, change_set);
|
let possible_directions = possible_directions.iter().collect::<HashSet<_>>();
|
||||||
|
let other_direction = other_direction.iter().collect();
|
||||||
|
let mut intersected_direction =
|
||||||
|
possible_directions.intersection(&other_direction);
|
||||||
|
let new_direction = **intersected_direction.next().unwrap();
|
||||||
|
|
||||||
|
// let other_direction = {
|
||||||
|
// let mut set = possible_directions.iter().collect::<HashSet<_>>();
|
||||||
|
// set.remove(&direction);
|
||||||
|
// *set.into_iter().next().unwrap()
|
||||||
|
// };
|
||||||
|
|
||||||
|
let mut result = self.block_can_move(other_block, new_direction, change_set);
|
||||||
|
if let Ok(ref mut change_set) = result {
|
||||||
|
change_set.insert(Entity::Block(other_block), new_direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle normal pushes
|
// handle normal pushes
|
||||||
if let Some((entity, shape)) = target_occupant {
|
if let Some((entity, shape, _orientation)) = target_occupant {
|
||||||
match entity {
|
match entity {
|
||||||
Entity::Player(_) => {
|
Entity::Player(_) => {
|
||||||
// TODO: assert that the board is the same
|
// TODO: assert that the board is the same
|
||||||
|
|
|
@ -83,9 +83,9 @@ impl PlayScreen {
|
||||||
|
|
||||||
pub fn new() -> PlayScreen {
|
pub fn new() -> PlayScreen {
|
||||||
let levels = vec![
|
let levels = vec![
|
||||||
Level::from_json(&LEVEL_1),
|
|
||||||
Level::from_json(&LEVEL_TUTORIAL),
|
Level::from_json(&LEVEL_TUTORIAL),
|
||||||
Level::from_json(&LEVEL_TUTORIAL2),
|
Level::from_json(&LEVEL_TUTORIAL2),
|
||||||
|
Level::from_json(&LEVEL_1),
|
||||||
];
|
];
|
||||||
|
|
||||||
PlayScreen {
|
PlayScreen {
|
||||||
|
@ -97,6 +97,11 @@ impl PlayScreen {
|
||||||
|
|
||||||
fn go_to_next_level(&mut self) {
|
fn go_to_next_level(&mut self) {
|
||||||
self.current_level += 1;
|
self.current_level += 1;
|
||||||
|
|
||||||
|
// TODO: make an actual win screen
|
||||||
|
if self.current_level >= self.levels.len() {
|
||||||
|
self.current_level = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_win_condition(&mut self) {
|
fn check_win_condition(&mut self) {
|
||||||
|
|
Loading…
Reference in a new issue