summaryrefslogtreecommitdiff
path: root/src/hitomezashi.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/hitomezashi.rs')
-rw-r--r--src/hitomezashi.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/hitomezashi.rs b/src/hitomezashi.rs
new file mode 100644
index 0000000..50d3d32
--- /dev/null
+++ b/src/hitomezashi.rs
@@ -0,0 +1,75 @@
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+use rand::Rng;
+
+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<f32>) {
+ let skew: f64 = match skew {
+ Some(n) => { n.into() }
+ None => { 0.5 }
+ };
+
+ let mut rng = rand::thread_rng();
+
+ let init_bit: bool = rng.gen::<bool>();
+ let mut row_bits: Vec<bool> = Vec::with_capacity(height - 1);
+ let mut col_bits: Vec<bool> = Vec::with_capacity(width - 1);
+
+ for _ in 0..(height - 1) {
+ row_bits.push(rng.gen_bool(skew));
+ }
+
+ for _ in 0..(width - 1) {
+ col_bits.push(rng.gen_bool(skew));
+ }
+
+ // each new row of the pattern depends on the bits directly above it
+ let mut above_bits: Vec<bool> = 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) {
+ for col in 0..width {
+ /* 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[col] = above_bits[col] ^ (row_bits[row] ^ (col % 2 == 1));
+ print_square(above_bits[col]);
+ }
+ println!();
+ }
+}