1use std::{
13 fmt::{self, Display, Formatter},
14 io::{Error, ErrorKind},
15};
16
17use console::style;
18use shakmaty::{uci::Uci, Board, Color, Role, Square};
19
20#[derive(Debug)]
22pub struct PageBounds {
23 pub pad: i32,
25 pub low: i32,
27 pub high: i32,
29}
30
31#[derive(Debug, Clone, Eq, PartialEq)]
33pub struct ByteBoard {
34 pub bytes: [u8; 64],
36}
37
38#[derive(Debug, Eq, PartialEq, Copy, Clone, PartialOrd, Ord)]
50#[repr(u8)]
51pub enum Nag {
52 Null,
54 Good,
56 Mistake,
58 Hard,
60 Blunder,
62 Interesting,
64 Dubious,
66 Forced,
68 Only,
70 Worst,
72 Drawish,
74 EqualQuiet,
76 EqualActive,
78 Unclear,
80 SlightEdgeWhite,
82 SlightEdgeBlack,
84 ModerateAdvantageWhite,
86 ModerateAdvantageBlack,
88 DecisiveAdvantageWhite,
90 DecisiveAdvantageBlack,
92 CrushingAdvantageWhite,
94 CrushingAdvantageBlack,
96 ZugzwangWhite,
98 ZugzwangBlack,
100 SlightSpaceAdvantageWhite,
102 SlightSpaceAdvantageBlack,
104 ModerateSpaceAdvantageWhite,
106 ModerateSpaceAdvantageBlack,
108 DecisiveSpaceAdvantageWhite,
110 DecisiveSpaceAdvantageBlack,
112 SlightDevelopmentAdvantageWhite,
114 SlightDevelopmentAdvantageBlack,
116 ModerateDevelopmentAdvantageWhite,
118 ModerateDevelopmentAdvantageBlack,
120 DecisiveDevelopmentAdvantageWhite,
122 DecisiveDevelopmentAdvantageBlack,
124 InitiativeWhite,
126 InitiativeBlack,
128 LastingInitiativeWhite,
130 LastingInitiativeBlack,
132 AttackWhite,
134 AttackBlack,
136 InsufficientCompensationWhite,
138 InsufficientCompensationBlack,
140 SufficientCompensationWhite,
142 SufficientCompensationBlack,
144 MoreThanAdequateCompensationWhite,
146 MoreThanAdequateCompensationBlack,
148 SlightCenterControlAdvantageWhite,
150 SlightCenterControlAdvantageBlack,
152 ModerateCenterControlAdvantageWhite,
154 ModerateCenterControlAdvantageBlack,
156 DecisiveCenterControlAdvantageWhite,
158 DecisiveCenterControlAdvantageBlack,
160 SlightKingSideControlAdvantageWhite,
162 SlightKingSideControlAdvantageBlack,
164 ModerateKingSideControlAdvantageWhite,
166 ModerateKingSideControlAdvantageBlack,
168 DecisiveKingSideControlAdvantageWhite,
170 DecisiveKingSideControlAdvantageBlack,
172 SlightQueenSideControlAdvantageWhite,
174 SlightQueenSideControlAdvantageBlack,
176 ModerateQueenSideControlAdvantageWhite,
178 ModerateQueenSideControlAdvantageBlack,
180 DecisiveQueenSideControlAdvantageWhite,
182 DecisiveQueenSideControlAdvantageBlack,
184 VulnerableFirstRankWhite,
186 VulnerableFirstRankBlack,
188 WellProtectedFirstRankWhite,
190 WellProtectedFirstRankBlack,
192 PoorlyProtectedKingWhite,
194 PoorlyProtectedKingBlack,
196 WellProtectedKingWhite,
198 WellProtectedKingBlack,
200 PoorlyPlacedKingWhite,
202 PoorlyPlacedKingBlack,
204 WellPlacedKingWhite,
206 WellPlacedKingBlack,
208 VeryWeakPawnStructureWhite,
210 VeryWeakPawnStructureBlack,
212 ModeratelyWeakPawnStructureWhite,
214 ModeratelyWeakPawnStructureBlack,
216 ModeratelyStrongPawnStructureWhite,
218 ModeratelyStrongPawnStructureBlack,
220 VeryStrongPawnStructureWhite,
222 VeryStrongPawnStructureBlack,
224 PoorKnightPlacementWhite,
226 PoorKnightPlacementBlack,
228 GoodKnightPlacementWhite,
230 GoodKnightPlacementBlack,
232 PoorBishopPlacementWhite,
234 PoorBishopPlacementBlack,
236 GoodBishopPlacementWhite,
238 GoodBishopPlacementBlack,
240 PoorRookPlacementWhite,
242 PoorRookPlacementBlack,
244 GoodRookPlacementWhite,
246 GoodRookPlacementBlack,
248 PoorQueenPlacementWhite,
250 PoorQueenPlacementBlack,
252 GoodQueenPlacementWhite,
254 GoodQueenPlacementBlack,
256 PoorPieceCoordinationWhite,
258 PoorPieceCoordinationBlack,
260 GoodPieceCoordinationWhite,
262 GoodPieceCoordinationBlack,
264 VeryPoorOpeningPlayWhite,
266 VeryPoorOpeningPlayBlack,
268 PoorOpeningPlayWhite,
270 PoorOpeningPlayBlack,
272 WellOpeningPlayWhite,
274 WellOpeningPlayBlack,
276 VeryWellOpeningPlayWhite,
278 VeryWellOpeningPlayBlack,
280 VeryPoorMiddleGamePlayWhite,
282 VeryPoorMiddleGamePlayBlack,
284 PoorMiddleGamePlayWhite,
286 PoorMiddleGamePlayBlack,
288 WellMiddleGamePlayWhite,
290 WellMiddleGamePlayBlack,
292 VeryWellMiddleGamePlayWhite,
294 VeryWellMiddleGamePlayBlack,
296 VeryPoorEndingPlayWhite,
298 VeryPoorEndingPlayBlack,
300 PoorEndingPlayWhite,
302 PoorEndingPlayBlack,
304 WellEndingPlayWhite,
306 WellEndingPlayBlack,
308 VeryWellEndingPlayWhite,
310 VeryWellEndingPlayBlack,
312 SlightCounterPlayWhite,
314 SlightCounterPlayBlack,
316 ModerateCounterPlayWhite,
318 ModerateCounterPlayBlack,
320 DecisiveCounterPlayWhite,
322 DecisiveCounterPlayBlack,
324 ModerateTimeControlPressureWhite,
326 ModerateTimeControlPressureBlack,
328 SevereTimeControlPressureWhite,
330 SevereTimeControlPressureBlack,
332 WithTheIdea,
334 AimedAgainst,
336 BetterIs,
338 WorseIs,
340 EquivalentIs,
342 EditorialComment,
344 Novelty,
346 Nag147,
348 Nag148,
350 Nag149,
352 Nag150,
354 Nag151,
356 Nag152,
358 Nag153,
360 Nag154,
362 Nag155,
364 Nag156,
366 Nag157,
368 Nag158,
370 Nag159,
372 Nag160,
374 Nag161,
376 Nag162,
378 Nag163,
380 Nag164,
382 Nag165,
384 Nag166,
386 Nag167,
388 Nag168,
390 Nag169,
392 Nag170,
394 Nag171,
396 Nag172,
398 Nag173,
400 Nag174,
402 Nag175,
404 Nag176,
406 Nag177,
408 Nag178,
410 Nag179,
412 Nag180,
414 Nag181,
416 Nag182,
418 Nag183,
420 Nag184,
422 Nag185,
424 Nag186,
426 Nag187,
428 Nag188,
430 Nag189,
432 Nag190,
434 Nag191,
436 Nag192,
438 Nag193,
440 Nag194,
442 Nag195,
444 Nag196,
446 Nag197,
448 Nag198,
450 Nag199,
452 Nag200,
454 Nag201,
456 Nag202,
458 Nag203,
460 Nag204,
462 Nag205,
464 Nag206,
466 Nag207,
468 Nag208,
470 Nag209,
472 Nag210,
474 Nag211,
476 Nag212,
478 Nag213,
480 Nag214,
482 Nag215,
484 Nag216,
486 Nag217,
488 Nag218,
490 Nag219,
492 Diagram,
494 DiagramFromBlack,
496 Nag222,
498 Nag223,
500 Nag224,
502 Nag225,
504 Nag226,
506 Nag227,
508 Nag228,
510 Nag229,
512 Nag230,
514 Nag231,
516 Nag232,
518 Nag233,
520 Nag234,
522 Nag235,
524 Nag236,
526 Nag237,
528 SpaceAdvantage,
530 File,
532 Diagonal,
534 Centre,
536 KingSide,
538 QueenSide,
540 WeakPoint,
542 Ending,
544 BishopPair,
546 OppositeBishops,
548 SameBishops,
550 ConnectedPawns,
552 IsolatedPawns,
554 DoubledPawns,
556 PassedPawn,
558 PawnMajority,
560 With,
562 Without,
564}
565
566impl Display for Nag {
567 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
568 match self {
569 Nag::Null => write!(f, " "),
570 Nag::Hard => write!(f, "!!"),
571 Nag::Good => write!(f, "!"),
572 Nag::Mistake => write!(f, "?"),
573 Nag::Blunder => write!(f, "??"),
574 Nag::Interesting => write!(f, "!?"),
575 Nag::Dubious => write!(f, "?!"),
576 Nag::Forced | Nag::Only => write!(f, "□"),
577 Nag::ZugzwangWhite | Nag::ZugzwangBlack => write!(f, "⊙"),
578 Nag::ModerateSpaceAdvantageWhite | Nag::ModerateSpaceAdvantageBlack => write!(f, "○"),
579 Nag::ModerateDevelopmentAdvantageWhite | Nag::ModerateDevelopmentAdvantageBlack => {
580 write!(f, "⟳")
581 }
582 Nag::InitiativeWhite | Nag::InitiativeBlack => write!(f, "↑"),
583 Nag::AttackWhite | Nag::AttackBlack => write!(f, "→"),
584 Nag::SufficientCompensationWhite | Nag::SufficientCompensationBlack => write!(f, "⯹"),
585 Nag::ModerateCounterPlayWhite
586 | Nag::DecisiveCounterPlayWhite
587 | Nag::ModerateCounterPlayBlack
588 | Nag::DecisiveCounterPlayBlack => write!(f, "⇆"),
589 Nag::SevereTimeControlPressureWhite | Nag::SevereTimeControlPressureBlack => {
590 write!(f, "⨁")
591 }
592 Nag::WithTheIdea => write!(f, "∆"),
593 Nag::AimedAgainst => write!(f, "∇"),
594 Nag::BetterIs => write!(f, "⌓"),
595 Nag::WorseIs => write!(f, "<="),
596 Nag::EquivalentIs => write!(f, "=="),
597 Nag::EditorialComment => write!(f, "RR"),
598 Nag::Novelty => write!(f, "N"),
599 Nag::Diagram => write!(f, "⬒"),
600 Nag::DiagramFromBlack => write!(f, "⬓"),
601 Nag::SpaceAdvantage => write!(f, "○"),
602 Nag::File => write!(f, "⇔"),
603 Nag::Diagonal => write!(f, "⇗"),
604 Nag::Centre => write!(f, "⊞"),
605 Nag::KingSide => write!(f, "⟫"),
606 Nag::QueenSide => write!(f, "⟪"),
607 Nag::WeakPoint => write!(f, "✕"),
608 Nag::Ending => write!(f, "⊥"),
609 Nag::ConnectedPawns => write!(f, "⯺"),
610 Nag::IsolatedPawns => write!(f, "⯻"),
611 Nag::DoubledPawns => write!(f, "⯼"),
612 Nag::PassedPawn => write!(f, "⯽"),
613 Nag::With => write!(f, "∟"),
614 Nag::Without => write!(f, "⯾"),
615 n => write!(f, "${}", n),
616 }
617 }
618}
619
620impl From<u8> for Nag {
621 fn from(num: u8) -> Self {
622 match num {
623 0 => Nag::Null,
624 1 => Nag::Good,
625 2 => Nag::Mistake,
626 3 => Nag::Hard,
627 4 => Nag::Blunder,
628 5 => Nag::Interesting,
629 6 => Nag::Dubious,
630 7 => Nag::Forced,
631 8 => Nag::Only,
632 9 => Nag::Worst,
633 10 => Nag::Drawish,
634 11 => Nag::EqualQuiet,
635 12 => Nag::EqualActive,
636 13 => Nag::Unclear,
637 14 => Nag::SlightEdgeWhite,
638 15 => Nag::SlightEdgeBlack,
639 16 => Nag::ModerateAdvantageWhite,
640 17 => Nag::ModerateAdvantageBlack,
641 18 => Nag::DecisiveAdvantageWhite,
642 19 => Nag::DecisiveAdvantageBlack,
643 20 => Nag::CrushingAdvantageWhite,
644 21 => Nag::CrushingAdvantageBlack,
645 22 => Nag::ZugzwangWhite,
646 23 => Nag::ZugzwangBlack,
647 24 => Nag::SlightSpaceAdvantageWhite,
648 25 => Nag::SlightSpaceAdvantageBlack,
649 26 => Nag::ModerateSpaceAdvantageWhite,
650 27 => Nag::ModerateSpaceAdvantageBlack,
651 28 => Nag::DecisiveSpaceAdvantageWhite,
652 29 => Nag::DecisiveSpaceAdvantageBlack,
653 30 => Nag::SlightDevelopmentAdvantageWhite,
654 31 => Nag::SlightDevelopmentAdvantageBlack,
655 32 => Nag::ModerateDevelopmentAdvantageWhite,
656 33 => Nag::ModerateDevelopmentAdvantageBlack,
657 34 => Nag::DecisiveDevelopmentAdvantageWhite,
658 35 => Nag::DecisiveDevelopmentAdvantageBlack,
659 36 => Nag::InitiativeWhite,
660 37 => Nag::InitiativeBlack,
661 38 => Nag::LastingInitiativeWhite,
662 39 => Nag::LastingInitiativeBlack,
663 40 => Nag::AttackWhite,
664 41 => Nag::AttackBlack,
665 42 => Nag::InsufficientCompensationWhite,
666 43 => Nag::InsufficientCompensationBlack,
667 44 => Nag::SufficientCompensationWhite,
668 45 => Nag::SufficientCompensationBlack,
669 46 => Nag::MoreThanAdequateCompensationWhite,
670 47 => Nag::MoreThanAdequateCompensationBlack,
671 48 => Nag::SlightCenterControlAdvantageWhite,
672 49 => Nag::SlightCenterControlAdvantageBlack,
673 50 => Nag::ModerateCenterControlAdvantageWhite,
674 51 => Nag::ModerateCenterControlAdvantageBlack,
675 52 => Nag::DecisiveCenterControlAdvantageWhite,
676 53 => Nag::DecisiveCenterControlAdvantageBlack,
677 54 => Nag::SlightKingSideControlAdvantageWhite,
678 55 => Nag::SlightKingSideControlAdvantageBlack,
679 56 => Nag::ModerateKingSideControlAdvantageWhite,
680 57 => Nag::ModerateKingSideControlAdvantageBlack,
681 58 => Nag::DecisiveKingSideControlAdvantageWhite,
682 59 => Nag::DecisiveKingSideControlAdvantageBlack,
683 60 => Nag::SlightQueenSideControlAdvantageWhite,
684 61 => Nag::SlightQueenSideControlAdvantageBlack,
685 62 => Nag::ModerateQueenSideControlAdvantageWhite,
686 63 => Nag::ModerateQueenSideControlAdvantageBlack,
687 64 => Nag::DecisiveQueenSideControlAdvantageWhite,
688 65 => Nag::DecisiveQueenSideControlAdvantageBlack,
689 66 => Nag::VulnerableFirstRankWhite,
690 67 => Nag::VulnerableFirstRankBlack,
691 68 => Nag::WellProtectedFirstRankWhite,
692 69 => Nag::WellProtectedFirstRankBlack,
693 70 => Nag::PoorlyProtectedKingWhite,
694 71 => Nag::PoorlyProtectedKingBlack,
695 72 => Nag::WellProtectedKingWhite,
696 73 => Nag::WellProtectedKingBlack,
697 74 => Nag::PoorlyPlacedKingWhite,
698 75 => Nag::PoorlyPlacedKingBlack,
699 76 => Nag::WellPlacedKingWhite,
700 77 => Nag::WellPlacedKingBlack,
701 78 => Nag::VeryWeakPawnStructureWhite,
702 79 => Nag::VeryWeakPawnStructureBlack,
703 80 => Nag::ModeratelyWeakPawnStructureWhite,
704 81 => Nag::ModeratelyWeakPawnStructureBlack,
705 82 => Nag::ModeratelyStrongPawnStructureWhite,
706 83 => Nag::ModeratelyStrongPawnStructureBlack,
707 84 => Nag::VeryStrongPawnStructureWhite,
708 85 => Nag::VeryStrongPawnStructureBlack,
709 86 => Nag::PoorKnightPlacementWhite,
710 87 => Nag::PoorKnightPlacementBlack,
711 88 => Nag::GoodKnightPlacementWhite,
712 89 => Nag::GoodKnightPlacementBlack,
713 90 => Nag::PoorBishopPlacementWhite,
714 91 => Nag::PoorBishopPlacementBlack,
715 92 => Nag::GoodBishopPlacementWhite,
716 93 => Nag::GoodBishopPlacementBlack,
717 94 => Nag::PoorRookPlacementWhite,
718 95 => Nag::PoorRookPlacementBlack,
719 96 => Nag::GoodRookPlacementWhite,
720 97 => Nag::GoodRookPlacementBlack,
721 98 => Nag::PoorQueenPlacementWhite,
722 99 => Nag::PoorQueenPlacementBlack,
723 100 => Nag::GoodQueenPlacementWhite,
724 101 => Nag::GoodQueenPlacementBlack,
725 102 => Nag::PoorPieceCoordinationWhite,
726 103 => Nag::PoorPieceCoordinationBlack,
727 104 => Nag::GoodPieceCoordinationWhite,
728 105 => Nag::GoodPieceCoordinationBlack,
729 106 => Nag::VeryPoorOpeningPlayWhite,
730 107 => Nag::VeryPoorOpeningPlayBlack,
731 108 => Nag::PoorOpeningPlayWhite,
732 109 => Nag::PoorOpeningPlayBlack,
733 110 => Nag::WellOpeningPlayWhite,
734 111 => Nag::WellOpeningPlayBlack,
735 112 => Nag::VeryWellOpeningPlayWhite,
736 113 => Nag::VeryWellOpeningPlayBlack,
737 114 => Nag::VeryPoorMiddleGamePlayWhite,
738 115 => Nag::VeryPoorMiddleGamePlayBlack,
739 116 => Nag::PoorMiddleGamePlayWhite,
740 117 => Nag::PoorMiddleGamePlayBlack,
741 118 => Nag::WellMiddleGamePlayWhite,
742 119 => Nag::WellMiddleGamePlayBlack,
743 120 => Nag::VeryWellMiddleGamePlayWhite,
744 121 => Nag::VeryWellMiddleGamePlayBlack,
745 122 => Nag::VeryPoorEndingPlayWhite,
746 123 => Nag::VeryPoorEndingPlayBlack,
747 124 => Nag::PoorEndingPlayWhite,
748 125 => Nag::PoorEndingPlayBlack,
749 126 => Nag::WellEndingPlayWhite,
750 127 => Nag::WellEndingPlayBlack,
751 128 => Nag::VeryWellEndingPlayWhite,
752 129 => Nag::VeryWellEndingPlayBlack,
753 130 => Nag::SlightCounterPlayWhite,
754 131 => Nag::SlightCounterPlayBlack,
755 132 => Nag::ModerateCounterPlayWhite,
756 133 => Nag::ModerateCounterPlayBlack,
757 134 => Nag::DecisiveCounterPlayWhite,
758 135 => Nag::DecisiveCounterPlayBlack,
759 136 => Nag::ModerateTimeControlPressureWhite,
760 137 => Nag::ModerateTimeControlPressureBlack,
761 138 => Nag::SevereTimeControlPressureWhite,
762 139 => Nag::SevereTimeControlPressureBlack,
763 140 => Nag::WithTheIdea,
764 141 => Nag::AimedAgainst,
765 142 => Nag::BetterIs,
766 143 => Nag::WorseIs,
767 144 => Nag::EquivalentIs,
768 145 => Nag::EditorialComment,
769 146 => Nag::Novelty,
770 147 => Nag::Nag147,
771 148 => Nag::Nag148,
772 149 => Nag::Nag149,
773 150 => Nag::Nag150,
774 151 => Nag::Nag151,
775 152 => Nag::Nag152,
776 153 => Nag::Nag153,
777 154 => Nag::Nag154,
778 155 => Nag::Nag155,
779 156 => Nag::Nag156,
780 157 => Nag::Nag157,
781 158 => Nag::Nag158,
782 159 => Nag::Nag159,
783 160 => Nag::Nag160,
784 161 => Nag::Nag161,
785 162 => Nag::Nag162,
786 163 => Nag::Nag163,
787 164 => Nag::Nag164,
788 165 => Nag::Nag165,
789 166 => Nag::Nag166,
790 167 => Nag::Nag167,
791 168 => Nag::Nag168,
792 169 => Nag::Nag169,
793 170 => Nag::Nag170,
794 171 => Nag::Nag171,
795 172 => Nag::Nag172,
796 173 => Nag::Nag173,
797 174 => Nag::Nag174,
798 175 => Nag::Nag175,
799 176 => Nag::Nag176,
800 177 => Nag::Nag177,
801 178 => Nag::Nag178,
802 179 => Nag::Nag179,
803 180 => Nag::Nag180,
804 181 => Nag::Nag181,
805 182 => Nag::Nag182,
806 183 => Nag::Nag183,
807 184 => Nag::Nag184,
808 185 => Nag::Nag185,
809 186 => Nag::Nag186,
810 187 => Nag::Nag187,
811 188 => Nag::Nag188,
812 189 => Nag::Nag189,
813 190 => Nag::Nag190,
814 191 => Nag::Nag191,
815 192 => Nag::Nag192,
816 193 => Nag::Nag193,
817 194 => Nag::Nag194,
818 195 => Nag::Nag195,
819 196 => Nag::Nag196,
820 197 => Nag::Nag197,
821 198 => Nag::Nag198,
822 199 => Nag::Nag199,
823 200 => Nag::Nag200,
824 201 => Nag::Nag201,
825 202 => Nag::Nag202,
826 203 => Nag::Nag203,
827 204 => Nag::Nag204,
828 205 => Nag::Nag205,
829 206 => Nag::Nag206,
830 207 => Nag::Nag207,
831 208 => Nag::Nag208,
832 209 => Nag::Nag209,
833 210 => Nag::Nag210,
834 211 => Nag::Nag211,
835 212 => Nag::Nag212,
836 213 => Nag::Nag213,
837 214 => Nag::Nag214,
838 215 => Nag::Nag215,
839 216 => Nag::Nag216,
840 217 => Nag::Nag217,
841 218 => Nag::Nag218,
842 219 => Nag::Nag219,
843 220 => Nag::Diagram,
844 221 => Nag::DiagramFromBlack,
845 222 => Nag::Nag222,
846 223 => Nag::Nag223,
847 224 => Nag::Nag224,
848 225 => Nag::Nag225,
849 226 => Nag::Nag226,
850 227 => Nag::Nag227,
851 228 => Nag::Nag228,
852 229 => Nag::Nag229,
853 230 => Nag::Nag230,
854 231 => Nag::Nag231,
855 232 => Nag::Nag232,
856 233 => Nag::Nag233,
857 234 => Nag::Nag234,
858 235 => Nag::Nag235,
859 236 => Nag::Nag236,
860 237 => Nag::Nag237,
861 238 => Nag::SpaceAdvantage,
862 239 => Nag::File,
863 240 => Nag::Diagonal,
864 241 => Nag::Centre,
865 242 => Nag::KingSide,
866 243 => Nag::QueenSide,
867 244 => Nag::WeakPoint,
868 245 => Nag::Ending,
869 246 => Nag::BishopPair,
870 247 => Nag::OppositeBishops,
871 248 => Nag::SameBishops,
872 249 => Nag::ConnectedPawns,
873 250 => Nag::IsolatedPawns,
874 251 => Nag::DoubledPawns,
875 252 => Nag::PassedPawn,
876 253 => Nag::PawnMajority,
877 254 => Nag::With,
878 255 => Nag::Without,
879 }
880 }
881}
882
883impl Nag {
884 pub fn is_question_mark(&self) -> bool {
887 matches!(
888 self,
889 Nag::Interesting | Nag::Dubious | Nag::Mistake | Nag::Blunder | Nag::Worst
890 )
891 }
892}
893
894impl ByteBoard {
895 pub fn new(board_str: &str) -> Self {
904 let bytes: [u8; 64] = board_str.as_bytes().try_into().unwrap();
905 Self { bytes }
906 }
907
908 pub fn from_bytes(slice: &[u8; 64]) -> Self {
923 Self { bytes: *slice }
924 }
925
926 pub fn from_board(board: &Board) -> Self {
940 let mut bytes: [u8; 64] = [b' '; 64];
941
942 let mut set_piece_byte = |role, color, byte: u8| {
943 for square in board.by_role(role) & board.by_color(color) {
944 let (file, rank) = square.coords();
945 let index = (7 - rank as usize) * 8 + file as usize;
946 bytes[index] = byte;
947 }
948 };
949
950 set_piece_byte(Role::Pawn, Color::Black, b'p');
952 set_piece_byte(Role::Pawn, Color::White, b'P');
953 set_piece_byte(Role::Knight, Color::Black, b'n');
954 set_piece_byte(Role::Knight, Color::White, b'N');
955 set_piece_byte(Role::Bishop, Color::Black, b'b');
956 set_piece_byte(Role::Bishop, Color::White, b'B');
957 set_piece_byte(Role::Rook, Color::Black, b'r');
958 set_piece_byte(Role::Rook, Color::White, b'R');
959 set_piece_byte(Role::Queen, Color::Black, b'q');
960 set_piece_byte(Role::Queen, Color::White, b'Q');
961 set_piece_byte(Role::King, Color::Black, b'k');
962 set_piece_byte(Role::King, Color::White, b'K');
963
964 Self { bytes }
965 }
966
967 pub fn as_bytes(&self) -> &[u8] {
978 &self.bytes
979 }
980
981 pub fn from_fen(fen: &[u8]) -> Result<Self, Error> {
996 let mut bytes = [b' '; 64];
998 let mut i = 0;
1000
1001 for &ch in fen {
1003 match ch {
1004 b'r' | b'n' | b'b' | b'q' | b'k' | b'p' | b'R' | b'N' | b'B' | b'Q' | b'K'
1006 | b'P' => {
1007 if i < 64 {
1009 bytes[i] = ch;
1010 i += 1;
1011 } else {
1012 return Err(Error::from(ErrorKind::InvalidInput));
1013 }
1014 }
1015 b'1'..=b'8' => {
1017 let spaces = ch - b'0'; i = (i + spaces as usize).min(64); }
1020 b'/' => {
1022 let remainder = i % 8;
1027 if remainder != 0 {
1028 i += 8 - remainder;
1029 }
1030 }
1031 b' ' => {
1033 break;
1034 }
1035 _ => {
1037 return Err(Error::from(ErrorKind::InvalidInput));
1038 }
1039 }
1040 }
1041
1042 Ok(Self { bytes })
1044 }
1045
1046 pub fn find_piece(&self, piece: char, num: i32) -> Option<i32> {
1062 let piece_byte = piece as u8;
1063 let mut occurrence = num;
1064
1065 for x in 0..8 {
1066 let ux: usize = unsafe { x.try_into().unwrap_unchecked() };
1068
1069 for y in 0..8 {
1070 let uy: usize = unsafe { y.try_into().unwrap_unchecked() };
1072
1073 let index = (7 - uy) * 8 + ux;
1074 if self.bytes[index] != piece_byte {
1075 continue;
1076 }
1077 if occurrence == 1 {
1078 return Some(y * 8 + x);
1079 }
1080 occurrence -= 1;
1081 }
1082 }
1083
1084 None
1085 }
1086
1087 pub fn invert(&mut self) {
1097 for y in 0..4 {
1098 for x in 0..8 {
1099 let index1 = y * 8 + x;
1100 let index2 = (7 - y) * 8 + x;
1101
1102 self.bytes.swap(index1, index2);
1103 self.bytes[index1] = invert_color(self.bytes[index1]);
1104 self.bytes[index2] = invert_color(self.bytes[index2]);
1105 }
1106 }
1107 }
1108
1109 pub fn needs_flipping(&self) -> bool {
1119 self.bytes[0..32].contains(&b'K')
1120 }
1121
1122 pub fn flip(&mut self, eps: Option<Square>) -> Option<Square> {
1136 self.bytes.reverse();
1138
1139 eps.map(|square| square.flip_horizontal())
1140 }
1141}
1142
1143impl std::fmt::Display for ByteBoard {
1144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1145 write!(f, "{}", String::from_utf8_lossy(&self.bytes))
1146 }
1147}
1148
1149#[inline(always)]
1164fn invert_color(c: u8) -> u8 {
1165 match c {
1166 b'p' => b'P',
1167 b'P' => b'p',
1168 b'n' => b'N',
1169 b'N' => b'n',
1170 b'b' => b'B',
1171 b'B' => b'b',
1172 b'r' => b'R',
1173 b'R' => b'r',
1174 b'q' => b'Q',
1175 b'Q' => b'q',
1176 b'k' => b'K',
1177 b'K' => b'k',
1178 _ => c,
1179 }
1180}
1181
1182const TBL2: [u32; 64] = [
1184 0x3100d2bf, 0x3118e3de, 0x34ab1372, 0x2807a847, 0x1633f566, 0x2143b359, 0x26d56488, 0x3b9e6f59,
1185 0x37755656, 0x3089ca7b, 0x18e92d85, 0x0cd0e9d8, 0x1a9e3b54, 0x3eaa902f, 0x0d9bfaae, 0x2f32b45b,
1186 0x31ed6102, 0x3d3c8398, 0x146660e3, 0x0f8d4b76, 0x02c77a5f, 0x146c8799, 0x1c47f51f, 0x249f8f36,
1187 0x24772043, 0x1fbc1e4d, 0x1e86b3fa, 0x37df36a6, 0x16ed30e4, 0x02c3148e, 0x216e5929, 0x0636b34e,
1188 0x317f9f56, 0x15f09d70, 0x131026fb, 0x38c784b1, 0x29ac3305, 0x2b485dc5, 0x3c049ddc, 0x35a9fbcd,
1189 0x31d5373b, 0x2b246799, 0x0a2923d3, 0x08a96e9d, 0x30031a9f, 0x08f525b5, 0x33611c06, 0x2409db98,
1190 0x0ca4feb2, 0x1000b71e, 0x30566e32, 0x39447d31, 0x194e3752, 0x08233a95, 0x0f38fe36, 0x29c7cd57,
1191 0x0f7b3a39, 0x328e8a16, 0x1e7d1388, 0x0fba78f5, 0x274c7e7c, 0x1e8be65c, 0x2fa0b0bb, 0x1eb6c371,
1192];
1193
1194pub fn colored_uci(uci: &Uci, nag: &Option<Nag>, recommendation: u8) -> String {
1209 let is_question_mark = nag.map(|n| n.is_question_mark()).unwrap_or(false);
1210
1211 match recommendation {
1212 0xa4 => style(uci.to_string()).green().to_string(),
1213 0x80 => {
1214 if is_question_mark {
1215 style(uci.to_string()).blue().to_string()
1216 } else {
1217 style(uci.to_string()).green().to_string()
1218 }
1219 }
1220 0x40 => style(uci.to_string()).red().to_string(),
1221 _ => uci.to_string(),
1222 }
1223}
1224
1225#[inline(always)]
1239pub fn gen_hash(ptr: &[i8], len: usize) -> i32 {
1240 let mut hash: i32 = 0;
1241 let mut tmp: i16 = 0;
1242
1243 for ch in ptr.iter().take(len) {
1244 let ch = i16::from(*ch);
1245 tmp += ((0x0f - (ch & 0x0f)) << 2) + 1;
1246 hash = hash.wrapping_add(TBL2[(tmp & 0x3f) as usize] as i32);
1247 tmp += ((0xf0 - (ch & 0xf0)) >> 2) + 1;
1248 hash = hash.wrapping_add(TBL2[(tmp & 0x3f) as usize] as i32);
1249 }
1250
1251 hash
1252}
1253
1254pub struct MoveEnc {
1260 pub encoding: u8,
1262 pub piece: char,
1264 pub num: i32,
1266 pub forward: i32,
1268 pub right: i32,
1270}
1271
1272pub const MOVETABLE_MAX: usize = 166;
1274
1275pub static MOVETABLE: [MoveEnc; MOVETABLE_MAX] = [
1280 MoveEnc {
1281 encoding: 0x00,
1282 piece: 'P',
1283 num: 5,
1284 forward: 1,
1285 right: 1,
1286 },
1287 MoveEnc {
1288 encoding: 0x01,
1289 piece: 'N',
1290 num: 2,
1291 forward: -1,
1292 right: -2,
1293 },
1294 MoveEnc {
1295 encoding: 0x03,
1296 piece: 'Q',
1297 num: 2,
1298 forward: 0,
1299 right: 2,
1300 },
1301 MoveEnc {
1302 encoding: 0x04,
1303 piece: 'P',
1304 num: 2,
1305 forward: 1,
1306 right: 0,
1307 },
1308 MoveEnc {
1309 encoding: 0x05,
1310 piece: 'Q',
1311 num: 1,
1312 forward: 1,
1313 right: 0,
1314 },
1315 MoveEnc {
1316 encoding: 0x06,
1317 piece: 'P',
1318 num: 4,
1319 forward: 1,
1320 right: -1,
1321 },
1322 MoveEnc {
1323 encoding: 0x08,
1324 piece: 'Q',
1325 num: 2,
1326 forward: 0,
1327 right: 4,
1328 },
1329 MoveEnc {
1330 encoding: 0x09,
1331 piece: 'B',
1332 num: 2,
1333 forward: 6,
1334 right: 6,
1335 },
1336 MoveEnc {
1337 encoding: 0x0a,
1338 piece: 'K',
1339 num: 1,
1340 forward: -1,
1341 right: 0,
1342 },
1343 MoveEnc {
1344 encoding: 0x0c,
1345 piece: 'P',
1346 num: 1,
1347 forward: 1,
1348 right: -1,
1349 },
1350 MoveEnc {
1351 encoding: 0x0d,
1352 piece: 'B',
1353 num: 1,
1354 forward: 3,
1355 right: 3,
1356 },
1357 MoveEnc {
1358 encoding: 0x0e,
1359 piece: 'R',
1360 num: 2,
1361 forward: 0,
1362 right: 3,
1363 },
1364 MoveEnc {
1365 encoding: 0x0f,
1366 piece: 'N',
1367 num: 1,
1368 forward: -1,
1369 right: -2,
1370 },
1371 MoveEnc {
1372 encoding: 0x12,
1373 piece: 'B',
1374 num: 1,
1375 forward: 7,
1376 right: 7,
1377 },
1378 MoveEnc {
1379 encoding: 0x13,
1380 piece: 'K',
1381 num: 1,
1382 forward: 1,
1383 right: 0,
1384 },
1385 MoveEnc {
1386 encoding: 0x14,
1387 piece: 'P',
1388 num: 8,
1389 forward: 1,
1390 right: 1,
1391 },
1392 MoveEnc {
1393 encoding: 0x15,
1394 piece: 'B',
1395 num: 1,
1396 forward: 5,
1397 right: 5,
1398 },
1399 MoveEnc {
1400 encoding: 0x18,
1401 piece: 'P',
1402 num: 7,
1403 forward: 1,
1404 right: 0,
1405 },
1406 MoveEnc {
1407 encoding: 0x1a,
1408 piece: 'Q',
1409 num: 2,
1410 forward: 6,
1411 right: 0,
1412 },
1413 MoveEnc {
1414 encoding: 0x1b,
1415 piece: 'B',
1416 num: 1,
1417 forward: 1,
1418 right: -1,
1419 },
1420 MoveEnc {
1421 encoding: 0x1d,
1422 piece: 'B',
1423 num: 2,
1424 forward: 7,
1425 right: 7,
1426 },
1427 MoveEnc {
1428 encoding: 0x21,
1429 piece: 'R',
1430 num: 2,
1431 forward: 0,
1432 right: 7,
1433 },
1434 MoveEnc {
1435 encoding: 0x22,
1436 piece: 'B',
1437 num: 2,
1438 forward: 2,
1439 right: -2,
1440 },
1441 MoveEnc {
1442 encoding: 0x23,
1443 piece: 'Q',
1444 num: 2,
1445 forward: 6,
1446 right: 6,
1447 },
1448 MoveEnc {
1449 encoding: 0x24,
1450 piece: 'P',
1451 num: 8,
1452 forward: 1,
1453 right: -1,
1454 },
1455 MoveEnc {
1456 encoding: 0x26,
1457 piece: 'B',
1458 num: 1,
1459 forward: 7,
1460 right: -7,
1461 },
1462 MoveEnc {
1463 encoding: 0x27,
1464 piece: 'P',
1465 num: 3,
1466 forward: 1,
1467 right: -1,
1468 },
1469 MoveEnc {
1470 encoding: 0x28,
1471 piece: 'Q',
1472 num: 1,
1473 forward: 5,
1474 right: 5,
1475 },
1476 MoveEnc {
1477 encoding: 0x29,
1478 piece: 'Q',
1479 num: 1,
1480 forward: 0,
1481 right: 6,
1482 },
1483 MoveEnc {
1484 encoding: 0x2a,
1485 piece: 'N',
1486 num: 2,
1487 forward: -2,
1488 right: 1,
1489 },
1490 MoveEnc {
1491 encoding: 0x2d,
1492 piece: 'P',
1493 num: 6,
1494 forward: 1,
1495 right: 1,
1496 },
1497 MoveEnc {
1498 encoding: 0x2e,
1499 piece: 'B',
1500 num: 1,
1501 forward: 1,
1502 right: 1,
1503 },
1504 MoveEnc {
1505 encoding: 0x2f,
1506 piece: 'Q',
1507 num: 1,
1508 forward: 0,
1509 right: 1,
1510 },
1511 MoveEnc {
1512 encoding: 0x30,
1513 piece: 'N',
1514 num: 2,
1515 forward: -2,
1516 right: -1,
1517 },
1518 MoveEnc {
1519 encoding: 0x31,
1520 piece: 'Q',
1521 num: 1,
1522 forward: 0,
1523 right: 3,
1524 },
1525 MoveEnc {
1526 encoding: 0x32,
1527 piece: 'B',
1528 num: 2,
1529 forward: 5,
1530 right: 5,
1531 },
1532 MoveEnc {
1533 encoding: 0x34,
1534 piece: 'N',
1535 num: 1,
1536 forward: 2,
1537 right: 1,
1538 },
1539 MoveEnc {
1540 encoding: 0x36,
1541 piece: 'N',
1542 num: 1,
1543 forward: 1,
1544 right: 2,
1545 },
1546 MoveEnc {
1547 encoding: 0x37,
1548 piece: 'Q',
1549 num: 1,
1550 forward: 4,
1551 right: 0,
1552 },
1553 MoveEnc {
1554 encoding: 0x38,
1555 piece: 'Q',
1556 num: 2,
1557 forward: 4,
1558 right: -4,
1559 },
1560 MoveEnc {
1561 encoding: 0x39,
1562 piece: 'Q',
1563 num: 1,
1564 forward: 0,
1565 right: 5,
1566 },
1567 MoveEnc {
1568 encoding: 0x3a,
1569 piece: 'B',
1570 num: 1,
1571 forward: 6,
1572 right: 6,
1573 },
1574 MoveEnc {
1575 encoding: 0x3b,
1576 piece: 'Q',
1577 num: 2,
1578 forward: 5,
1579 right: -5,
1580 },
1581 MoveEnc {
1582 encoding: 0x3c,
1583 piece: 'B',
1584 num: 1,
1585 forward: 5,
1586 right: -5,
1587 },
1588 MoveEnc {
1589 encoding: 0x41,
1590 piece: 'Q',
1591 num: 2,
1592 forward: 5,
1593 right: 5,
1594 },
1595 MoveEnc {
1596 encoding: 0x42,
1597 piece: 'Q',
1598 num: 1,
1599 forward: 7,
1600 right: -7,
1601 },
1602 MoveEnc {
1603 encoding: 0x44,
1604 piece: 'K',
1605 num: 1,
1606 forward: -1,
1607 right: 1,
1608 },
1609 MoveEnc {
1610 encoding: 0x45,
1611 piece: 'Q',
1612 num: 1,
1613 forward: 3,
1614 right: 3,
1615 },
1616 MoveEnc {
1617 encoding: 0x4a,
1618 piece: 'P',
1619 num: 8,
1620 forward: 2,
1621 right: 0,
1622 },
1623 MoveEnc {
1624 encoding: 0x4b,
1625 piece: 'Q',
1626 num: 1,
1627 forward: 5,
1628 right: -5,
1629 },
1630 MoveEnc {
1631 encoding: 0x4c,
1632 piece: 'N',
1633 num: 2,
1634 forward: 2,
1635 right: 1,
1636 },
1637 MoveEnc {
1638 encoding: 0x4d,
1639 piece: 'Q',
1640 num: 2,
1641 forward: 1,
1642 right: 0,
1643 },
1644 MoveEnc {
1645 encoding: 0x50,
1646 piece: 'R',
1647 num: 1,
1648 forward: 6,
1649 right: 0,
1650 },
1651 MoveEnc {
1652 encoding: 0x52,
1653 piece: 'R',
1654 num: 1,
1655 forward: 0,
1656 right: 6,
1657 },
1658 MoveEnc {
1659 encoding: 0x54,
1660 piece: 'B',
1661 num: 2,
1662 forward: 1,
1663 right: -1,
1664 },
1665 MoveEnc {
1666 encoding: 0x55,
1667 piece: 'P',
1668 num: 3,
1669 forward: 1,
1670 right: 0,
1671 },
1672 MoveEnc {
1673 encoding: 0x5c,
1674 piece: 'P',
1675 num: 7,
1676 forward: 1,
1677 right: 1,
1678 },
1679 MoveEnc {
1680 encoding: 0x5f,
1681 piece: 'P',
1682 num: 5,
1683 forward: 2,
1684 right: 0,
1685 },
1686 MoveEnc {
1687 encoding: 0x61,
1688 piece: 'Q',
1689 num: 1,
1690 forward: 6,
1691 right: 6,
1692 },
1693 MoveEnc {
1694 encoding: 0x62,
1695 piece: 'P',
1696 num: 2,
1697 forward: 2,
1698 right: 0,
1699 },
1700 MoveEnc {
1701 encoding: 0x63,
1702 piece: 'Q',
1703 num: 2,
1704 forward: 7,
1705 right: -7,
1706 },
1707 MoveEnc {
1708 encoding: 0x66,
1709 piece: 'B',
1710 num: 1,
1711 forward: 3,
1712 right: -3,
1713 },
1714 MoveEnc {
1715 encoding: 0x67,
1716 piece: 'K',
1717 num: 1,
1718 forward: 1,
1719 right: 1,
1720 },
1721 MoveEnc {
1722 encoding: 0x69,
1723 piece: 'R',
1724 num: 2,
1725 forward: 7,
1726 right: 0,
1727 },
1728 MoveEnc {
1729 encoding: 0x6a,
1730 piece: 'B',
1731 num: 1,
1732 forward: 4,
1733 right: 4,
1734 },
1735 MoveEnc {
1736 encoding: 0x6b,
1738 piece: 'K',
1739 num: 1,
1740 forward: 0,
1741 right: 2,
1742 },
1743 MoveEnc {
1744 encoding: 0x6e,
1745 piece: 'R',
1746 num: 1,
1747 forward: 0,
1748 right: 5,
1749 },
1750 MoveEnc {
1751 encoding: 0x6f,
1752 piece: 'Q',
1753 num: 2,
1754 forward: 7,
1755 right: 7,
1756 },
1757 MoveEnc {
1758 encoding: 0x72,
1759 piece: 'B',
1760 num: 2,
1761 forward: 7,
1762 right: -7,
1763 },
1764 MoveEnc {
1765 encoding: 0x74,
1766 piece: 'Q',
1767 num: 1,
1768 forward: 0,
1769 right: 2,
1770 },
1771 MoveEnc {
1772 encoding: 0x79,
1773 piece: 'B',
1774 num: 2,
1775 forward: 6,
1776 right: -6,
1777 },
1778 MoveEnc {
1779 encoding: 0x7a,
1780 piece: 'R',
1781 num: 1,
1782 forward: 3,
1783 right: 0,
1784 },
1785 MoveEnc {
1786 encoding: 0x7b,
1787 piece: 'R',
1788 num: 2,
1789 forward: 6,
1790 right: 0,
1791 },
1792 MoveEnc {
1793 encoding: 0x7c,
1794 piece: 'P',
1795 num: 3,
1796 forward: 1,
1797 right: 1,
1798 },
1799 MoveEnc {
1800 encoding: 0x7d,
1801 piece: 'R',
1802 num: 2,
1803 forward: 1,
1804 right: 0,
1805 },
1806 MoveEnc {
1807 encoding: 0x7e,
1808 piece: 'Q',
1809 num: 1,
1810 forward: 3,
1811 right: -3,
1812 },
1813 MoveEnc {
1814 encoding: 0x7f,
1815 piece: 'R',
1816 num: 1,
1817 forward: 0,
1818 right: 1,
1819 },
1820 MoveEnc {
1821 encoding: 0x80,
1822 piece: 'Q',
1823 num: 1,
1824 forward: 6,
1825 right: -6,
1826 },
1827 MoveEnc {
1828 encoding: 0x81,
1829 piece: 'R',
1830 num: 1,
1831 forward: 1,
1832 right: 0,
1833 },
1834 MoveEnc {
1835 encoding: 0x82,
1836 piece: 'P',
1837 num: 6,
1838 forward: 1,
1839 right: -1,
1840 },
1841 MoveEnc {
1842 encoding: 0x85,
1843 piece: 'N',
1844 num: 1,
1845 forward: 2,
1846 right: -1,
1847 },
1848 MoveEnc {
1849 encoding: 0x86,
1850 piece: 'R',
1851 num: 1,
1852 forward: 0,
1853 right: 7,
1854 },
1855 MoveEnc {
1856 encoding: 0x87,
1857 piece: 'R',
1858 num: 1,
1859 forward: 5,
1860 right: 0,
1861 },
1862 MoveEnc {
1863 encoding: 0x8a,
1864 piece: 'N',
1865 num: 1,
1866 forward: -2,
1867 right: 1,
1868 },
1869 MoveEnc {
1870 encoding: 0x8b,
1871 piece: 'P',
1872 num: 1,
1873 forward: 1,
1874 right: 1,
1875 },
1876 MoveEnc {
1877 encoding: 0x8c,
1878 piece: 'K',
1879 num: 1,
1880 forward: -1,
1881 right: -1,
1882 },
1883 MoveEnc {
1884 encoding: 0x8e,
1885 piece: 'Q',
1886 num: 2,
1887 forward: 2,
1888 right: -2,
1889 },
1890 MoveEnc {
1891 encoding: 0x8f,
1892 piece: 'Q',
1893 num: 1,
1894 forward: 0,
1895 right: 7,
1896 },
1897 MoveEnc {
1898 encoding: 0x92,
1899 piece: 'Q',
1900 num: 2,
1901 forward: 1,
1902 right: 1,
1903 },
1904 MoveEnc {
1905 encoding: 0x94,
1906 piece: 'Q',
1907 num: 1,
1908 forward: 3,
1909 right: 0,
1910 },
1911 MoveEnc {
1912 encoding: 0x96,
1913 piece: 'P',
1914 num: 2,
1915 forward: 1,
1916 right: 1,
1917 },
1918 MoveEnc {
1919 encoding: 0x97,
1920 piece: 'K',
1921 num: 1,
1922 forward: 0,
1923 right: -1,
1924 },
1925 MoveEnc {
1926 encoding: 0x98,
1927 piece: 'R',
1928 num: 1,
1929 forward: 0,
1930 right: 3,
1931 },
1932 MoveEnc {
1933 encoding: 0x99,
1934 piece: 'R',
1935 num: 1,
1936 forward: 4,
1937 right: 0,
1938 },
1939 MoveEnc {
1940 encoding: 0x9a,
1941 piece: 'Q',
1942 num: 1,
1943 forward: 6,
1944 right: 0,
1945 },
1946 MoveEnc {
1947 encoding: 0x9b,
1948 piece: 'P',
1949 num: 3,
1950 forward: 2,
1951 right: 0,
1952 },
1953 MoveEnc {
1954 encoding: 0x9d,
1955 piece: 'Q',
1956 num: 1,
1957 forward: 2,
1958 right: 0,
1959 },
1960 MoveEnc {
1961 encoding: 0x9f,
1962 piece: 'B',
1963 num: 2,
1964 forward: 4,
1965 right: -4,
1966 },
1967 MoveEnc {
1968 encoding: 0xa0,
1969 piece: 'Q',
1970 num: 2,
1971 forward: 3,
1972 right: 0,
1973 },
1974 MoveEnc {
1975 encoding: 0xa2,
1976 piece: 'Q',
1977 num: 1,
1978 forward: 2,
1979 right: 2,
1980 },
1981 MoveEnc {
1982 encoding: 0xa3,
1983 piece: 'P',
1984 num: 8,
1985 forward: 1,
1986 right: 0,
1987 },
1988 MoveEnc {
1989 encoding: 0xa5,
1990 piece: 'R',
1991 num: 2,
1992 forward: 5,
1993 right: 0,
1994 },
1995 MoveEnc {
1996 encoding: 0xa9,
1997 piece: 'R',
1998 num: 2,
1999 forward: 0,
2000 right: 2,
2001 },
2002 MoveEnc {
2003 encoding: 0xab,
2004 piece: 'Q',
2005 num: 2,
2006 forward: 6,
2007 right: -6,
2008 },
2009 MoveEnc {
2010 encoding: 0xad,
2011 piece: 'R',
2012 num: 2,
2013 forward: 0,
2014 right: 4,
2015 },
2016 MoveEnc {
2017 encoding: 0xae,
2018 piece: 'Q',
2019 num: 2,
2020 forward: 3,
2021 right: 3,
2022 },
2023 MoveEnc {
2024 encoding: 0xb0,
2025 piece: 'Q',
2026 num: 2,
2027 forward: 4,
2028 right: 0,
2029 },
2030 MoveEnc {
2031 encoding: 0xb1,
2032 piece: 'P',
2033 num: 6,
2034 forward: 2,
2035 right: 0,
2036 },
2037 MoveEnc {
2038 encoding: 0xb2,
2039 piece: 'B',
2040 num: 1,
2041 forward: 6,
2042 right: -6,
2043 },
2044 MoveEnc {
2045 encoding: 0xb5,
2046 piece: 'R',
2047 num: 2,
2048 forward: 0,
2049 right: 5,
2050 },
2051 MoveEnc {
2052 encoding: 0xb7,
2053 piece: 'Q',
2054 num: 1,
2055 forward: 5,
2056 right: 0,
2057 },
2058 MoveEnc {
2059 encoding: 0xb9,
2060 piece: 'B',
2061 num: 2,
2062 forward: 3,
2063 right: 3,
2064 },
2065 MoveEnc {
2066 encoding: 0xbb,
2067 piece: 'P',
2068 num: 5,
2069 forward: 1,
2070 right: 0,
2071 },
2072 MoveEnc {
2073 encoding: 0xbc,
2074 piece: 'Q',
2075 num: 2,
2076 forward: 0,
2077 right: 5,
2078 },
2079 MoveEnc {
2080 encoding: 0xbd,
2081 piece: 'Q',
2082 num: 2,
2083 forward: 2,
2084 right: 0,
2085 },
2086 MoveEnc {
2087 encoding: 0xbe,
2088 piece: 'K',
2089 num: 1,
2090 forward: 0,
2091 right: 1,
2092 },
2093 MoveEnc {
2094 encoding: 0xc1,
2095 piece: 'B',
2096 num: 1,
2097 forward: 2,
2098 right: 2,
2099 },
2100 MoveEnc {
2101 encoding: 0xc2,
2102 piece: 'B',
2103 num: 2,
2104 forward: 2,
2105 right: 2,
2106 },
2107 MoveEnc {
2108 encoding: 0xc3,
2109 piece: 'B',
2110 num: 1,
2111 forward: 2,
2112 right: -2,
2113 },
2114 MoveEnc {
2115 encoding: 0xc4,
2116 piece: 'R',
2117 num: 2,
2118 forward: 0,
2119 right: 1,
2120 },
2121 MoveEnc {
2122 encoding: 0xc5,
2123 piece: 'R',
2124 num: 2,
2125 forward: 4,
2126 right: 0,
2127 },
2128 MoveEnc {
2129 encoding: 0xc6,
2130 piece: 'Q',
2131 num: 2,
2132 forward: 5,
2133 right: 0,
2134 },
2135 MoveEnc {
2136 encoding: 0xc7,
2137 piece: 'P',
2138 num: 7,
2139 forward: 1,
2140 right: -1,
2141 },
2142 MoveEnc {
2143 encoding: 0xc8,
2144 piece: 'P',
2145 num: 7,
2146 forward: 2,
2147 right: 0,
2148 },
2149 MoveEnc {
2150 encoding: 0xc9,
2151 piece: 'Q',
2152 num: 2,
2153 forward: 7,
2154 right: 0,
2155 },
2156 MoveEnc {
2157 encoding: 0xca,
2158 piece: 'B',
2159 num: 2,
2160 forward: 3,
2161 right: -3,
2162 },
2163 MoveEnc {
2164 encoding: 0xcb,
2165 piece: 'P',
2166 num: 6,
2167 forward: 1,
2168 right: 0,
2169 },
2170 MoveEnc {
2171 encoding: 0xcc,
2172 piece: 'B',
2173 num: 2,
2174 forward: 5,
2175 right: -5,
2176 },
2177 MoveEnc {
2178 encoding: 0xcd,
2179 piece: 'R',
2180 num: 1,
2181 forward: 0,
2182 right: 2,
2183 },
2184 MoveEnc {
2185 encoding: 0xcf,
2186 piece: 'P',
2187 num: 4,
2188 forward: 1,
2189 right: 0,
2190 },
2191 MoveEnc {
2192 encoding: 0xd1,
2193 piece: 'P',
2194 num: 2,
2195 forward: 1,
2196 right: -1,
2197 },
2198 MoveEnc {
2199 encoding: 0xd2,
2200 piece: 'N',
2201 num: 2,
2202 forward: 1,
2203 right: 2,
2204 },
2205 MoveEnc {
2206 encoding: 0xd3,
2207 piece: 'N',
2208 num: 2,
2209 forward: 1,
2210 right: -2,
2211 },
2212 MoveEnc {
2213 encoding: 0xd7,
2214 piece: 'Q',
2215 num: 1,
2216 forward: 1,
2217 right: -1,
2218 },
2219 MoveEnc {
2220 encoding: 0xd8,
2221 piece: 'R',
2222 num: 2,
2223 forward: 0,
2224 right: 6,
2225 },
2226 MoveEnc {
2227 encoding: 0xd9,
2228 piece: 'Q',
2229 num: 1,
2230 forward: 2,
2231 right: -2,
2232 },
2233 MoveEnc {
2234 encoding: 0xda,
2235 piece: 'N',
2236 num: 1,
2237 forward: -2,
2238 right: -1,
2239 },
2240 MoveEnc {
2241 encoding: 0xdb,
2242 piece: 'P',
2243 num: 1,
2244 forward: 2,
2245 right: 0,
2246 },
2247 MoveEnc {
2248 encoding: 0xde,
2249 piece: 'P',
2250 num: 5,
2251 forward: 1,
2252 right: -1,
2253 },
2254 MoveEnc {
2255 encoding: 0xdf,
2256 piece: 'K',
2257 num: 1,
2258 forward: 1,
2259 right: -1,
2260 },
2261 MoveEnc {
2262 encoding: 0xe0,
2263 piece: 'N',
2264 num: 2,
2265 forward: -1,
2266 right: 2,
2267 },
2268 MoveEnc {
2269 encoding: 0xe1,
2270 piece: 'R',
2271 num: 1,
2272 forward: 7,
2273 right: 0,
2274 },
2275 MoveEnc {
2276 encoding: 0xe3,
2277 piece: 'R',
2278 num: 2,
2279 forward: 3,
2280 right: 0,
2281 },
2282 MoveEnc {
2283 encoding: 0xe5,
2284 piece: 'Q',
2285 num: 1,
2286 forward: 0,
2287 right: 4,
2288 },
2289 MoveEnc {
2290 encoding: 0xe6,
2291 piece: 'P',
2292 num: 4,
2293 forward: 2,
2294 right: 0,
2295 },
2296 MoveEnc {
2297 encoding: 0xe7,
2298 piece: 'Q',
2299 num: 1,
2300 forward: 4,
2301 right: 4,
2302 },
2303 MoveEnc {
2304 encoding: 0xe8,
2305 piece: 'R',
2306 num: 1,
2307 forward: 2,
2308 right: 0,
2309 },
2310 MoveEnc {
2311 encoding: 0xe9,
2312 piece: 'N',
2313 num: 1,
2314 forward: -1,
2315 right: 2,
2316 },
2317 MoveEnc {
2318 encoding: 0xeb,
2319 piece: 'P',
2320 num: 4,
2321 forward: 1,
2322 right: 1,
2323 },
2324 MoveEnc {
2325 encoding: 0xec,
2326 piece: 'P',
2327 num: 1,
2328 forward: 1,
2329 right: 0,
2330 },
2331 MoveEnc {
2332 encoding: 0xed,
2333 piece: 'Q',
2334 num: 1,
2335 forward: 7,
2336 right: 7,
2337 },
2338 MoveEnc {
2339 encoding: 0xee,
2340 piece: 'Q',
2341 num: 2,
2342 forward: 1,
2343 right: -1,
2344 },
2345 MoveEnc {
2346 encoding: 0xef,
2347 piece: 'R',
2348 num: 1,
2349 forward: 0,
2350 right: 4,
2351 },
2352 MoveEnc {
2353 encoding: 0xf0,
2354 piece: 'Q',
2355 num: 2,
2356 forward: 0,
2357 right: 7,
2358 },
2359 MoveEnc {
2360 encoding: 0xf1,
2361 piece: 'Q',
2362 num: 1,
2363 forward: 1,
2364 right: 1,
2365 },
2366 MoveEnc {
2367 encoding: 0xf3,
2368 piece: 'N',
2369 num: 2,
2370 forward: 2,
2371 right: -1,
2372 },
2373 MoveEnc {
2374 encoding: 0xf4,
2375 piece: 'R',
2376 num: 2,
2377 forward: 2,
2378 right: 0,
2379 },
2380 MoveEnc {
2381 encoding: 0xf5,
2382 piece: 'B',
2383 num: 2,
2384 forward: 1,
2385 right: 1,
2386 },
2387 MoveEnc {
2388 encoding: 0xf6,
2390 piece: 'K',
2391 num: 1,
2392 forward: 0,
2393 right: -2,
2394 },
2395 MoveEnc {
2396 encoding: 0xf7,
2397 piece: 'N',
2398 num: 1,
2399 forward: 1,
2400 right: -2,
2401 },
2402 MoveEnc {
2403 encoding: 0xf8,
2404 piece: 'Q',
2405 num: 2,
2406 forward: 0,
2407 right: 1,
2408 },
2409 MoveEnc {
2410 encoding: 0xf9,
2411 piece: 'Q',
2412 num: 2,
2413 forward: 6,
2414 right: 0,
2415 },
2416 MoveEnc {
2417 encoding: 0xfa,
2418 piece: 'Q',
2419 num: 2,
2420 forward: 0,
2421 right: 3,
2422 },
2423 MoveEnc {
2424 encoding: 0xfb,
2425 piece: 'Q',
2426 num: 2,
2427 forward: 2,
2428 right: 2,
2429 },
2430 MoveEnc {
2431 encoding: 0xfd,
2432 piece: 'Q',
2433 num: 1,
2434 forward: 7,
2435 right: 0,
2436 },
2437 MoveEnc {
2438 encoding: 0xfe,
2439 piece: 'Q',
2440 num: 2,
2441 forward: 3,
2442 right: -3,
2443 },
2444];
2445
2446#[cfg(test)]
2447mod tests {
2448 use shakmaty::*;
2449
2450 use super::*;
2451
2452 #[test]
2453 fn test_byteboard_from_board() {
2454 let pos = Chess::default();
2455 let epd = format!(
2456 "{}",
2457 shakmaty::fen::Epd::from_position(pos.clone(), EnPassantMode::PseudoLegal)
2458 );
2459 let bb0 = ByteBoard::from_fen(epd.as_bytes()).expect("invalid fen");
2460 let bb1 = ByteBoard::from_board(&pos.board());
2461
2462 assert_eq!(bb0, bb1);
2463 }
2464}