aboutsummaryrefslogtreecommitdiff
path: root/src/hitomezashi.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/hitomezashi.rs')
-rw-r--r--src/hitomezashi.rs102
1 files changed, 0 insertions, 102 deletions
diff --git a/src/hitomezashi.rs b/src/hitomezashi.rs
deleted file mode 100644
index 8e2a773..0000000
--- a/src/hitomezashi.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- 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::distributions::{Bernoulli, Distribution};
-
-const TRANSPARENT_SQUARE: char = ' ';
-const OPAQUE_SQUARE: char = '█';
-
-fn print_square(is_opaque: bool) {
- print!(
- "{}",
- if is_opaque {
- OPAQUE_SQUARE
- } else {
- TRANSPARENT_SQUARE
- }
- );
-}
-
-pub fn hitomezashi(width: usize, height: usize, skew: Option<f64>) {
- // skew=0.5 generates the most random-looking patterns
- let skew: f64 = skew.unwrap_or(0.5);
-
- assert!(width >= 1, "Width must be a positive number!");
- assert!(height >= 1, "Height must be a positive number!");
- assert!(skew >= 0.0 && skew <= 1.0, "Skew must be between zero and one inclusive!");
-
- let mut rng = rand::thread_rng();
- let brn = Bernoulli::new(skew).unwrap();
-
- // Each value represents whether to start that row with a stitch or no stitch
- let mut row_bits: Vec<bool> = Vec::with_capacity(height - 1);
-
- for _ in 0..row_bits.capacity() {
- row_bits.push(brn.sample(&mut rng));
- }
-
- // Each value represents whether to start that column with a stitch or no stitch
- let mut col_bits: Vec<bool> = Vec::with_capacity(width - 1);
-
- for _ in 0..col_bits.capacity() {
- col_bits.push(brn.sample(&mut rng));
- }
-
- // Precomputed values to facilitate alternating between stitch presence and stitch absence
- let mut alt_bits: Vec<bool> = Vec::with_capacity(width);
-
- let mut alternator: bool = false;
- for _ in 0..alt_bits.capacity() {
- alt_bits.push(alternator);
- alternator = !alternator;
- }
-
- /* The first square is always opaque to prevent invisible 1xN or Nx1 patterns. Invisible
- * patterns must be prevented so that users don't mistakenly conclude that the function does
- * not work. */
- let first_square: bool = true;
-
- let mut cur_row: Vec<bool> = Vec::with_capacity(width);
-
- /* Base case
- *
- * The first row has no preceding row, so it's computing using the column stitches */
- cur_row.push(first_square);
- for col in 0..(cur_row.capacity() - 1) {
- print_square(cur_row[col]);
- cur_row.push(cur_row[col] ^ col_bits[col]);
- }
-
- print_square(cur_row[cur_row.capacity() - 1]);
- println!(); // End of base case
-
- for row_bit in row_bits.iter() {
- /* Recursive case
- *
- * Each row after the first row is computed based on the preceding row. */
- cur_row
- .iter_mut()
- .zip(alt_bits.iter())
- .for_each(|(x1, &x2)| {
- *x1 ^= x2 ^ row_bit;
- print_square(*x1);
- });
-
- println!(); // End of recursive case
- }
-}