/*
hitomezashi-rs Generates classical colored Hitomezashi stitch patterns
Copyright (C) 2024 Nicholas Johnson
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
use rand::distributions::{Bernoulli, Distribution};
const TRANSPARENT_SQUARE: char = ' ';
const OPAQUE_SQUARE: char = '█';
fn print_square(is_transparent: bool) {
print!(
"{}",
if is_transparent {
TRANSPARENT_SQUARE
} else {
OPAQUE_SQUARE
}
);
}
pub fn hitomezashi(width: usize, height: usize, skew: Option) {
let skew: f64 = skew.unwrap_or(0.5);
let mut rng = rand::thread_rng();
let brn = Bernoulli::new(skew).unwrap();
// the first square (upper left corner) is always opaque
let init_bit: bool = false;
let mut row_bits: Vec = Vec::with_capacity(height - 1);
for _ in 0..(height - 1) {
row_bits.push(brn.sample(&mut rng));
}
let mut col_bits: Vec = Vec::with_capacity(width - 1);
for _ in 0..(width - 1) {
col_bits.push(brn.sample(&mut rng));
}
let mut alt_bits: Vec = Vec::with_capacity(width - 1);
for col in 0..width {
alt_bits.push(col % 2 == 1);
}
// each new row of the pattern depends on the bits directly above it
let mut above_bits: Vec = Vec::with_capacity(width);
above_bits.push(init_bit);
for col in 0..(width - 1) {
/* each square in the first row is derived from the square to its left. the column bits
* represent whether there's a stitch between the two squares. if there's a stitch, the squares
* are different, otherwise they are the same. */
print_square(above_bits[col]);
above_bits.push(above_bits[col] ^ col_bits[col]);
}
print_square(above_bits[width - 1]);
println!();
// height-1 because the first row has already been printed
for row_bit in row_bits.iter().take(height - 1) {
/* each square in each successive row is derived from the square above it. the row bits
* represent whether there's a stitch between the two squares. if there's a stitch, the
* squares are different, otherwise they are the same. */
above_bits
.iter_mut()
.zip(alt_bits.iter())
.for_each(|(x1, &x2)| {
*x1 ^= x2 ^ row_bit;
print_square(*x1);
});
println!();
}
}