You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.3 KiB

use std::collections::HashSet;
#[derive(Clone)]
pub struct Playground {
arr: [[u8; 9]; 9]
}
impl Playground {
pub fn new() -> Playground {
return Playground { arr: [[0; 9]; 9] };
}
pub fn from_array(arr: &[u8;81]) -> Playground {
let mut p = Playground::new();
for y in 0..9 {
for x in 0..9 {
p.arr[y][x] = arr[y*9+x];
}
}
p
}
pub fn print(&self) {
println!("┌───────┬───────┬───────┐");
for y in 0..9 {
if y != 0 && y%3 == 0 {
println!("├───────┼───────┼───────┤");
}
print!("|");
for x in 0..9 {
if let Some(value) = self.get_value(x, y) {
print!(" {}", value);
} else {
print!(" ");
}
if (x + 1) % 3 == 0 {
print!(" |");
}
}
println!();
}
println!("└───────┴───────┴───────┘");
}
pub fn get_value(&self, x: usize, y: usize) -> Option<u8> {
match self.arr[y][x] {
1..=9 => Some(self.arr[y][x]),
_ => None
}
}
pub fn set_value(&mut self, x: usize, y: usize, value : u8) {
self.arr[y][x] = value;
}
pub fn is_solved(&self) -> bool {
return self.arr.iter()
.flat_map(|row| row.iter())
.all(|value| *value != 0u8);
}
/** Checks if the playground has failures (not neccesary solved) */
pub fn is_valid(&self) -> bool {
self.rows_valid() && self.columns_valid() && self.sections_valid()
}
fn rows_valid(&self) -> bool {
let mut rows_set : HashSet<u8> = HashSet::with_capacity(9);
for x in 0..9 {
rows_set.clear();
for y in 0..9 {
if !rows_set.insert(self.arr[y][x]) {
return false
}
}
}
true
}
fn columns_valid(&self) -> bool {
let mut cols_set : HashSet<u8> = HashSet::with_capacity(9);
for y in 0..9 {
cols_set.clear();
for x in 0..9 {
if !cols_set.insert(self.arr[y][x]) {
return false
}
}
}
true
}
fn sections_valid(&self) -> bool {
let mut sects_set : HashSet<u8> = HashSet::with_capacity(9);
for s in 0..9 {
sects_set.clear();
let ref_point = ((s * 3) % 9, s / 3 * 3);
for i in 0..9 {
let (ref_x,ref_y) = ref_point;
if !sects_set.insert(self.arr[ref_y + (i/3)][ref_x + (i%3)]) {
return false
}
}
}
true
}
pub fn contains(&self, other : &Playground) -> bool {
for x in 0..9 {
for y in 0..9 {
if other.arr[y][x] != 0 && self.arr[y][x] != other.arr[y][x] {
return false;
}
}
}
true
}
}