//! 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!(); } }