/* 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 = match skew { Some(n) => { n } None => { 0.5 } }; let mut rng = rand::thread_rng(); let brn = Bernoulli::new(skew).unwrap(); // the first square (upper left corner) is always transparent let init_bit: bool = true; 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); print_square(above_bits[0]); for col in 1..width { /* 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. */ above_bits.push(above_bits[col - 1] ^ col_bits[col - 1]); print_square(above_bits[col]); } println!(); // height-1 because the first row has already been printed for row in 0..(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_bits[row]; print_square(*x1); }); println!(); } }