-
Notifications
You must be signed in to change notification settings - Fork 9
/
mask_pattern.rs
62 lines (52 loc) · 2.22 KB
/
mask_pattern.rs
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
use std::cmp::min;
use cubing::kpuzzle::{KPattern, OrientationWithMod};
use crate::scramble::PuzzleError;
pub(crate) fn apply_mask(
source_pattern: &KPattern,
mask_pattern: &KPattern,
) -> Result<KPattern, PuzzleError> {
let mut masked_pattern = mask_pattern.clone();
for orbit_info in source_pattern.kpuzzle().orbit_info_iter() {
for i in 0..orbit_info.num_pieces {
let old_piece = source_pattern.get_piece(orbit_info, i);
let old_piece_mapped = mask_pattern.get_piece(orbit_info, old_piece);
masked_pattern.set_piece(orbit_info, i, old_piece_mapped);
let source_orientation_with_mod =
source_pattern.get_orientation_with_mod(orbit_info, i);
let mask_orientation_with_mod = mask_pattern.get_orientation_with_mod(orbit_info, i);
if mask_orientation_with_mod.orientation != 0 {
return Err(PuzzleError {
description: "Masks cannot currently have piece orientation".to_owned(),
});
};
let source_mod = source_orientation_with_mod.orientation_mod;
let source_mod = if source_mod == 0 {
orbit_info.num_orientations
} else {
source_mod
};
let mask_mod = mask_orientation_with_mod.orientation_mod;
let mask_mod = if mask_mod == 0 {
orbit_info.num_orientations
} else {
mask_mod
};
if source_mod % mask_mod != 0 && mask_mod % source_mod != 0 {
return Err(PuzzleError {
description: "Incompatible orientation mod in mask".to_owned(),
});
};
let masked_mod = min(source_mod, mask_mod);
let orientation_with_mod = OrientationWithMod {
orientation: source_orientation_with_mod.orientation % masked_mod,
orientation_mod: if masked_mod == orbit_info.num_orientations {
0
} else {
masked_mod
},
};
masked_pattern.set_orientation_with_mod(orbit_info, i, &orientation_with_mod);
}
}
Ok(masked_pattern)
}