From c3335e9263be06fdb2bf84bd4ab282663ef19f04 Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Sat, 25 Oct 2025 14:51:37 -0700 Subject: [PATCH] Move tests to separate file, escape -> pause --- src/bin/tetris/main.rs | 138 +++++++++++------------------------------ src/bin/tetris/test.rs | 85 +++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 103 deletions(-) create mode 100644 src/bin/tetris/test.rs diff --git a/src/bin/tetris/main.rs b/src/bin/tetris/main.rs index 3236638..224ffb0 100644 --- a/src/bin/tetris/main.rs +++ b/src/bin/tetris/main.rs @@ -1,9 +1,13 @@ // Bevy basically forces "complex types" with Querys #![allow(clippy::type_complexity)] -use itertools::Itertools; 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 fn main() { @@ -14,23 +18,24 @@ fn main() { game_type: GameType::Two, ..default() }) - .init_state::() - .add_systems(Startup, (init_world, init_debug_ui)) + .init_state::() + .add_systems(Startup, (init_world, init_debug_ui, init_ui)) .add_systems( Update, ( kb_input.run_if(on_event::), falling - .run_if(in_state(Falling::On)) + .run_if(in_state(GameState::Falling)) .run_if(clock_cycle(1.0)), update_shape_blocks .run_if(any_component_added::.or(any_component_changed::)), sync_singleton_to_ui::.run_if(any_component_changed::), sync_singleton_to_ui::.run_if(any_component_changed::), - update_position, + update_position.run_if(any_component_changed::), add_piece.run_if(not(any_with_component::)), clear_line.run_if(any_component_changed::), adjust_block_lines.run_if(any_component_changed::), + toggle_state_visibility::.run_if(state_changed::), ), ) .add_systems(Update, draw_grid) @@ -208,10 +213,10 @@ impl Display for Orientation { } #[derive(States, Clone, Eq, PartialEq, Debug, Hash, Default, Component)] -enum Falling { +enum GameState { #[default] - On, - Off, + Falling, + Pause, } #[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) { commands .spawn(( @@ -480,9 +500,9 @@ fn update_shape_blocks( fn kb_input( mut events: EventReader, - mut query: Query<(Entity, &Orientation, &mut Shape)>, - curr: Res>, - mut next: ResMut>, + mut query: Query<(Entity, &mut Shape)>, + curr: Res>, + mut next: ResMut>, mut commands: Commands, ) { events.read().for_each( @@ -490,7 +510,7 @@ fn kb_input( key_code, 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 { // Up arrow should rotate if in falling mode // Only move up if in falling::off mode @@ -506,9 +526,9 @@ fn kb_input( KeyCode::ArrowRight => { commands.entity(e).trigger(Movement::Right); } - KeyCode::Space => next.set(match curr.get() { - Falling::On => Falling::Off, - Falling::Off => Falling::On, + KeyCode::Escape => next.set(match curr.get() { + GameState::Falling => GameState::Pause, + GameState::Pause => GameState::Falling, }), KeyCode::Digit1 => *s = Shape::new_t(), KeyCode::Digit2 => *s = Shape::new_o(), @@ -719,91 +739,3 @@ fn deactive_shape( 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> = vec![ - Ok((5, 6).into()), - Ok((4, 5).into()), - Ok((5, 5).into()), - Ok((6, 5).into()), - ]; - - let actual: Vec> = shape.coordinates(¢er).collect(); - - assert_eq!(actual, expected); - } -} diff --git a/src/bin/tetris/test.rs b/src/bin/tetris/test.rs new file mode 100644 index 0000000..0f85d35 --- /dev/null +++ b/src/bin/tetris/test.rs @@ -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> = vec![ + Ok((5, 6).into()), + Ok((4, 5).into()), + Ok((5, 5).into()), + Ok((6, 5).into()), + ]; + + let actual: Vec> = shape.coordinates(¢er).collect(); + + assert_eq!(actual, expected); +}