From 1a406fc29e218a29dfe9ac0f8bdf580ff46829c8 Mon Sep 17 00:00:00 2001 From: David Harkness Date: Sun, 28 May 2023 18:04:36 -0700 Subject: [PATCH] Document more modules --- src/layout.rs | 4 +++- src/layout/cells.rs | 3 ++- src/layout/houses.rs | 6 ++++++ src/layout/knowns.rs | 2 ++ src/play.rs | 2 ++ src/printers.rs | 2 ++ src/puzzle.rs | 4 ++++ src/puzzle/board.rs | 50 +++++++++++++++++++++----------------------- src/solvers.rs | 2 ++ 9 files changed, 47 insertions(+), 28 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index 988ef02..67f8955 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -1,7 +1,9 @@ +//! Combines the various pieces that make up a Sudoku puzzle. + mod cells; mod houses; mod knowns; -pub use cells::{Bit, Bits, Cell, Rectangle, Set as CellSet}; +pub use cells::{Bits, Cell, Rectangle, Set as CellSet}; pub use houses::{Coord, House, Shape}; pub use knowns::{Known, Set as KnownSet}; diff --git a/src/layout/cells.rs b/src/layout/cells.rs index ae823ff..3918396 100644 --- a/src/layout/cells.rs +++ b/src/layout/cells.rs @@ -1,4 +1,5 @@ -///! Provides Cell and Set to track collections of cells and methods to manipulate them. +//! Provides [`Cell`] and [`Set`] to track collections of cells and methods to manipulate them. + mod bit; mod cell; mod label; diff --git a/src/layout/houses.rs b/src/layout/houses.rs index 54cd81d..c5884f7 100644 --- a/src/layout/houses.rs +++ b/src/layout/houses.rs @@ -1,3 +1,9 @@ +//! [`House`]s are the nine rows, columns and boxes (also called blocks) +//! that make up the [`Board`][crate::puzzle::Board]. +//! +//! Each [`House`] has a [`Shape`] and a unique [`Coord`]. +//! In a valid puzzle, each `House` must contain exactly one of each [`Known`][crate::layout::Known]. + mod coord; mod house; mod shape; diff --git a/src/layout/knowns.rs b/src/layout/knowns.rs index 7ad0439..e1a90b4 100644 --- a/src/layout/knowns.rs +++ b/src/layout/knowns.rs @@ -1,3 +1,5 @@ +//! Provides [`Known`] and [`Set`] to track collections of knowns and methods to manipulate them. + mod known; mod set; diff --git a/src/play.rs b/src/play.rs index 6f238da..405e867 100644 --- a/src/play.rs +++ b/src/play.rs @@ -1,3 +1,5 @@ +//! Provides a text-based interface for creating and playing Sudoku puzzles. + use std::io::{stdout, Write}; use crate::layout::{Cell, Known}; diff --git a/src/printers.rs b/src/printers.rs index 67878c2..c920945 100644 --- a/src/printers.rs +++ b/src/printers.rs @@ -1,3 +1,5 @@ +//! Provides functions for printing the state of a puzzle to the console. + use crate::layout::{House, Known}; use crate::puzzle::Board; diff --git a/src/puzzle.rs b/src/puzzle.rs index 9ebace6..b958c11 100644 --- a/src/puzzle.rs +++ b/src/puzzle.rs @@ -1,3 +1,7 @@ +//! Provides the [`Board`] for tracking the state of a puzzle, +//! the [`Action`]s that can be taken to solve it, +//! and any [`Error`]s that arise due to those actions. + mod action; mod board; mod effects; diff --git a/src/puzzle/board.rs b/src/puzzle/board.rs index 81971a1..e83be8c 100644 --- a/src/puzzle/board.rs +++ b/src/puzzle/board.rs @@ -8,13 +8,18 @@ use super::{Effects, Error, Strategy}; /// Tracks the full state of a puzzle in play. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct Board { + // Cells that were solved at the start. givens: CellSet, + // Solved cells. knowns: CellSet, + // Values for all cells. values: [u8; 81], - known_candidates: [KnownSet; 81], - cell_candidates: [CellSet; 9], - cell_knowns: [CellSet; 9], - valid: bool, + // Knowns that are still possible for each cell. + candidate_knowns: [KnownSet; 81], + // Cells that are still possible for each known. + candidate_cells: [CellSet; 9], + // Cells that have been solved for each known. + known_cells: [CellSet; 9], } impl Board { @@ -23,10 +28,9 @@ impl Board { givens: CellSet::empty(), knowns: CellSet::empty(), values: [Known::UNKNOWN; 81], - known_candidates: [KnownSet::full(); 81], - cell_candidates: [CellSet::full(); 9], - cell_knowns: [CellSet::empty(); 9], - valid: true, + candidate_knowns: [KnownSet::full(); 81], + candidate_cells: [CellSet::full(); 9], + known_cells: [CellSet::empty(); 9], } } @@ -54,10 +58,6 @@ impl Board { self.knowns.is_full() } - pub fn is_valid(&self) -> bool { - self.valid - } - pub fn all_candidates(&self, cells: CellSet) -> KnownSet { cells .iter() @@ -65,26 +65,25 @@ impl Board { } pub fn candidates(&self, cell: Cell) -> KnownSet { - self.known_candidates[cell.usize()] + self.candidate_knowns[cell.usize()] } pub fn is_candidate(&self, cell: Cell, known: Known) -> bool { - self.known_candidates[cell.usize()][known] + self.candidate_knowns[cell.usize()][known] } pub fn remove_candidate(&mut self, cell: Cell, known: Known, effects: &mut Effects) -> bool { - let knowns = &mut self.known_candidates[cell.usize()]; + let knowns = &mut self.candidate_knowns[cell.usize()]; if knowns[known] { // println!("remove candidate {} from {}", known, cell); *knowns -= known; if knowns.is_empty() { - self.valid = false; effects.add_error(Error::UnsolvableCell(cell)); } else if knowns.size() == 1 { effects.add_set(Strategy::NakedSingle, cell, knowns.iter().next().unwrap()); } - let cells = &mut self.cell_candidates[known.usize()]; + let cells = &mut self.candidate_cells[known.usize()]; debug_assert!(cells[cell]); *cells -= cell; self.remove_candidate_cell_from_houses(cell, known, effects); @@ -100,13 +99,12 @@ impl Board { known: Known, effects: &mut Effects, ) { - let all_candidates = self.cell_candidates[known.usize()]; + let all_candidates = self.candidate_cells[known.usize()]; for house in cell.houses() { let house_cells = house.cells(); - if (self.cell_knowns[known.usize()] & house_cells).is_empty() { + if (self.known_cells[known.usize()] & house_cells).is_empty() { let candidates = all_candidates & house_cells; if candidates.is_empty() { - self.valid = false; effects.add_error(Error::UnsolvableHouse(house, known)); } else if candidates.size() == 1 { effects.add_set( @@ -145,17 +143,17 @@ impl Board { self.values[cell.usize()] = known.value(); self.knowns += cell; - self.cell_knowns[known.usize()] += cell; - self.cell_candidates[known.usize()] -= cell; + self.known_cells[known.usize()] += cell; + self.candidate_cells[known.usize()] -= cell; - let candidates = self.known_candidates[cell.usize()] - known; - self.known_candidates[cell.usize()] = KnownSet::empty(); + let candidates = self.candidate_knowns[cell.usize()] - known; + self.candidate_knowns[cell.usize()] = KnownSet::empty(); for known in candidates.iter() { - self.cell_candidates[known.usize()] -= cell; + self.candidate_cells[known.usize()] -= cell; self.remove_candidate_cell_from_houses(cell, known, effects); } - for neighbor in (self.cell_candidates[known.usize()] & cell.neighbors()).iter() { + for neighbor in (self.candidate_cells[known.usize()] & cell.neighbors()).iter() { effects.add_erase(Strategy::Neighbor, neighbor, known); } diff --git a/src/solvers.rs b/src/solvers.rs index 65c5e47..0e49199 100644 --- a/src/solvers.rs +++ b/src/solvers.rs @@ -1,2 +1,4 @@ +//! Provides various strategies for solving Sudoku puzzles. + pub mod deadly_rectangles; pub mod intersection_removals;