summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hitomezashi.rs153
-rw-r--r--src/main.rs82
2 files changed, 121 insertions, 114 deletions
diff --git a/src/hitomezashi.rs b/src/hitomezashi.rs
index 7b74998..d8a8c42 100644
--- a/src/hitomezashi.rs
+++ b/src/hitomezashi.rs
@@ -1,19 +1,19 @@
/*
- hitomezashi-rs Generates classical colored Hitomezashi stitch patterns
- Copyright (C) 2024 Nicholas Johnson
+ 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 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.
+ 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/>.
+ 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};
@@ -22,68 +22,75 @@ const TRANSPARENT_SQUARE: char = ' ';
const OPAQUE_SQUARE: char = '█';
fn print_square(is_transparent: bool) {
- print!("{}", if is_transparent { TRANSPARENT_SQUARE } else { OPAQUE_SQUARE });
+ print!(
+ "{}",
+ if is_transparent {
+ TRANSPARENT_SQUARE
+ } else {
+ OPAQUE_SQUARE
+ }
+ );
}
pub fn hitomezashi(width: usize, height: usize, skew: Option<f64>) {
- 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 opaque
- let init_bit: bool = false;
-
- let mut row_bits: Vec<bool> = Vec::with_capacity(height - 1);
-
- for _ in 0..(height - 1) {
- row_bits.push(brn.sample(&mut rng));
- }
-
- let mut col_bits: Vec<bool> = Vec::with_capacity(width - 1);
-
- for _ in 0..(width - 1) {
- col_bits.push(brn.sample(&mut rng));
- }
-
- let mut alt_bits: Vec<bool> = 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<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) {
- /* 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!();
- }
+ 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 opaque
+ let init_bit: bool = false;
+
+ let mut row_bits: Vec<bool> = Vec::with_capacity(height - 1);
+
+ for _ in 0..(height - 1) {
+ row_bits.push(brn.sample(&mut rng));
+ }
+
+ let mut col_bits: Vec<bool> = Vec::with_capacity(width - 1);
+
+ for _ in 0..(width - 1) {
+ col_bits.push(brn.sample(&mut rng));
+ }
+
+ let mut alt_bits: Vec<bool> = 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<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) {
+ /* 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!();
+ }
}
diff --git a/src/main.rs b/src/main.rs
index 87274af..3732b50 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,22 +1,22 @@
/*
- hitomezashi-rs Generates classical colored Hitomezashi stitch patterns
- Copyright (C) 2024 Nicholas Johnson
+ 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 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.
+ 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/>.
+ 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 clap::{Parser, value_parser};
+use clap::{value_parser, Parser};
use colored::Colorize;
use std::process::exit;
@@ -25,54 +25,54 @@ mod hitomezashi;
#[derive(Parser)]
#[command(version, about, long_about = None)] // Read from `Cargo.toml`
struct Cli {
- /// Pattern width
- #[arg(value_parser = value_parser!(usize))]
- width: usize,
+ /// Pattern width
+ #[arg(value_parser = value_parser!(usize))]
+ width: usize,
- /// Pattern height
- #[arg(value_parser = value_parser!(usize))]
- height: usize,
+ /// Pattern height
+ #[arg(value_parser = value_parser!(usize))]
+ height: usize,
- #[arg(short, long)]
- #[arg(default_value_t = 0.5)]
- #[arg(value_parser = value_parser!(f64))]
- /// Set skew
- skew: f64,
+ #[arg(short, long)]
+ #[arg(default_value_t = 0.5)]
+ #[arg(value_parser = value_parser!(f64))]
+ /// Set skew
+ skew: f64,
}
/* CLI for hitomezashi */
fn main() {
- let cli = Cli::parse();
+ let cli = Cli::parse();
- // validate bounds of width [1..]
- if cli.width < 1 {
- println!("{} invalid value '{}' for '{}': valid values are [1..]\n\nFor more information, try '{}'.",
+ // validate bounds of width [1..]
+ if cli.width < 1 {
+ println!("{} invalid value '{}' for '{}': valid values are [1..]\n\nFor more information, try '{}'.",
"error:".red().bold(),
cli.width.to_string().yellow(),
"<WIDTH>".bold(),
"--help".bold());
- exit(2);
- }
+ exit(2);
+ }
- // validate bounds of height [1..]
- if cli.height < 1 {
- println!("{} invalid value '{}' for '{}': valid values are [1..]\n\nFor more information, try '{}'.",
+ // validate bounds of height [1..]
+ if cli.height < 1 {
+ println!("{} invalid value '{}' for '{}': valid values are [1..]\n\nFor more information, try '{}'.",
"error:".red().bold(),
cli.height.to_string().yellow(),
"<HEIGHT>".bold(),
"--help".bold());
- exit(2);
- }
+ exit(2);
+ }
- // validate bounds of skew [0-1]
- if cli.skew < 0.0 || cli.skew > 1.0 {
- println!("{} invalid value '{}' for '{}': valid values are [0-1]\n\nFor more information, try '{}'.",
+ // validate bounds of skew [0-1]
+ if cli.skew < 0.0 || cli.skew > 1.0 {
+ println!("{} invalid value '{}' for '{}': valid values are [0-1]\n\nFor more information, try '{}'.",
"error:".red().bold(),
cli.skew.to_string().yellow(),
"--skew <SKEW>".bold(),
"--help".bold());
- exit(2);
- }
+ exit(2);
+ }
- hitomezashi::hitomezashi(cli.width, cli.height, Some(cli.skew));
+ hitomezashi::hitomezashi(cli.width, cli.height, Some(cli.skew));
}