Move tests to separate file, escape -> pause

main
Elijah Voigt 1 day ago
parent 90a6181e22
commit c3335e9263

@ -1,9 +1,13 @@
// Bevy basically forces "complex types" with Querys // Bevy basically forces "complex types" with Querys
#![allow(clippy::type_complexity)] #![allow(clippy::type_complexity)]
use itertools::Itertools;
use games::*; use games::*;
use itertools::Itertools;
#[cfg(test)]
mod test;
// TODO: Space key: skip to end
// TODO: When line is "full" (has 10 children) clear line and add to score // TODO: When line is "full" (has 10 children) clear line and add to score
fn main() { fn main() {
@ -14,23 +18,24 @@ fn main() {
game_type: GameType::Two, game_type: GameType::Two,
..default() ..default()
}) })
.init_state::<Falling>() .init_state::<GameState>()
.add_systems(Startup, (init_world, init_debug_ui)) .add_systems(Startup, (init_world, init_debug_ui, init_ui))
.add_systems( .add_systems(
Update, Update,
( (
kb_input.run_if(on_event::<KeyboardInput>), kb_input.run_if(on_event::<KeyboardInput>),
falling falling
.run_if(in_state(Falling::On)) .run_if(in_state(GameState::Falling))
.run_if(clock_cycle(1.0)), .run_if(clock_cycle(1.0)),
update_shape_blocks update_shape_blocks
.run_if(any_component_added::<Shape>.or(any_component_changed::<Shape>)), .run_if(any_component_added::<Shape>.or(any_component_changed::<Shape>)),
sync_singleton_to_ui::<Shape>.run_if(any_component_changed::<Shape>), sync_singleton_to_ui::<Shape>.run_if(any_component_changed::<Shape>),
sync_singleton_to_ui::<Orientation>.run_if(any_component_changed::<Orientation>), sync_singleton_to_ui::<Orientation>.run_if(any_component_changed::<Orientation>),
update_position, update_position.run_if(any_component_changed::<GridPosition>),
add_piece.run_if(not(any_with_component::<Shape>)), add_piece.run_if(not(any_with_component::<Shape>)),
clear_line.run_if(any_component_changed::<LineBlocks>), clear_line.run_if(any_component_changed::<LineBlocks>),
adjust_block_lines.run_if(any_component_changed::<Line>), adjust_block_lines.run_if(any_component_changed::<Line>),
toggle_state_visibility::<GameState>.run_if(state_changed::<GameState>),
), ),
) )
.add_systems(Update, draw_grid) .add_systems(Update, draw_grid)
@ -208,10 +213,10 @@ impl Display for Orientation {
} }
#[derive(States, Clone, Eq, PartialEq, Debug, Hash, Default, Component)] #[derive(States, Clone, Eq, PartialEq, Debug, Hash, Default, Component)]
enum Falling { enum GameState {
#[default] #[default]
On, Falling,
Off, Pause,
} }
#[derive(Resource, Debug)] #[derive(Resource, Debug)]
@ -238,6 +243,21 @@ fn init_world(
}); });
} }
fn init_ui(mut commands: Commands) {
commands
.spawn((
Node {
align_self: AlignSelf::Center,
justify_self: JustifySelf::Center,
..default()
},
GameState::Pause,
))
.with_children(|parent| {
parent.spawn(Text::new("Paused"));
});
}
fn init_debug_ui(mut commands: Commands) { fn init_debug_ui(mut commands: Commands) {
commands commands
.spawn(( .spawn((
@ -480,9 +500,9 @@ fn update_shape_blocks(
fn kb_input( fn kb_input(
mut events: EventReader<KeyboardInput>, mut events: EventReader<KeyboardInput>,
mut query: Query<(Entity, &Orientation, &mut Shape)>, mut query: Query<(Entity, &mut Shape)>,
curr: Res<State<Falling>>, curr: Res<State<GameState>>,
mut next: ResMut<NextState<Falling>>, mut next: ResMut<NextState<GameState>>,
mut commands: Commands, mut commands: Commands,
) { ) {
events.read().for_each( events.read().for_each(
@ -490,7 +510,7 @@ fn kb_input(
key_code, state, .. key_code, state, ..
}| { }| {
if let ButtonState::Pressed = state { if let ButtonState::Pressed = state {
query.iter_mut().for_each(|(e, o, mut s)| { query.iter_mut().for_each(|(e, mut s)| {
match key_code { match key_code {
// Up arrow should rotate if in falling mode // Up arrow should rotate if in falling mode
// Only move up if in falling::off mode // Only move up if in falling::off mode
@ -506,9 +526,9 @@ fn kb_input(
KeyCode::ArrowRight => { KeyCode::ArrowRight => {
commands.entity(e).trigger(Movement::Right); commands.entity(e).trigger(Movement::Right);
} }
KeyCode::Space => next.set(match curr.get() { KeyCode::Escape => next.set(match curr.get() {
Falling::On => Falling::Off, GameState::Falling => GameState::Pause,
Falling::Off => Falling::On, GameState::Pause => GameState::Falling,
}), }),
KeyCode::Digit1 => *s = Shape::new_t(), KeyCode::Digit1 => *s = Shape::new_t(),
KeyCode::Digit2 => *s = Shape::new_o(), KeyCode::Digit2 => *s = Shape::new_o(),
@ -719,91 +739,3 @@ fn deactive_shape(
commands.entity(trigger.target()).despawn(); commands.entity(trigger.target()).despawn();
} }
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_shape_t() {
let mut shape = Shape::new_t();
let expected_up = "010\n\
111\n\
000\n";
let expected_right = "010\n\
011\n\
010\n";
let expected_down = "000\n\
111\n\
010\n";
let expected_left = "010\n\
110\n\
010\n";
assert_eq!(shape.as_ascii(), expected_up);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_right);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_down);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_left);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_up);
}
#[test]
fn test_shape_i() {
let mut shape = Shape::new_i();
let expected_up = "0010\n\
0010\n\
0010\n\
0010\n";
let expected_right = "0000\n\
0000\n\
1111\n\
0000\n";
let expected_down = "0100\n\
0100\n\
0100\n\
0100\n";
let expected_left = "0000\n\
1111\n\
0000\n\
0000\n";
assert_eq!(shape.as_ascii(), expected_up);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_right);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_down);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_left);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_up);
}
#[test]
fn test_coordinates() {
let shape = Shape::new_t();
let center = GridPosition { x: 5, y: 5 };
let expected: Vec<Result<GridPosition, GameError>> = vec![
Ok((5, 6).into()),
Ok((4, 5).into()),
Ok((5, 5).into()),
Ok((6, 5).into()),
];
let actual: Vec<Result<GridPosition, GameError>> = shape.coordinates(&center).collect();
assert_eq!(actual, expected);
}
}

@ -0,0 +1,85 @@
use super::*;
#[test]
fn test_shape_t() {
let mut shape = Shape::new_t();
let expected_up = "010\n\
111\n\
000\n";
let expected_right = "010\n\
011\n\
010\n";
let expected_down = "000\n\
111\n\
010\n";
let expected_left = "010\n\
110\n\
010\n";
assert_eq!(shape.as_ascii(), expected_up);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_right);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_down);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_left);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_up);
}
#[test]
fn test_shape_i() {
let mut shape = Shape::new_i();
let expected_up = "0010\n\
0010\n\
0010\n\
0010\n";
let expected_right = "0000\n\
0000\n\
1111\n\
0000\n";
let expected_down = "0100\n\
0100\n\
0100\n\
0100\n";
let expected_left = "0000\n\
1111\n\
0000\n\
0000\n";
assert_eq!(shape.as_ascii(), expected_up);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_right);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_down);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_left);
shape.rotate();
assert_eq!(shape.as_ascii(), expected_up);
}
#[test]
fn test_coordinates() {
let shape = Shape::new_t();
let center = GridPosition { x: 5, y: 5 };
let expected: Vec<Result<GridPosition, GameError>> = vec![
Ok((5, 6).into()),
Ok((4, 5).into()),
Ok((5, 5).into()),
Ok((6, 5).into()),
];
let actual: Vec<Result<GridPosition, GameError>> = shape.coordinates(&center).collect();
assert_eq!(actual, expected);
}
Loading…
Cancel
Save