use crate::*;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) enum DrainPlan {
Straight,
BounceTogether,
BounceEach,
}
impl DrainPlan {
pub(crate) fn new(scratch: Scratch, bounces: bool) -> Self {
match (scratch, bounces) {
(Scratch::None, _) | (_, false) => DrainPlan::Straight,
(Scratch::OneTile, true) => DrainPlan::BounceEach,
(Scratch::WholeGrid, true) => DrainPlan::BounceTogether,
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) enum DrainPass {
Copy,
Bounce,
Spill,
Add,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) enum Drain {
EachUnit,
UnitZero,
PlaneReduce,
GroupReduce { unit_bits: usize },
}
impl Drain {
pub(crate) const fn of(units: UnitShare, write: Write) -> Self {
match (units, write) {
(UnitShare::Plane, _) => Drain::PlaneReduce,
(UnitShare::Group { unit_bits }, _) => Drain::GroupReduce { unit_bits },
(UnitShare::Repeated, Write::Accumulate | Write::Exclusive(_)) => Drain::UnitZero,
(UnitShare::Repeated, Write::Replace) | (UnitShare::Whole, _) => Drain::EachUnit,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_destination_stored_whole_takes_any_grid_straight() {
for scratch in [Scratch::None, Scratch::OneTile, Scratch::WholeGrid] {
assert_eq!(DrainPlan::new(scratch, false), DrainPlan::Straight);
}
}
#[test]
fn a_bouncing_destination_takes_the_grid_through_its_scratch() {
assert_eq!(
DrainPlan::new(Scratch::OneTile, true),
DrainPlan::BounceEach
);
assert_eq!(
DrainPlan::new(Scratch::WholeGrid, true),
DrainPlan::BounceTogether
);
}
}