diff --git a/src/animations.rs b/src/animations.rs index 8c9e51b..fd90058 100644 --- a/src/animations.rs +++ b/src/animations.rs @@ -1,4 +1,4 @@ -use std::collections::{HashSet, HashMap}; +use std::collections::{HashMap, HashSet}; use std::time::Duration; use crate::enums::Board; diff --git a/src/enums.rs b/src/enums.rs index 38dd1f3..b97241e 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -16,7 +16,7 @@ impl From for Board { } } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub enum Orientation { None = 0, Horizontal = 1, diff --git a/src/level/mod.rs b/src/level/mod.rs index e4927ae..68ec8d9 100644 --- a/src/level/mod.rs +++ b/src/level/mod.rs @@ -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::>(); - 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::>(); + 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::>(); + // 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 diff --git a/src/screens/play.rs b/src/screens/play.rs index dcfd7c1..0f75b64 100644 --- a/src/screens/play.rs +++ b/src/screens/play.rs @@ -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) {