1use std::collections::BTreeSet;
2use std::ops::{Add, Sub};
3use strum_macros::{EnumIter, EnumString};
4
5#[repr(usize)]
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
7pub enum Colour {
8 Black = 0,
9 Blue = 1,
10 Red = 2,
11 Green = 3,
12 Yellow = 4,
13 Grey = 5,
14 Fuchsia = 6,
15 Orange = 7,
16 Teal = 8,
17 Brown = 9,
18 ToBlack = 10,
19 ToBlue = 11,
20 ToRed = 12,
21 ToGreen = 13,
22 ToYellow = 14,
23 ToGrey = 15,
24 ToFuchsia = 16,
25 ToOrange = 17,
26 ToTeal = 18,
27 ToBrown = 19,
28 FromBlack = 20,
29 FromBlue = 21,
30 FromRed = 22,
31 FromGreen = 23,
32 FromYellow = 24,
33 FromGrey = 25,
34 FromFuchsia = 26,
35 FromOrange = 27,
36 FromTeal = 28,
37 FromBrown = 29,
38 SameBlack = 30,
39 SameBlue = 31,
40 SameRed = 32,
41 SameGreen = 33,
42 SameYellow = 34,
43 SameGrey = 35,
44 SameFuchsia = 36,
45 SameOrange = 37,
46 SameTeal = 38,
47 SameBrown = 39,
48 DiffBlack = 40,
49 DiffBlue = 41,
50 DiffRed = 42,
51 DiffGreen = 43,
52 DiffYellow = 44,
53 DiffGrey = 45,
54 DiffFuchsia = 46,
55 DiffOrange = 47,
56 DiffTeal = 48,
57 DiffBrown = 49,
58 OrigBlack = 50,
59 OrigBlue = 51,
60 OrigRed = 52,
61 OrigGreen = 53,
62 OrigYellow = 54,
63 OrigGrey = 55,
64 OrigFuchsia = 56,
65 OrigOrange = 57,
66 OrigTeal = 58,
67 OrigBrown = 59,
68 NoColour = 90,
69 Mixed = 91,
70 Transparent = 92, DiffShape = 93, Same = 94, }
74
75impl Colour {
76 pub fn new(colour: usize) -> Self {
77 Colour::from_usize(colour)
78 }
79
80 pub fn from_usize(colour: usize) -> Self {
81 match colour {
82 0 => Self::Black,
83 1 => Self::Blue,
84 2 => Self::Red,
85 3 => Self::Green,
86 4 => Self::Yellow,
87 5 => Self::Grey,
88 6 => Self::Fuchsia,
89 7 => Self::Orange,
90 8 => Self::Teal,
91 9 => Self::Brown,
92 10 => Self::ToBlack,
93 11 => Self::ToBlue,
94 12 => Self::ToRed,
95 13 => Self::ToGreen,
96 14 => Self::ToYellow,
97 15 => Self::ToGrey,
98 16 => Self::ToFuchsia,
99 17 => Self::ToOrange,
100 18 => Self::ToTeal,
101 19 => Self::ToBrown,
102 20 => Self::FromBlack,
103 21 => Self::FromBlue,
104 22 => Self::FromRed,
105 23 => Self::FromGreen,
106 24 => Self::FromYellow,
107 25 => Self::FromGrey,
108 26 => Self::FromFuchsia,
109 27 => Self::FromOrange,
110 28 => Self::FromTeal,
111 29 => Self::FromBrown,
112 30 => Self::SameBlack,
113 31 => Self::SameBlue,
114 32 => Self::SameRed,
115 33 => Self::SameGreen,
116 34 => Self::SameYellow,
117 35 => Self::SameGrey,
118 36 => Self::SameFuchsia,
119 37 => Self::SameOrange,
120 38 => Self::SameTeal,
121 39 => Self::SameBrown,
122 40 => Self::DiffBlack,
123 41 => Self::DiffBlue,
124 42 => Self::DiffRed,
125 43 => Self::DiffGreen,
126 44 => Self::DiffYellow,
127 45 => Self::DiffGrey,
128 46 => Self::DiffFuchsia,
129 47 => Self::DiffOrange,
130 48 => Self::DiffTeal,
131 49 => Self::DiffBrown,
132 50 => Self::OrigBlack,
133 51 => Self::OrigBlue,
134 52 => Self::OrigRed,
135 53 => Self::OrigGreen,
136 54 => Self::OrigYellow,
137 55 => Self::OrigGrey,
138 56 => Self::OrigFuchsia,
139 57 => Self::OrigOrange,
140 58 => Self::OrigTeal,
141 59 => Self::OrigBrown,
142 90 => Self::NoColour,
143 91 => Self::Mixed,
144 92 => Self::Transparent,
145 93 => Self::DiffShape, 94 => Self::Same, _ => Self::NoColour
148 }
149 }
150
151 pub fn to_usize(self) -> usize {
152 match self {
153 Self::Black => 0,
154 Self::Blue => 1,
155 Self::Red => 2,
156 Self::Green => 3,
157 Self::Yellow => 4,
158 Self::Grey => 5,
159 Self::Fuchsia => 6,
160 Self::Orange => 7,
161 Self::Teal => 8,
162 Self::Brown => 9,
163 Self::ToBlack => 10,
164 Self::ToBlue => 11,
165 Self::ToRed => 12,
166 Self::ToGreen => 13,
167 Self::ToYellow => 14,
168 Self::ToGrey => 15,
169 Self::ToFuchsia => 16,
170 Self::ToOrange => 17,
171 Self::ToTeal => 18,
172 Self::ToBrown => 19,
173 Self::FromBlack => 20,
174 Self::FromBlue => 21,
175 Self::FromRed => 22,
176 Self::FromGreen => 23,
177 Self::FromYellow => 24,
178 Self::FromGrey => 25,
179 Self::FromFuchsia => 26,
180 Self::FromOrange => 27,
181 Self::FromTeal => 28,
182 Self::FromBrown => 29,
183 Self::SameBlack => 30,
184 Self::SameBlue => 31,
185 Self::SameRed => 32,
186 Self::SameGreen => 33,
187 Self::SameYellow => 34,
188 Self::SameGrey => 35,
189 Self::SameFuchsia => 36,
190 Self::SameOrange => 37,
191 Self::SameTeal => 38,
192 Self::SameBrown => 39,
193 Self::DiffBlack => 40,
194 Self::DiffBlue => 41,
195 Self::DiffRed => 42,
196 Self::DiffGreen => 43,
197 Self::DiffYellow => 44,
198 Self::DiffGrey => 45,
199 Self::DiffFuchsia => 46,
200 Self::DiffOrange => 47,
201 Self::DiffTeal => 48,
202 Self::DiffBrown => 49,
203 Self::OrigBlack => 50,
204 Self::OrigBlue => 51,
205 Self::OrigRed => 52,
206 Self::OrigGreen => 53,
207 Self::OrigYellow => 54,
208 Self::OrigGrey => 55,
209 Self::OrigFuchsia => 56,
210 Self::OrigOrange => 57,
211 Self::OrigTeal => 58,
212 Self::OrigBrown => 59,
213 Self::NoColour => 90,
214 Self::Mixed => 91,
215 Self::Transparent => 92, Self::DiffShape => 93, Self::Same => 94, }
220 }
221
222 pub fn to_base(self) -> Self {
223 Self::from_usize(Self::to_usize(self) % 10)
224 }
225
226 pub fn to_base_sub(self, colour: Self) -> Self {
227 Self::from_usize(Self::to_usize(self) - Self::to_usize(colour))
228 }
229
230 pub fn is_colour(self) -> bool {
231 self == Self::Same || self < Self::NoColour
232 }
233
234 pub fn in_range(c: usize) -> bool {
235 c < 60 || c >= 90 && c <= 94
236 }
237
238 pub fn colours() -> Vec<Self> {
239 (1..=9).map(Self::from_usize).collect()
240 }
241
242 pub const fn base_colours() -> &'static [Self] {
243 &[Self::Black, Self::Blue, Self::Red, Self::Green, Self::Yellow, Self::Grey, Self::Fuchsia, Self::Orange, Self::Teal, Self::Brown]
244 }
245
246 pub fn is_unit(self) -> bool {
247 self > Self::Black && self <= Self::Brown
248 }
249
250 pub fn is_to(self) -> bool {
251 self > Self::ToBlack && self <= Self::ToBrown
252 }
253
254 pub fn is_from(self) -> bool {
255 self >= Self::FromBlack && self <= Self::FromBrown
256 }
257
258 pub fn is_same(self) -> bool {
259 self >= Self::SameBlack && self <= Self::SameBrown
260 }
261
262 pub fn is_diff(self) -> bool {
263 self >= Self::DiffBlack && self <= Self::DiffBrown
264 }
265
266 pub fn is_orig(self) -> bool {
267 self >= Self::OrigBlack && self <= Self::OrigBrown
268 }
269
270 pub fn and(self, other: Self) -> Self {
271 if self == Self::Black || other == Self::Black || self != other {
272 Self::Black
273 } else {
274 self
275 }
276 }
277
278 pub fn or(self, other: Self) -> Self {
279 if self == Self::Black {
280 if other == Self::Black {
281 Self::Black
282 } else {
283 other
284 }
285 } else if other == Self::Black || self == other {
286 self
287 } else {
288 Self::Black
289 }
290 }
291
292 pub fn xor(self, other: Self) -> Self {
293 if self == Self::Black {
294 if other == Self::Black {
295 Self::Black
296 } else {
297 other
298 }
299 } else if other == Self::Black {
300 self
301 } else {
302 Self::Black
303 }
304 }
305
306 pub fn single_colour_vec(v: &[Self]) -> bool {
307 if v.is_empty() {
308 return false;
309 }
310
311 let c = v[0];
312
313 for col in v.iter() {
314 if *col != c {
315 return false;
316 }
317 }
318
319 true
320 }
321
322 pub fn all_colours() -> BTreeSet<Self> {
323 (0 ..= 9).map(Colour::from_usize).collect()
324 }
325
326 pub fn get_position(self, v: &[Colour]) -> usize {
327 v.iter().position(|&ac| ac == self).unwrap_or(0)
328 }
329}
330
331impl Add for Colour {
332 type Output = Colour;
333
334 fn add(self, other: Colour) -> Self::Output {
335 Self::from_usize(Self::to_usize(self) + Self::to_usize(other))
336 }
337}
338
339impl Sub for Colour {
340 type Output = Colour;
341
342 fn sub(self, other: Colour) -> Self::Output {
343 Self::from_usize(Self::to_usize(self) - Self::to_usize(other))
344 }
345}
346
347#[repr(usize)]
348#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
349pub enum GridCategory {
350 HasArms,
351 BareCornersIn,
352 BareCornersOut,
353 BGGridInBlack,
354 BGGridInColoured,
355 BGGridOutBlack,
356 BGGridOutColoured,
357 BlackPatches,
358 BlankIn,
359 BlankOut,
360 BorderBottomIn,
361 BorderBottomOut,
362 BorderLeftIn,
363 BorderLeftOut,
364 BorderRightIn,
365 BorderRightOut,
366 BorderTopIn,
367 BorderTopOut,
368 DiagonalOutOrigin,
369 DiagonalOutNotOrigin,
370 Div9In,
371 Div9Out,
372 Double,
373 CatchAll,
374 EmptyOutput,
375 EvenRowsIn,
376 EvenRowsOut,
377 FullyPopulatedIn,
378 FullyPopulatedOut,
379 GravityDown,
380 GravityLeft,
381 GravityRight,
382 GravityUp,
383 GridLikelyhood,
384 HasBGShape,
385 HasBGShapeColoured,
386 IdenticalColours,
387 IdenticalNoColours,
388 IdenticalNoPixels,
389 InEmpty,
390 InLessCountOut,
391 InLessCountOutColoured,
392 InLessThanOut,
393 InLine,
394 InOutSameShapes,
395 InOutSameShapesColoured,
396 InOutSameSize,
397 InOutShapeCount,
398 InOutShapeCountColoured,
399 InOutSquare,
400 InOutSquareSameSize,
401 InOutSquareSameSizeEven,
402 InOutSquareSameSizeOdd,
403 InSameCountOut,
404 InSameCountOutColoured,
405 InSameSize,
406 InSquare,
407 InToSquaredOut,
408 InvTranspose,
409 InROutHeight(usize),
410 InROutWidth(usize),
411 Is3x3In,
412 Is3x3Out,
413 IsPanelledRIn,
414 IsPanelledROut,
415 IsPanelledCIn,
416 IsPanelledCOut,
417 MirroredR,
418 MirroredC,
419 MirrorRIn,
420 MirrorROut,
421 MirrorCIn,
422 MirrorCOut,
423 NoColouredShapesIn(usize),
424 NoColouredShapesOut(usize),
425 NoColoursIn(usize),
426 NoColoursOut(usize),
427 NoNetColouredShapesIn,
428 NoNetColouredShapesOut,
429 NoShapesIn(usize),
430 NoShapesOut(usize),
431 NotCat,
432 NxNIn(usize),
433 NxNOut(usize),
434 OutLessCountIn,
435 OutLessCountInColoured,
436 OutLessThanIn,
437 OutLine,
438 OutRInHeight(usize),
439 OutRInWidth(usize),
440 OutSameSize,
441 OutSquare,
442 OverlayInSame,
443 OverlayOutSame,
444 OverlayInDiff,
445 OverlayOutDiff,
446 Rot180,
447 Rot270,
448 Rot90,
449 SameColour,
450 ShapeMaxCntIn(usize),
451 ShapeMaxCntOut(usize),
452 ShapeMinCntIn(usize),
453 ShapeMinCntOut(usize),
454 SingleColouredShapeIn,
455 SingleColouredShapeOut,
456 SingleColourCountIn(usize),
457 SingleColourCountOut(usize),
458 SingleColourIn2xOut,
459 SingleColourIn4xOut,
460 SingleColourOut2xIn,
461 SingleColourOut4xIn,
462 SingleColourIn,
463 SingleColourOut,
464 SinglePixelOut,
465 SingleShapeIn,
466 SingleShapeOut,
467 SquareShapeSide(usize),
468 SquareShapeSize(usize),
469 SurroundOut,
470 SymmetricIn,
471 SymmetricInLR,
472 SymmetricInUD,
473 SymmetricOut,
474 SymmetricOutLR,
475 SymmetricOutUD,
476 Transpose,
477}
481
482impl GridCategory {
483 pub fn equal(&self, other: &Self) -> bool {
484 self.same(other) && self.get_para() == other.get_para()
485 }
486
487 pub fn lt(&self, other: &Self) -> bool {
488 self.same(other) && self.get_para() < other.get_para()
489 }
490
491 pub fn gt(&self, other: &Self) -> bool {
492 self.same(other) && self.get_para() > other.get_para()
493 }
494
495 pub fn lte(&self, other: &Self) -> bool {
496 self.same(other) && self.get_para() <= other.get_para()
497 }
498
499 pub fn gte(&self, other: &Self) -> bool {
500 self.same(other) && self.get_para() >= other.get_para()
501 }
502
503 pub fn get_para(&self) -> usize {
504 match self {
505 GridCategory::InROutHeight(i) => *i,
506 GridCategory::InROutWidth(i) => *i,
507 GridCategory::NoColoursIn(i) => *i,
508 GridCategory::NoColoursOut(i) => *i,
509 GridCategory::NoColouredShapesIn(i) => *i,
510 GridCategory::NoColouredShapesOut(i) => *i,
511 GridCategory::NoShapesIn(i) => *i,
512 GridCategory::NoShapesOut(i) => *i,
513 GridCategory::NxNIn(i) => *i,
514 GridCategory::NxNOut(i) => *i,
515 GridCategory::OutRInHeight(i) => *i,
516 GridCategory::OutRInWidth(i) => *i,
517 GridCategory::ShapeMaxCntIn(i) => *i,
518 GridCategory::ShapeMaxCntOut(i) => *i,
519 GridCategory::ShapeMinCntIn(i) => *i,
520 GridCategory::ShapeMinCntOut(i) => *i,
521 GridCategory::SingleColourCountIn(i) => *i,
522 GridCategory::SingleColourCountOut(i) => *i,
523 GridCategory::SquareShapeSide(i) => *i,
524 GridCategory::SquareShapeSize(i) => *i,
525 _ => usize::MAX
526 }
527 }
528
529 pub fn same(&self, other: &Self) -> bool {
530 core::mem::discriminant(self) == core::mem::discriminant(other)
531 }
532
533 pub fn exists(&self, set: &BTreeSet<GridCategory>) -> bool {
534 for i in set.iter() {
535 if self.same(&i) {
536 return true;
537 }
538 }
539
540 false
541 }
542
543 pub fn get(&self, set: &BTreeSet<GridCategory>) -> GridCategory {
544 for cat in set.iter() {
545 if self.same(&cat) {
546 return *cat;
547 }
548 }
549
550 GridCategory::NotCat
551 }
552
553 pub fn value(&self, set: &BTreeSet<GridCategory>) -> usize {
554 for cat in set.iter() {
555 if self.same(&cat) {
556 return cat.get_para();
557 }
558 }
559
560 usize::MAX
561 }
562
563 pub fn eq_value(&self, other: &Self, cats: &BTreeSet<GridCategory>) -> bool {
564 self.same(other) && self.value(cats) == other.value(cats)
565 }
566
567 pub fn lt_value(&self, other: &Self, cats: &BTreeSet<GridCategory>) -> bool {
568 self.same(other) && self.value(cats) < other.value(cats)
569 }
570
571 pub fn gt_value(&self, other: &Self, cats: &BTreeSet<GridCategory>) -> bool {
572 self.same(other) && self.value(cats) > other.value(cats)
573 }
574
575 pub fn lte_value(&self, other: &Self, cats: &BTreeSet<GridCategory>) -> bool {
576 self.same(other) && self.value(cats) <= other.value(cats)
577 }
578
579 pub fn gte_value(&self, other: &Self, cats: &BTreeSet<GridCategory>) -> bool {
580 self.same(other) && self.value(cats) >= other.value(cats)
581 }
582
583}
584
585#[repr(usize)]
586#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
587pub enum ShapeCategory {
588 ArmBottom(usize),
589 ArmLeft(usize),
590 ArmRight(usize),
591 ArmTop(usize),
592 Full,
593 HasBorder,
594 HasEmptyHole,
595 HasHole,
596 HorizontalLine,
598 ManyShapes,
599 OpenBottom,
602 OpenBottomHole,
603 OpenLeft,
604 OpenLeftHole,
605 OpenRight,
606 OpenRightHole,
607 OpenTop,
608 OpenTopHole,
609 Pixel,
610 SingleCell,
611 SingleShape,
612 Square,
613 VerticalLine,
614 Other,
615}
616
617#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
618pub enum Direction {
619 Up,
620 Down,
621 Left,
622 Right,
623 UpLeft,
624 UpRight,
625 DownLeft,
626 DownRight,
627 FromUpLeft,
628 FromUpRight,
629 FromDownLeft,
630 FromDownRight,
631 Vertical,
632 Horizontal,
633 Middle,
634 Other,
635 SameDir,
636 CalcDir,
637}
638
639impl Direction {
640 pub fn inverse(&self) -> Self {
641 match self {
642 Self::Up => Self::Down,
643 Self::Down => Self::Up,
644 Self::Left => Self::Right,
645 Self::Right => Self::Left,
646 Self::UpLeft => Self::DownRight,
647 Self::UpRight => Self::DownLeft,
648 Self::DownLeft => Self::UpRight,
649 Self::DownRight => Self::UpLeft,
650 Self::FromUpLeft => Self::FromDownRight,
651 Self::FromUpRight => Self::FromDownLeft,
652 Self::FromDownLeft => Self::FromUpRight,
653 Self::FromDownRight => Self::FromUpLeft,
654 Self::Other => Self::Other,
655 Self::SameDir => Self::SameDir,
656 Self::CalcDir => Self::CalcDir,
657 Self::Vertical => Self::Vertical,
658 Self::Horizontal => Self::Horizontal,
659 Self::Middle => Self::Middle,
660 }
661 }
662
663 pub fn rot(&self) -> Self {
664 match self {
665 Self::Up => Self::Right,
666 Self::Down => Self::Left,
667 Self::Left => Self::Up,
668 Self::Right => Self::Down,
669 Self::UpLeft => Self::UpRight,
670 Self::UpRight => Self::UpLeft,
671 Self::DownLeft => Self::DownRight,
672 Self::DownRight => Self::DownLeft,
673 Self::FromUpLeft => Self::FromUpRight,
674 Self::FromUpRight => Self::FromUpLeft,
675 Self::FromDownLeft => Self::FromDownRight,
676 Self::FromDownRight => Self::FromDownLeft,
677 Self::Other => Self::Other,
678 Self::SameDir => Self::SameDir,
679 Self::CalcDir => Self::CalcDir,
680 Self::Vertical => Self::Vertical,
681 Self::Horizontal => Self::Horizontal,
682 Self::Middle => Self::Middle,
683 }
684 }
685}
686
687#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, EnumIter, EnumString)]
688pub enum Transformation { NoTrans,
690 MirrorRow,
691 MirrorCol,
692 Trans,
693 Rotate90,
694 Rotate180,
695 Rotate270,
696 Rotate90MirrorRow,
697 Rotate180MirrorRow,
698 Rotate270MirrorRow,
699 Rotate90MirrorCol,
700 Rotate180MirrorCol,
701 Rotate270MirrorCol,
702 MirrorRowRotate90,
703 MirrorRowRotate180,
704 MirrorRowRotate270,
705 MirrorColRotate90,
706 MirrorColRotate180,
707 MirrorColRotate270,
708}
709
710impl Transformation {
711 pub fn inverse(&self) -> Self {
712 match self {
713 Self::NoTrans => Self::NoTrans,
714 Self::MirrorRow => Self::MirrorRow,
715 Self::MirrorCol => Self::MirrorCol,
716 Self::Trans => Self::Trans,
717 Self::Rotate90 => Self::Rotate270,
718 Self::Rotate180 => Self::Rotate180,
719 Self::Rotate270 => Self::Rotate90,
720 Self::Rotate90MirrorRow => Self::MirrorRowRotate270,
721 Self::Rotate180MirrorRow => Self::MirrorRowRotate180,
722 Self::Rotate270MirrorRow => Self::MirrorRowRotate90,
723 Self::Rotate90MirrorCol => Self::MirrorColRotate270,
724 Self::Rotate180MirrorCol => Self::MirrorColRotate180,
725 Self::Rotate270MirrorCol => Self::MirrorColRotate90,
726 Self::MirrorRowRotate90 => Self::Rotate270MirrorRow,
727 Self::MirrorRowRotate180 => Self::Rotate180MirrorRow,
728 Self::MirrorRowRotate270 => Self::Rotate90MirrorRow,
729 Self::MirrorColRotate90 => Self::Rotate270MirrorCol,
730 Self::MirrorColRotate180 => Self::Rotate180MirrorCol,
731 Self::MirrorColRotate270 => Self::Rotate90MirrorCol,
732 }
733 }
734}
735
736#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
768pub enum Tag {
769 Colour,
770 Arm,
771 Shape,
772 Other,
773}
774
775#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
776pub enum Action {
777 Together,
778 Reach,
779}
780
781#[repr(usize)]
782#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
783pub enum ShapeEdgeCategory {
784 Above,
786 AboveLeft,
787 AboveRight,
788 Adjacent,
789 Below,
790 BelowLeft,
791 BelowRight,
792 CanContain,
793 CommonPixel,
794 Gravity,
795 HasArm,
796 Left,
797 MirroredRow,
798 MirroredCol,
799 Right,
800 Rot180,
801 Rot270,
802 Rot90,
803 Same,
804 SameColour,
805 SamePixelCount,
806 SameShape,
807 SameSingle,
808 SameSize,
809 SingleColour,
810 SingleDiffColour,
811 SinglePixel,
812 Symmetric,
813 Transposed,
814}
815
816#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
829pub enum CellCategory {
830 CornerTL,
831 CornerTR,
832 CornerBL,
833 CornerBR,
834 InsideCornerTL,
835 InsideCornerTR,
836 InsideCornerBL,
837 InsideCornerBR,
838 InternalCornerTL,
839 InternalCornerTR,
840 InternalCornerBL,
841 InternalCornerBR,
842 InternalEdgeT,
843 InternalEdgeB,
844 InternalEdgeL,
845 InternalEdgeR,
846 EdgeT,
847 EdgeB,
848 EdgeL,
849 EdgeR,
850 TopEdgeT,
851 TopEdgeB,
852 TopEdgeL,
853 TopEdgeR,
854 BottomEdgeT,
855 BottomEdgeB,
856 BottomEdgeL,
857 BottomEdgeR,
858 LeftEdgeT,
859 LeftEdgeB,
860 LeftEdgeL,
861 LeftEdgeR,
862 RightEdgeT,
863 RightEdgeB,
864 RightEdgeL,
865 RightEdgeR,
866 HollowEdgeT,
867 HollowEdgeB,
868 HollowEdgeL,
869 HollowEdgeR,
870 PointT,
871 PointB,
872 PointL,
873 PointR,
874 LineTB,
879 LineLR,
880 MiddleTB,
881 MiddleLR,
882 Middle,
883 Single,
884 SingleT,
885 SingleB,
886 SingleL,
887 SingleR,
888 Unknown,
889 StemLR,
890 StemTB,
891 BG,
892}
893
894impl CellCategory {
895 pub fn edge_corner(self) -> bool {
896 self >= Self::CornerTL && self <= Self::CornerBR
897 }
898
899 pub fn internal_corner(self) -> bool {
900 self >= Self::InternalCornerTL && self <= Self::InternalCornerBR
901 }
902
903 pub fn inside_corner(self) -> bool {
904 self >= Self::InsideCornerTL && self <= Self::InsideCornerBR
905 }
906
907 pub fn outer_corner(self) -> bool {
908 self.edge_corner() || self.internal_corner()
909 }
910
911 pub fn has_point(self) -> bool {
912 matches!(self, Self::PointT | Self::PointB | Self::PointL | Self::PointR)
913 }
914}