Initial implementations of all card ops

This commit is contained in:
Patrick Gelvin
2025-08-23 10:03:38 -07:00
parent e7f4a00f2a
commit e59b65e034

View File

@@ -114,19 +114,177 @@ impl Card {
/// Cuts this Card on the given line. Returns two cards
pub fn cut(self, line: CutLine) -> (Self, Self) {
todo!();
let is_cut: fn(usize, usize) -> bool = match line {
CutLine::VertLeft => |x, _| x > 0,
CutLine::VertRight => |x, _| x > 1,
CutLine::HorizUpper => |_, y| y > 0,
CutLine::HorizLower => |_, y| y > 1,
};
let mut first_card = Self::default();
let mut second_card = Self::default();
macro_rules! perform_cut {
( $dir:ident, $index:literal ) => {
if is_cut($index % 3, $index / 3) {
second_card.cells[$index] = self.cells[$index];
second_card.$dir = self.$dir;
} else {
first_card.cells[$index] = self.cells[$index];
first_card.$dir = self.$dir;
}
};
( $index:literal ) => {
if is_cut($index % 3, $index / 3) {
second_card.cells[$index] = self.cells[$index];
} else {
first_card.cells[$index] = self.cells[$index];
}
};
}
perform_cut!(nw, 0);
perform_cut!(n, 1);
perform_cut!(ne, 2);
perform_cut!(w, 3);
perform_cut!(4);
perform_cut!(e, 5);
perform_cut!(sw, 6);
perform_cut!(s, 7);
perform_cut!(se, 8);
(first_card, second_card)
}
pub fn flip(self, flip: FlipDir) -> Self {
todo!();
let mut new_card = Self::default();
// Check for doors
macro_rules! assign_cell {
( ($source_dir:ident, $source_index:literal), ($dest_dir:ident, $dest_index:literal), $repeat:expr ) => {
new_card.cells[$dest_index] = self.cells[$source_index];
new_card.$dest_dir = self.$source_dir;
if $repeat == true {
new_card.cells[$source_index] = self.cells[$dest_index];
new_card.$source_dir = self.$dest_dir;
}
};
}
match flip {
FlipDir::Horizontal => {
assign_cell!((nw, 0), (ne, 2), true);
assign_cell!((w, 3), (e, 5), true);
assign_cell!((sw, 6), (se, 8), true);
assign_cell!((n, 1), (n, 1), false);
assign_cell!((s, 7), (s, 7), false);
}
FlipDir::Vertical => {
assign_cell!((nw, 0), (sw, 6), true);
assign_cell!((n, 1), (s, 7), true);
assign_cell!((ne, 2), (se, 8), true);
assign_cell!((w, 3), (w, 3), false);
assign_cell!((e, 5), (e, 5), false);
}
}
new_card.cells[4] = self.cells[4];
new_card
}
pub fn transpose(self, other: Self, selection: TransposeSelection) -> (Self, Self) {
todo!();
let is_transposed: fn(usize, usize) -> bool = match selection {
TransposeSelection::Column(TransposeIndex::First) => |x, _| x == 0,
TransposeSelection::Column(TransposeIndex::Second) => |x, _| x == 1,
TransposeSelection::Column(TransposeIndex::Third) => |x, _| x == 2,
TransposeSelection::Row(TransposeIndex::First) => |_, y| y == 0,
TransposeSelection::Row(TransposeIndex::Second) => |_, y| y == 1,
TransposeSelection::Row(TransposeIndex::Third) => |_, y| y == 2,
};
let mut first_card = Self::default();
let mut second_card = Self::default();
macro_rules! perform_transpose {
( $dir:ident, $index:literal ) => {
if is_transposed($index % 3, $index / 3) {
first_card.cells[$index] = other.cells[$index];
second_card.cells[$index] = self.cells[$index];
first_card.$dir = other.$dir;
second_card.$dir = self.$dir;
} else {
first_card.cells[$index] = self.cells[$index];
second_card.cells[$index] = other.cells[$index];
first_card.$dir = self.$dir;
second_card.$dir = other.$dir;
}
};
( $index:literal ) => {
if is_transposed($index % 3, $index / 3) {
first_card.cells[$index] = other.cells[$index];
second_card.cells[$index] = self.cells[$index];
} else {
first_card.cells[$index] = self.cells[$index];
second_card.cells[$index] = other.cells[$index];
}
};
}
pub fn rotate(self, dir: RotationDir) {
todo!();
perform_transpose!(nw, 0);
perform_transpose!(n, 1);
perform_transpose!(ne, 2);
perform_transpose!(w, 3);
perform_transpose!(4);
perform_transpose!(e, 5);
perform_transpose!(sw, 6);
perform_transpose!(s, 7);
perform_transpose!(se, 8);
(first_card, second_card)
}
pub fn rotate(self, dir: RotationDir) -> Self {
let mut new_card = Self::default();
// Check for doors
macro_rules! assign_cell {
( ($source_dir:ident, $source_index:literal), ($dest_dir:ident, $dest_index:literal) ) => {
new_card.cells[$dest_index] = self.cells[$source_index];
new_card.$dest_dir = self.$source_dir;
};
}
match dir {
RotationDir::Clockwise => {
assign_cell!((nw, 0), (n, 1));
assign_cell!((n, 1), (ne, 2));
assign_cell!((ne, 2), (e, 5));
assign_cell!((e, 5), (se, 8));
assign_cell!((se, 8), (s, 7));
assign_cell!((s, 7), (sw, 6));
assign_cell!((sw, 6), (w, 3));
assign_cell!((w, 3), (nw, 0));
}
RotationDir::CounterClockwise => {
assign_cell!((nw, 0), (w, 3));
assign_cell!((w, 3), (sw, 6));
assign_cell!((sw, 6), (s, 7));
assign_cell!((s, 7), (se, 8));
assign_cell!((se, 8), (e, 5));
assign_cell!((e, 5), (ne, 2));
assign_cell!((ne, 2), (n, 1));
assign_cell!((n, 1), (nw, 0));
}
}
new_card.cells[4] = self.cells[4];
new_card
}
}