blob: 24a59be04d559da54ad2649d924d765b473a522dbe8139311b4be5a5c4f2ac4e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
/*
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_transparent: bool) {
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 transparent
let init_bit: bool = true;
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(brn.sample(&mut rng));
}
for _ in 0..(width - 1) {
col_bits.push(brn.sample(&mut rng));
}
// 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!();
}
}
|