98 lines
2.8 KiB
Rust
98 lines
2.8 KiB
Rust
use std::collections::HashSet;
|
|||
|
|
|
||
|
|
#[derive(Clone, Debug, Copy, Hash, Eq, PartialEq)]
|
||
|
|
pub enum CellValue {
|
||
|
|
One,
|
||
|
|
Two,
|
||
|
|
Three,
|
||
|
|
Four,
|
||
|
|
Five,
|
||
|
|
Six,
|
||
|
|
Seven,
|
||
|
|
Eight,
|
||
|
|
Nine,
|
||
|
|
}
|
||
|
|
|
||
|
|
pub struct Cell {
|
||
|
|
value: Option<CellValue>,
|
||
|
|
candidates: HashSet<CellValue>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Cell {
|
||
|
|
pub fn value(&self) -> Option<CellValue> {
|
||
|
|
self.value
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn set_value(&mut self, value: CellValue) {
|
||
|
|
self.value = Some(value);
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn candidates(&self) -> HashSet<CellValue> {
|
||
|
|
self.candidates.clone()
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn remove_candidate(&mut self, value: CellValue) {
|
||
|
|
self.candidates.remove(&value);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Default for Cell {
|
||
|
|
fn default() -> Cell {
|
||
|
|
let mut candidates = HashSet::new();
|
||
|
|
candidates.insert(CellValue::One);
|
||
|
|
candidates.insert(CellValue::Two);
|
||
|
|
candidates.insert(CellValue::Three);
|
||
|
|
candidates.insert(CellValue::Four);
|
||
|
|
candidates.insert(CellValue::Five);
|
||
|
|
candidates.insert(CellValue::Six);
|
||
|
|
candidates.insert(CellValue::Seven);
|
||
|
|
candidates.insert(CellValue::Eight);
|
||
|
|
candidates.insert(CellValue::Nine);
|
||
|
|
Cell {
|
||
|
|
value: None,
|
||
|
|
candidates,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[cfg(test)]
|
||
|
|
mod test {
|
||
|
|
use super::*;
|
||
|
|
use assertables::{assert_contains, assert_not_contains};
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn inits_empty() {
|
||
|
|
let cell = Cell::default();
|
||
|
|
assert!(cell.value().is_none());
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn has_all_candidates() {
|
||
|
|
let cell = Cell::default();
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::One);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Two);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Three);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Four);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Five);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Six);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Seven);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Eight);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Nine);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn removed_candidate_is_gone() {
|
||
|
|
let mut cell = Cell::default();
|
||
|
|
cell.remove_candidate(CellValue::One);
|
||
|
|
assert_not_contains!(cell.candidates(), &CellValue::One);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Two);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Three);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Four);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Five);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Six);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Seven);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Eight);
|
||
|
|
assert_contains!(cell.candidates(), &CellValue::Nine);
|
||
|
|
}
|
||
|
|
}
|