Add card merge impl
This commit is contained in:
68
src/card.rs
68
src/card.rs
@@ -1,5 +1,7 @@
|
||||
//! TODO: module doc :v
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
/// Value for the "sub tiles" inside a room tile
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
enum Cell {
|
||||
@@ -50,11 +52,11 @@ enum RotationDir {
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
struct Card {
|
||||
cells: [Cell; 9],
|
||||
e: bool,
|
||||
ne: bool,
|
||||
n: bool,
|
||||
nw: bool,
|
||||
n: bool,
|
||||
ne: bool,
|
||||
w: bool,
|
||||
e: bool,
|
||||
sw: bool,
|
||||
s: bool,
|
||||
se: bool,
|
||||
@@ -63,7 +65,53 @@ struct Card {
|
||||
impl Card {
|
||||
/// Produces a new card by stacking another on top of this one.
|
||||
pub fn merge(self, top: Self) -> (Self, Option<Self>) {
|
||||
todo!();
|
||||
let mut new_card = Self::default();
|
||||
let mut doors: Option<Self> = None;
|
||||
|
||||
new_card.cells = std::iter::zip(&self.cells, &top.cells)
|
||||
.map(|(lower, upper)| {
|
||||
if (lower == &Cell::Filled || upper == &Cell::Filled)
|
||||
|| (lower == &Cell::SW && upper == &Cell::NE)
|
||||
|| (lower == &Cell::SE && upper == &Cell::NW)
|
||||
|| (lower == &Cell::NE && upper == &Cell::SW)
|
||||
|| (lower == &Cell::NW && upper == &Cell::SE)
|
||||
{
|
||||
Cell::Filled
|
||||
} else if upper != &Cell::Empty {
|
||||
*upper
|
||||
} else {
|
||||
*lower
|
||||
}
|
||||
})
|
||||
.collect::<Vec<Cell>>()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
// Check for doors
|
||||
macro_rules! check_door {
|
||||
( $dir:ident, $index:literal ) => {
|
||||
if self.$dir {
|
||||
if top.cells[$index] == Cell::Empty || top.$dir {
|
||||
new_card.$dir = true;
|
||||
} else {
|
||||
doors.get_or_insert_default().$dir = true;
|
||||
}
|
||||
} else if top.$dir && new_card.cells[$index] != Cell::Empty {
|
||||
new_card.$dir = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
check_door!(nw, 0);
|
||||
check_door!(n, 1);
|
||||
check_door!(ne, 2);
|
||||
check_door!(w, 3);
|
||||
check_door!(e, 5);
|
||||
check_door!(sw, 6);
|
||||
check_door!(s, 7);
|
||||
check_door!(se, 8);
|
||||
|
||||
(new_card, doors)
|
||||
}
|
||||
|
||||
/// Cuts this Card on the given line. Returns two cards
|
||||
@@ -124,9 +172,15 @@ mod test {
|
||||
// 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,
|
||||
Cell::NW,
|
||||
Cell::Filled,
|
||||
Cell::NE,
|
||||
Cell::Filled,
|
||||
Cell::Filled,
|
||||
Cell::Filled,
|
||||
Cell::SW,
|
||||
Cell::Filled,
|
||||
Cell::Filled,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user