solver state and module glue
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
pub mod candidate;
|
||||
pub mod csp;
|
||||
pub mod state;
|
||||
|
||||
pub use csp::{SolveResult, solve};
|
||||
@@ -0,0 +1,78 @@
|
||||
use crate::dict::index::WordIndex;
|
||||
use crate::grid::slot::Slot;
|
||||
|
||||
pub struct SolverState {
|
||||
pub assignments: Vec<Option<usize>>,
|
||||
pub used_words: Vec<bool>,
|
||||
pub grid_letters: Vec<Vec<Option<u8>>>,
|
||||
pub cell_domains: Vec<Vec<u32>>,
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
}
|
||||
|
||||
impl SolverState {
|
||||
pub fn new(slots: &[Slot], width: usize, height: usize, dict_size: usize) -> Self {
|
||||
let all_bits = (1u32 << 26) - 1;
|
||||
Self {
|
||||
assignments: vec![None; slots.len()],
|
||||
used_words: vec![false; dict_size],
|
||||
grid_letters: vec![vec![None; width]; height],
|
||||
cell_domains: vec![vec![all_bits; width]; height],
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_domains(&mut self, slots: &[Slot], dict: &WordIndex) {
|
||||
for slot in slots {
|
||||
for (pos, &(r, c)) in slot.cells().iter().enumerate() {
|
||||
let allowed = dict.allowed_letters(slot.length, pos);
|
||||
if allowed != 0 {
|
||||
self.cell_domains[r][c] &= allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_domain(&self, r: usize, c: usize) -> u32 {
|
||||
self.cell_domains[r][c]
|
||||
}
|
||||
|
||||
pub fn set_domain(&mut self, r: usize, c: usize, domain: u32) {
|
||||
self.cell_domains[r][c] = domain;
|
||||
}
|
||||
|
||||
pub fn get_letter(&self, row: usize, col: usize) -> Option<u8> {
|
||||
self.grid_letters[row][col]
|
||||
}
|
||||
|
||||
pub fn set_letter(&mut self, row: usize, col: usize, letter: u8) {
|
||||
self.grid_letters[row][col] = Some(letter);
|
||||
}
|
||||
|
||||
pub fn clear_letter(&mut self, row: usize, col: usize) {
|
||||
self.grid_letters[row][col] = None;
|
||||
}
|
||||
|
||||
pub fn mark_used(&mut self, word_idx: usize) {
|
||||
self.used_words[word_idx] = true;
|
||||
}
|
||||
|
||||
pub fn unmark_used(&mut self, word_idx: usize) {
|
||||
self.used_words[word_idx] = false;
|
||||
}
|
||||
|
||||
pub fn is_used(&self, word_idx: usize) -> bool {
|
||||
self.used_words[word_idx]
|
||||
}
|
||||
|
||||
pub fn current_constraints(&self, slot: &Slot) -> Vec<(usize, u8)> {
|
||||
let mut constraints = Vec::new();
|
||||
for (pos, (r, c)) in slot.cells().iter().enumerate() {
|
||||
if let Some(letter) = self.get_letter(*r, *c) {
|
||||
constraints.push((pos, letter));
|
||||
}
|
||||
}
|
||||
constraints
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user