basic puzzle

This commit is contained in:
WanderingPenwing 2024-12-06 14:48:27 +01:00
parent 4be954b9d0
commit 684ab1565f
3 changed files with 34 additions and 21 deletions

View file

@ -35,7 +35,7 @@ struct Args {
/// Create puzzle /// Create puzzle
#[arg(long)] #[arg(long)]
puzzle: bool, puzzle: Option<usize>,
} }
@ -58,8 +58,8 @@ fn main() {
return return
} }
let result = if args.puzzle { let result = if let Some(difficulty) = args.puzzle {
solver.make_puzzle().map(|_| ()) solver.make_puzzle(difficulty).map(|_| ())
} else { } else {
solver.solve(args.limit).map(|_| ()) solver.solve(args.limit).map(|_| ())
}; };

View file

@ -139,30 +139,35 @@ impl Solver {
} }
} }
pub fn make_puzzle(&mut self) -> Result<(), WaveError> { pub fn make_puzzle(&mut self, difficulty: usize) -> Result<(), WaveError> {
self.solve_display = false; self.solve_display = false;
println!("# generating full..."); println!("\n# generating full...");
let _ = self.solve(None)?; let _ = self.solve(None)?;
println!("\n\n# erasing cells..."); println!("\n\n# erasing cells...");
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let erase_cell = loop {
let pos = (rng.gen_range(1..=self.size), rng.gen_range(1..=self.size));
if let Some(state) = self.grid[pos.0][pos.1].get_state() {
self.grid[pos.0][pos.1].reset_state();
break (pos, state);
}
};
let blocking_cell = cell::BlockingCell { let mut min_num_allowed = 1;
state: erase_cell.1,
position: erase_cell.0,
};
self.propagate_backtrack(erase_cell.0, blocking_cell); // get min allowed state number
// while min state number < 2 => loop
while min_num_allowed <= difficulty {
let erase_cell = loop {
let pos = (rng.gen_range(0..self.size), rng.gen_range(0..self.size));
if let Some(state) = self.grid[pos.0][pos.1].get_state() {
self.grid[pos.0][pos.1].reset_state();
break (pos, state);
}
};
let blocking_cell = cell::BlockingCell {
state: erase_cell.1,
position: erase_cell.0,
};
min_num_allowed = self.propagate_backtrack(erase_cell.0, blocking_cell);
if min_num_allowed > difficulty {
let _ = self.grid[erase_cell.0.0][erase_cell.0.1].collapse(&cell::CollapseOption::Set(erase_cell.1));
//println!("put back ({},{}) to {}", erase_cell.0.0, erase_cell.0.1, erase_cell.1);
//self.propagate_collapse(erase_cell.0, blocking_cell);
}
}
println!(); println!();
self.display(ui::DisplayMode::Full); self.display(ui::DisplayMode::Full);

View file

@ -74,7 +74,9 @@ impl Solver {
Ok(()) Ok(())
} }
pub fn propagate_backtrack(&mut self, cell_pos: (usize, usize), removed_cell: cell::BlockingCell) { pub fn propagate_backtrack(&mut self, cell_pos: (usize, usize), removed_cell: cell::BlockingCell) -> usize {
let mut min_allowed_number = self.size;
for index in 0..self.size { for index in 0..self.size {
if index != cell_pos.0 { if index != cell_pos.0 {
self.grid[index][cell_pos.1].add_allowed(&removed_cell); self.grid[index][cell_pos.1].add_allowed(&removed_cell);
@ -87,6 +89,12 @@ impl Solver {
if square_row != cell_pos.0 || square_column != cell_pos.1 { if square_row != cell_pos.0 || square_column != cell_pos.1 {
self.grid[square_row][square_column].add_allowed(&removed_cell); self.grid[square_row][square_column].add_allowed(&removed_cell);
} }
let num_allowed = self.grid[square_row][square_column].get_num_allowed();
if num_allowed < min_allowed_number {
min_allowed_number = num_allowed
}
} }
min_allowed_number
} }
} }