diff --git a/src/card.rs b/src/card.rs new file mode 100644 index 0000000..e91f728 --- /dev/null +++ b/src/card.rs @@ -0,0 +1,157 @@ +//! TODO: module doc :v + +/// Value for the "sub tiles" inside a room tile +#[derive(Clone, Copy, Debug, Default, PartialEq)] +enum Cell { + #[default] + Empty, + NW, + NE, + SE, + SW, + Filled, +} + +#[derive(Clone, Copy, Debug)] +enum CutLine { + VertLeft, + VertRight, + HorizUpper, + HorizLower, +} + +#[derive(Clone, Copy, Debug)] +enum FlipDir { + Vertical, + Horizontal, +} + +#[derive(Clone, Copy, Debug)] +enum TransposeIndex { + First, + Second, + Third, +} + +#[derive(Clone, Copy, Debug)] +enum TransposeSelection { + Column(TransposeIndex), + Row(TransposeIndex), +} + +#[derive(Clone, Copy, Debug)] +enum RotationDir { + Clockwise, + CounterClockwise, +} + +/// An invidiual room, or "card" in the player's hand. The room may +/// *or may not* be valid, yet. +#[derive(Clone, Copy, Debug, Default, PartialEq)] +struct Card { + cells: [Cell; 9], + e: bool, + ne: bool, + n: bool, + nw: bool, + w: bool, + sw: bool, + s: bool, + se: bool, +} + +impl Card { + /// Produces a new card by stacking another on top of this one. + pub fn merge(self, top: Self) -> (Self, Option) { + todo!(); + } + + /// Cuts this Card on the given line. Returns two cards + pub fn cut(&self, line: CutLine) -> (Self, Self) { + todo!(); + } + + pub fn flip(&self, flip: FlipDir) -> (Self) { + todo!(); + } + + pub fn transpose(&self, other: &Self, selection: TransposeSelection) -> (Self, Self) { + todo!(); + } + + pub fn rotate(&self, dir: RotationDir) { + todo!(); + } +} + +#[rustfmt::skip] +pub const FULL_SQUARE: [Cell; 9] = [ + Cell::Filled, Cell::Filled, Cell::Filled, + Cell::Filled, Cell::Filled, Cell::Filled, + Cell::Filled, Cell::Filled, Cell::Filled, +]; + +#[rustfmt::skip] +pub const NW_TRIANGLE: [Cell; 9] = [ + Cell::Empty, Cell::Empty, Cell::NW, + Cell::Empty, Cell::NW, Cell::Filled, + Cell::NW, Cell::Filled, Cell::Filled, +]; + +#[rustfmt::skip] +pub const OCTAGON: [Cell; 9] = [ + Cell::NW, Cell::Filled, Cell::NE, + Cell::Filled, Cell::Filled, Cell::Filled, + Cell::SW, Cell::Filled, Cell::SE, +]; + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn check_merge() { + let bottom = Card { + cells: NW_TRIANGLE, + ..Default::default() // no doors + }; + + let top = Card { + cells: OCTAGON, + ..Default::default() + }; + + // For now, triangular cells from the top-most Card survive the merge. + let expected = Card { + cells: [ + Cell::NW, Cell::Filled, Cell::NE, + Cell::Filled, Cell::Filled, Cell::Filled, + Cell::SW, Cell::Filled, Cell::Filled, + ], + ..Default::default() + }; + + // Run the test + let (stacked, extra_doors) = bottom.merge(top); + assert_eq!(stacked, expected); + assert!(extra_doors.is_none()); + } + + /// Merging two corner cells together results in the upper cell coming through. + #[test] + fn merge_triangle_and_triangle() { + todo!(); + } + + /// Merging a filled cell with anything should result in [`Cell::Filled`]. + #[test] + fn merge_triangle_and_filled() { + todo!(); + } + + /// Merging a NW and SE cell should result in a single [`Cell::Filled`]. + #[test] + fn merge_opposite_triangles() { + todo!(); + } +} diff --git a/src/main.rs b/src/main.rs index 826132f..c3ac2fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ use bevy::{prelude::*, window::WindowResolution}; use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin}; +mod card; + fn main() { App::new() .add_plugins(DefaultPlugins.set(WindowPlugin {