aboutsummaryrefslogtreecommitdiff
path: root/src/cube.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-11-01 19:26:09 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2023-11-01 19:26:09 +0100
commit08efbd62ef956327924aaea1fcfa97fde4dc1678 (patch)
tree656d9f6ab50eee73a6e7fd79098e0dcfa1fc9034 /src/cube.c
parentd65ce8e86b517ef3f7d48cf5ded1101444e05b2b (diff)
downloadnissy-core-08efbd62ef956327924aaea1fcfa97fde4dc1678.tar.gz
nissy-core-08efbd62ef956327924aaea1fcfa97fde4dc1678.zip
Reworked moves and transformations, moved some stuff
Diffstat (limited to 'src/cube.c')
-rw-r--r--src/cube.c438
1 files changed, 375 insertions, 63 deletions
diff --git a/src/cube.c b/src/cube.c
index fc04ee7..bb36447 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -2,17 +2,121 @@
2#include <stdbool.h> 2#include <stdbool.h>
3#include <string.h> 3#include <string.h>
4 4
5#ifdef CUBE_AVX2
6#include <immintrin.h>
7#endif
8
9#ifdef DEBUG 5#ifdef DEBUG
10#include <stdio.h> 6#include <stdio.h>
11#endif 7#endif
12 8
9#ifdef AVX2
10#include <immintrin.h>
11#endif
12
13#include "cube.h" 13#include "cube.h"
14 14
15#include "_constants.c" 15#define U 0U
16#define U2 1U
17#define U3 2U
18#define D 3U
19#define D2 4U
20#define D3 5U
21#define R 6U
22#define R2 7U
23#define R3 8U
24#define L 9U
25#define L2 10U
26#define L3 11U
27#define F 12U
28#define F2 13U
29#define F3 14U
30#define B 15U
31#define B2 16U
32#define B3 17U
33
34#define UFr 0
35#define ULr 1
36#define UBr 2
37#define URr 3
38#define DFr 4
39#define DLr 5
40#define DBr 6
41#define DRr 7
42#define RUr 8
43#define RFr 9
44#define RDr 10
45#define RBr 11
46#define LUr 12
47#define LFr 13
48#define LDr 14
49#define LBr 15
50#define FUr 16
51#define FRr 17
52#define FDr 18
53#define FLr 19
54#define BUr 20
55#define BRr 21
56#define BDr 22
57#define BLr 23
58
59#define UFm 24
60#define ULm 25
61#define UBm 26
62#define URm 27
63#define DFm 28
64#define DLm 29
65#define DBm 30
66#define DRm 31
67#define RUm 32
68#define RFm 33
69#define RDm 34
70#define RBm 35
71#define LUm 36
72#define LFm 37
73#define LDm 38
74#define LBm 39
75#define FUm 40
76#define FRm 41
77#define FDm 42
78#define FLm 43
79#define BUm 44
80#define BRm 45
81#define BDm 46
82#define BLm 47
83
84#define errormove 99U
85#define errortrans 99U
86
87#define _c_ufr 0U
88#define _c_ubl 1U
89#define _c_dfl 2U
90#define _c_dbr 3U
91#define _c_ufl 4U
92#define _c_ubr 5U
93#define _c_dfr 6U
94#define _c_dbl 7U
95
96#define _e_uf 0U
97#define _e_ub 1U
98#define _e_db 2U
99#define _e_df 3U
100#define _e_ur 4U
101#define _e_ul 5U
102#define _e_dl 6U
103#define _e_dr 7U
104#define _e_fr 8U
105#define _e_fl 9U
106#define _e_bl 10U
107#define _e_br 11U
108
109#define _eoshift 4U
110#define _coshift 5U
111
112#define _pbits 0xFU
113#define _eobit 0x10U
114#define _cobits 0xF0U
115#define _cobits2 0x60U
116#define _ctwist_cw 0x20U
117#define _ctwist_ccw 0x40U
118#define _eflip 0x10U
119#define _error 0xFFU
16 120
17cube_arr_t solvedcube_arr = { 121cube_arr_t solvedcube_arr = {
18 .c = {0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0}, 122 .c = {0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0},
@@ -36,18 +140,133 @@ cube_arr_t zerocube_arr = { .e = {0}, .c = {0} };
36 _mm256_andnot_si256(cube, _mm256_slli_si256(_c, 0)), \ 140 _mm256_andnot_si256(cube, _mm256_slli_si256(_c, 0)), \
37 _mm256_and_si256(_mm256_set1_epi8(p), _mm256_slli_si256(_c, 0))) 141 _mm256_and_si256(_mm256_set1_epi8(p), _mm256_slli_si256(_c, 0)))
38 142
143#include "_moves_avx2.c"
144#include "_trans_avx2.c"
145
39#else 146#else
40 147
41#define setsolved(cube) cube = solvedcube_arr 148#define setsolved(cube) cube = solvedcube_arr
42#define setzero(cube) cube = zerocube_arr 149#define setzero(cube) cube = zerocube_arr
43#define _c _mm256_set_epi64x(0, 0, 0, 0xFF)
44#define get_edge(cube, i) (cube).e[(i)] 150#define get_edge(cube, i) (cube).e[(i)]
45#define get_corner(cube, i) (cube).c[(i)] 151#define get_corner(cube, i) (cube).c[(i)]
46#define set_edge(cube, i, p) (cube).e[(i)] = (p) 152#define set_edge(cube, i, p) (cube).e[(i)] = (p)
47#define set_corner(cube, i, p) (cube).c[(i)] = (p) 153#define set_corner(cube, i, p) (cube).c[(i)] = (p)
48 154
155#include "_moves_arr.c"
156#include "_trans_arr.c"
157
49#endif 158#endif
50 159
160
161static char *cornerstr[] = {
162 [_c_ufr] = "UFR",
163 [_c_ubl] = "UBL",
164 [_c_dfl] = "DFL",
165 [_c_dbr] = "DBR",
166 [_c_ufl] = "UFL",
167 [_c_ubr] = "UBR",
168 [_c_dfr] = "DFR",
169 [_c_dbl] = "DBL"
170};
171
172static char *cornerstralt[] = {
173 [_c_ufr] = "URF",
174 [_c_ubl] = "ULB",
175 [_c_dfl] = "DLF",
176 [_c_dbr] = "DRB",
177 [_c_ufl] = "ULF",
178 [_c_ubr] = "URB",
179 [_c_dfr] = "DRF",
180 [_c_dbl] = "DLB"
181};
182
183static char *edgestr[] = {
184 [_e_uf] = "UF",
185 [_e_ub] = "UB",
186 [_e_db] = "DB",
187 [_e_df] = "DF",
188 [_e_ur] = "UR",
189 [_e_ul] = "UL",
190 [_e_dl] = "DL",
191 [_e_dr] = "DR",
192 [_e_fr] = "FR",
193 [_e_fl] = "FL",
194 [_e_bl] = "BL",
195 [_e_br] = "BR"
196};
197
198static char *movestr[] = {
199 [U] = "U",
200 [U2] = "U2",
201 [U3] = "U'",
202 [D] = "D",
203 [D2] = "D2",
204 [D3] = "D'",
205 [R] = "R",
206 [R2] = "R2",
207 [R3] = "R'",
208 [L] = "L",
209 [L2] = "L2",
210 [L3] = "L'",
211 [F] = "F",
212 [F2] = "F2",
213 [F3] = "F'",
214 [B] = "B",
215 [B2] = "B2",
216 [B3] = "B'",
217};
218
219static char *transstr[] = {
220 [UFr] = "rotation UF",
221 [UFm] = "mirrored UF",
222 [ULr] = "rotation UL",
223 [ULm] = "mirrored UL",
224 [UBr] = "rotation UB",
225 [UBm] = "mirrored UB",
226 [URr] = "rotation UR",
227 [URm] = "mirrored UR",
228 [DFr] = "rotation DF",
229 [DFm] = "mirrored DF",
230 [DLr] = "rotation DL",
231 [DLm] = "mirrored DL",
232 [DBr] = "rotation DB",
233 [DBm] = "mirrored DB",
234 [DRr] = "rotation DR",
235 [DRm] = "mirrored DR",
236 [RUr] = "rotation RU",
237 [RUm] = "mirrored RU",
238 [RFr] = "rotation RF",
239 [RFm] = "mirrored RF",
240 [RDr] = "rotation RD",
241 [RDm] = "mirrored RD",
242 [RBr] = "rotation RB",
243 [RBm] = "mirrored RB",
244 [LUr] = "rotation LU",
245 [LUm] = "mirrored LU",
246 [LFr] = "rotation LF",
247 [LFm] = "mirrored LF",
248 [LDr] = "rotation LD",
249 [LDm] = "mirrored LD",
250 [LBr] = "rotation LB",
251 [LBm] = "mirrored LB",
252 [FUr] = "rotation FU",
253 [FUm] = "mirrored FU",
254 [FRr] = "rotation FR",
255 [FRm] = "mirrored FR",
256 [FDr] = "rotation FD",
257 [FDm] = "mirrored FD",
258 [FLr] = "rotation FL",
259 [FLm] = "mirrored FL",
260 [BUr] = "rotation BU",
261 [BUm] = "mirrored BU",
262 [BRr] = "rotation BR",
263 [BRm] = "mirrored BR",
264 [BDr] = "rotation BD",
265 [BDm] = "mirrored BD",
266 [BLr] = "rotation BL",
267 [BLm] = "mirrored BL",
268};
269
51static bool isconsistent(cube_t); 270static bool isconsistent(cube_t);
52static cube_t flipallcorners(cube_t); 271static cube_t flipallcorners(cube_t);
53static uint8_t readco(char *); 272static uint8_t readco(char *);
@@ -187,9 +406,9 @@ readcube(format_t format, char *buf)
187 ret = readcube_H48(buf); 406 ret = readcube_H48(buf);
188 break; 407 break;
189 default: 408 default:
190 #ifdef DEBUG 409#ifdef DEBUG
191 fprintf(stderr, "Cannot read cube in the given format\n"); 410 fprintf(stderr, "Cannot read cube in the given format\n");
192 #endif 411#endif
193 setzero(ret); 412 setzero(ret);
194 } 413 }
195 414
@@ -421,18 +640,6 @@ writetrans(trans_t t, char *buf)
421 buf[11] = '\0'; 640 buf[11] = '\0';
422} 641}
423 642
424move_t
425inverse_move(move_t m)
426{
427 return inverse_move_arr[m];
428}
429
430trans_t
431inverse_trans(trans_t t)
432{
433 return inverse_trans_arr[t];
434}
435
436static int 643static int
437permsign(uint8_t *a, int n) 644permsign(uint8_t *a, int n)
438{ 645{
@@ -617,11 +824,49 @@ move(cube_t c, move_t m)
617 } 824 }
618#endif 825#endif
619 826
620#ifdef CUBE_AVX2 827 switch (m) {
621#include "_move_logic_avx2.c" 828 case U:
622#else 829 return inline_move_U(c);
623#include "_move_logic_arr.c" 830 case U2:
831 return inline_move_U2(c);
832 case U3:
833 return inline_move_U3(c);
834 case D:
835 return inline_move_D(c);
836 case D2:
837 return inline_move_D2(c);
838 case D3:
839 return inline_move_D3(c);
840 case R:
841 return inline_move_R(c);
842 case R2:
843 return inline_move_R2(c);
844 case R3:
845 return inline_move_R3(c);
846 case L:
847 return inline_move_L(c);
848 case L2:
849 return inline_move_L2(c);
850 case L3:
851 return inline_move_L3(c);
852 case F:
853 return inline_move_F(c);
854 case F2:
855 return inline_move_F2(c);
856 case F3:
857 return inline_move_F3(c);
858 case B:
859 return inline_move_B(c);
860 case B2:
861 return inline_move_B2(c);
862 case B3:
863 return inline_move_B3(c);
864 default:
865#ifdef DEBUG
866 fprintf(stderr, "mover error, unknown move\n");
624#endif 867#endif
868 goto move_error;
869 }
625 870
626move_error: 871move_error:
627 setzero(err); 872 setzero(err);
@@ -696,56 +941,123 @@ compose(cube_t c1, cube_t c2)
696 return ret; 941 return ret;
697} 942}
698 943
699static cube_t
700flipallcorners(cube_t c)
701{
702/* TODO: optimize for avx2, can be a couple of instructions */
703
704 uint8_t i, piece, orien;
705 cube_t ret;
706
707 ret = c;
708 for (i = 0; i < 8; i++) {
709 piece = get_corner(c, i);
710 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
711 set_corner(ret, i, (piece & _pbits) | orien);
712 }
713
714 return ret;
715}
716
717cube_t 944cube_t
718transform(cube_t c, trans_t t) 945transform(cube_t c, trans_t t)
719{ 946{
720 cube_t ret, solved; 947 cube_t ret;
721 948
722#ifdef DEBUG 949#ifdef DEBUG
723 setzero(ret);
724 if (!isconsistent(c)) { 950 if (!isconsistent(c)) {
725 fprintf(stderr, "transform error, inconsistent cube\n"); 951 fprintf(stderr, "transform error, inconsistent cube\n");
726 return ret; 952 goto trans_error;
727 }
728 if (t >= 48) {
729 fprintf(stderr, "transform error, unknown transformation\n");
730 return ret;
731 } 953 }
732#endif 954#endif
733 955
734#ifdef CUBE_AVX2 956 switch (t) {
735#include "_trans_move_avx2.c" 957 case UFr:
736#else 958 return inline_trans_UFr(c);
737#include "_trans_move_arr.c" 959 case ULr:
960 return inline_trans_ULr(c);
961 case UBr:
962 return inline_trans_UBr(c);
963 case URr:
964 return inline_trans_URr(c);
965 case DFr:
966 return inline_trans_DFr(c);
967 case DLr:
968 return inline_trans_DLr(c);
969 case DBr:
970 return inline_trans_DBr(c);
971 case DRr:
972 return inline_trans_DRr(c);
973 case RUr:
974 return inline_trans_RUr(c);
975 case RFr:
976 return inline_trans_RFr(c);
977 case RDr:
978 return inline_trans_RDr(c);
979 case RBr:
980 return inline_trans_RBr(c);
981 case LUr:
982 return inline_trans_LUr(c);
983 case LFr:
984 return inline_trans_LFr(c);
985 case LDr:
986 return inline_trans_LDr(c);
987 case LBr:
988 return inline_trans_LBr(c);
989 case FUr:
990 return inline_trans_FUr(c);
991 case FRr:
992 return inline_trans_FRr(c);
993 case FDr:
994 return inline_trans_FDr(c);
995 case FLr:
996 return inline_trans_FLr(c);
997 case BUr:
998 return inline_trans_BUr(c);
999 case BRr:
1000 return inline_trans_BRr(c);
1001 case BDr:
1002 return inline_trans_BDr(c);
1003 case BLr:
1004 return inline_trans_BLr(c);
1005 case UFm:
1006 return inline_trans_UFm(c);
1007 case ULm:
1008 return inline_trans_ULm(c);
1009 case UBm:
1010 return inline_trans_UBm(c);
1011 case URm:
1012 return inline_trans_URm(c);
1013 case DFm:
1014 return inline_trans_DFm(c);
1015 case DLm:
1016 return inline_trans_DLm(c);
1017 case DBm:
1018 return inline_trans_DBm(c);
1019 case DRm:
1020 return inline_trans_DRm(c);
1021 case RUm:
1022 return inline_trans_RUm(c);
1023 case RFm:
1024 return inline_trans_RFm(c);
1025 case RDm:
1026 return inline_trans_RDm(c);
1027 case RBm:
1028 return inline_trans_RBm(c);
1029 case LUm:
1030 return inline_trans_LUm(c);
1031 case LFm:
1032 return inline_trans_LFm(c);
1033 case LDm:
1034 return inline_trans_LDm(c);
1035 case LBm:
1036 return inline_trans_LBm(c);
1037 case FUm:
1038 return inline_trans_FUm(c);
1039 case FRm:
1040 return inline_trans_FRm(c);
1041 case FDm:
1042 return inline_trans_FDm(c);
1043 case FLm:
1044 return inline_trans_FLm(c);
1045 case BUm:
1046 return inline_trans_BUm(c);
1047 case BRm:
1048 return inline_trans_BRm(c);
1049 case BDm:
1050 return inline_trans_BDm(c);
1051 case BLm:
1052 return inline_trans_BLm(c);
1053 default:
1054#ifdef DEBUG
1055 fprintf(stderr, "transform error, unknown transformation\n");
738#endif 1056#endif
1057 goto trans_error;
1058 }
739 1059
740 setsolved(solved); 1060trans_error:
741 1061 setzero(ret);
742 ret = compose(solved, trans_move_cube[t]);
743 ret = compose(ret, c);
744 ret = compose(ret, trans_move_cube_inverse[t]);
745
746 /* TODO: work out a better way to do this */
747 if (t >= 24)
748 ret = flipallcorners(ret);
749
750 return ret; 1062 return ret;
751} 1063}

Generated with cgit - Back to sebastiano.tronto.net