fix logic bug to make level 1 playable

This commit is contained in:
Michael Zhang 2020-06-08 04:01:21 -05:00
parent 37425edfe1
commit 17dfebda6c
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
4 changed files with 55 additions and 16 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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

View file

@ -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) {