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 crate::enums::Board;
|
||||
|
|
|
@ -16,7 +16,7 @@ impl From<i32> for Board {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Orientation {
|
||||
None = 0,
|
||||
Horizontal = 1,
|
||||
|
|
|
@ -178,6 +178,7 @@ impl Level {
|
|||
);
|
||||
let segment_loc = (segment.position.0, segment.position.1, segment.board);
|
||||
let target = segment_loc + direction;
|
||||
println!(" - target: {:?}", target);
|
||||
|
||||
// is the target actually in the map?
|
||||
if target.0 < 0
|
||||
|
@ -212,30 +213,44 @@ impl Level {
|
|||
}
|
||||
|
||||
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.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) {
|
||||
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!(
|
||||
" occupants: {:?} | {:?}",
|
||||
" - occupants: current={:?} | target={:?}",
|
||||
current_occupant, target_occupant
|
||||
);
|
||||
|
||||
// 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?
|
||||
let both_triangles = match (segment.shape, other_shape) {
|
||||
(Shape::Full, Shape::Full) => false,
|
||||
(Shape::Full, _) => unreachable!("invalid to have triangle + full"),
|
||||
(_, Shape::Full) => unreachable!("invalid to have triangle + full"),
|
||||
_ => true,
|
||||
// TODO: enumerate them to get rid of invalid states
|
||||
};
|
||||
|
||||
if both_triangles {
|
||||
|
@ -247,23 +262,42 @@ impl Level {
|
|||
Shape::BottomRight => [PushDir::Right, PushDir::Down],
|
||||
Shape::Full => unreachable!("already eliminated this possibility"),
|
||||
};
|
||||
println!(" - possible directions: {:?}", possible_directions);
|
||||
|
||||
// does the direction we're pushing appear in this list?
|
||||
if possible_directions.contains(&direction) {
|
||||
// the other shape goes in the other direction
|
||||
let other_direction = {
|
||||
let mut set = possible_directions.iter().collect::<HashSet<_>>();
|
||||
set.remove(&direction);
|
||||
*set.into_iter().next().unwrap()
|
||||
let other_direction = match other_orientation {
|
||||
Orientation::None => unreachable!("already eliminated this possibility"),
|
||||
Orientation::Vertical => [PushDir::Up, PushDir::Down],
|
||||
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
|
||||
if let Some((entity, shape)) = target_occupant {
|
||||
if let Some((entity, shape, _orientation)) = target_occupant {
|
||||
match entity {
|
||||
Entity::Player(_) => {
|
||||
// TODO: assert that the board is the same
|
||||
|
|
|
@ -83,9 +83,9 @@ impl PlayScreen {
|
|||
|
||||
pub fn new() -> PlayScreen {
|
||||
let levels = vec![
|
||||
Level::from_json(&LEVEL_1),
|
||||
Level::from_json(&LEVEL_TUTORIAL),
|
||||
Level::from_json(&LEVEL_TUTORIAL2),
|
||||
Level::from_json(&LEVEL_1),
|
||||
];
|
||||
|
||||
PlayScreen {
|
||||
|
@ -97,6 +97,11 @@ impl PlayScreen {
|
|||
|
||||
fn go_to_next_level(&mut self) {
|
||||
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) {
|
||||
|
|
Loading…
Reference in a new issue