aboutsummaryrefslogtreecommitdiff
path: root/src/moves.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano.tronto@gmail.com>2021-11-11 21:37:34 +0100
committerSebastiano Tronto <sebastiano.tronto@gmail.com>2021-11-11 21:37:34 +0100
commit3568412f8f230774d0d11d7ed1c897424f95d3ef (patch)
tree77223792d8c925a9b1fc32b3f4341e943b5f8209 /src/moves.c
parent67e1b5e6e6a2c917a2fe58a37a1382c982b1e5c5 (diff)
downloadnissy-3568412f8f230774d0d11d7ed1c897424f95d3ef.tar.gz
nissy-3568412f8f230774d0d11d7ed1c897424f95d3ef.zip
Rewritten from scratch. Welocme nissy 2.0!
Diffstat (limited to 'src/moves.c')
-rw-r--r--src/moves.c860
1 files changed, 407 insertions, 453 deletions
diff --git a/src/moves.c b/src/moves.c
index ce47e8f..25ce779 100644
--- a/src/moves.c
+++ b/src/moves.c
@@ -1,521 +1,475 @@
1/* This file contains the definitions of the basic moves of the cube.
2 * There is no object or type representing the cube.
3 * Data about the cube can be represented by arrays (describing the position
4 * of pieces of certain types), integers (representing for example a bitmask
5 * for the orientation of pieces of certain type, or the permutation index of
6 * an array representing the permutation of pieces).
7 * Each of the moves functions operates on one such piece of data.
8 *
9 * For example, a way of representing the cube can be:
10 * - An integer eo, which is a bitmask for the orientation of the edges.
11 * - An integer co, same for corners.
12 * - An array ep[12], where a[i]=j means that the edge j is in place i.
13 * - An integer cp representing the permutation index of a permutation array
14 * which is the analogue of that described for edges.
15 *
16 * Different representations will be used for different use-cases. */
17
18#include "coordinates.h"
19#include "moves.h" 1#include "moves.h"
20 2
21/* possible_next[i][j] is a bitmask representing the possible 3/* Local functions ***********************************************************/
22 * next moves we can apply. For example, if the last moves a 0 R then it does
23 * not make sense to apply R, R2 or R'. If they are U D2 it does not make
24 * sense to apply any U* or D*. */
25int possible_next[19][19];
26 4
27int parallel(int m1, int m2) { 5static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
28 if (m1 == 0 || m2 == 0) return 0; 6static bool read_mtables_file();
29 return ((m1-1)/6 == (m2-1)/6); 7static bool write_mtables_file();
30}
31 8
32int compute_possible_next(int last1, int last2) { 9/* Tables and other data *****************************************************/
33 if (last1 == 0) return move_mask_all;
34 10
35 /* Removes the 2 or ' (e.g. turns U2 to U, R' to R). */ 11/* Every move is translated to a an <U, x, y> alg before filling the
36 last2 = (last2 == 0) ? last2 : 3*((last2-1)/3) + 1; 12 transition tables, see init_moves() */
37 last1 = 3*((last1-1)/3) + 1;
38 13
39 int mask = move_mask_all ^ (7 << last1); 14static int edge_cycle[NMOVES][12] =
15{
16 [U] = { UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR },
17 [x] = { DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR },
18 [y] = { UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL }
19};
40 20
41 if (parallel(last1, last2)) 21static int corner_cycle[NMOVES][8] =
42 mask ^= 7 << last2; 22{
43 else if (last1 % 6 == 4) /*Always U before D, R before L, F before B*/ 23 [U] = { UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR },
44 mask ^= 7 << (last1-3); 24 [x] = { DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR },
25 [y] = { UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL }
26};
45 27
46 return mask; 28static int center_cycle[NMOVES][6] =
47} 29{
30 [x] = { F_center, B_center, R_center, L_center, D_center, U_center },
31 [y] = { U_center, D_center, B_center, F_center, R_center, L_center }
32};
48 33
49void init_possible_next() { 34static int eofb_flipped[NMOVES][12] = {
50 for (int i = 0; i < 19; i++) 35 [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
51 for (int j = 0; j < 19; j++) 36 [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 }
52 possible_next[i][j] = compute_possible_next(i, j); 37};
53}
54 38
55/* Piece cycles depending on the move. For example edge_cycle[U2][UF] 39static int eorl_flipped[NMOVES][12] = {
56 * gives the piece in position UF after applying U2 to a solved cube */ 40 [x] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
41 [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 }
42};
57 43
58int edge_cycle[19][12] = { 44static int eoud_flipped[NMOVES][12] = {
59 {UF, UL, UB, UR, DF, DL, DB, DR, FR, FL, BL, BR}, /* - */ 45 [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 },
60 {UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR}, /* U */ 46 [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
61 {UB, UR, UF, UL, DF, DL, DB, DR, FR, FL, BL, BR}, /* U2 */ 47 [y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
62 {UL, UB, UR, UF, DF, DL, DB, DR, FR, FL, BL, BR}, /* U' */
63 {UF, UL, UB, UR, DL, DB, DR, DF, FR, FL, BL, BR}, /* D */
64 {UF, UL, UB, UR, DB, DR, DF, DL, FR, FL, BL, BR}, /* D2 */
65 {UF, UL, UB, UR, DR, DF, DL, DB, FR, FL, BL, BR}, /* D' */
66 {UF, UL, UB, FR, DF, DL, DB, BR, DR, FL, BL, UR}, /* R */
67 {UF, UL, UB, DR, DF, DL, DB, UR, BR, FL, BL, FR}, /* R2 */
68 {UF, UL, UB, BR, DF, DL, DB, FR, UR, FL, BL, DR}, /* R' */
69 {UF, BL, UB, UR, DF, FL, DB, DR, FR, UL, DL, BR}, /* L */
70 {UF, DL, UB, UR, DF, UL, DB, DR, FR, BL, FL, BR}, /* L2 */
71 {UF, FL, UB, UR, DF, BL, DB, DR, FR, DL, UL, BR}, /* L' */
72 {FL, UL, UB, UR, FR, DL, DB, DR, UF, DF, BL, BR}, /* F */
73 {DF, UL, UB, UR, UF, DL, DB, DR, FL, FR, BL, BR}, /* F2 */
74 {FR, UL, UB, UR, FL, DL, DB, DR, DF, UF, BL, BR}, /* F' */
75 {UF, UL, BR, UR, DF, DL, BL, DR, FR, FL, UB, DB}, /* B */
76 {UF, UL, DB, UR, DF, DL, UB, DR, FR, FL, BR, BL}, /* B2 */
77 {UF, UL, BL, UR, DF, DL, BR, DR, FR, FL, DB, UB} /* B' */
78}; 48};
79 49
80int corner_cycle[19][8] = { 50static int coud_flipped[NMOVES][8] = {
81 {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR}, /* - */ 51 [x] = {
82 {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR}, /* U */ 52 [UFR] = 2, [UBR] = 1, [UFL] = 1, [UBL] = 2,
83 {UBL, UBR, UFR, UFL, DFR, DFL, DBL, DBR}, /* U2 */ 53 [DBR] = 2, [DFR] = 1, [DBL] = 1, [DFL] = 2
84 {UFL, UBL, UBR, UFR, DFR, DFL, DBL, DBR}, /* U' */ 54 }
85 {UFR, UFL, UBL, UBR, DFL, DBL, DBR, DFR}, /* D */
86 {UFR, UFL, UBL, UBR, DBL, DBR, DFR, DFL}, /* D2 */
87 {UFR, UFL, UBL, UBR, DBR, DFR, DFL, DBL}, /* D' */
88 {DFR, UFL, UBL, UFR, DBR, DFL, DBL, UBR}, /* R */
89 {DBR, UFL, UBL, DFR, UBR, DFL, DBL, UFR}, /* R2 */
90 {UBR, UFL, UBL, DBR, UFR, DFL, DBL, DFR}, /* R' */
91 {UFR, UBL, DBL, UBR, DFR, UFL, DFL, DBR}, /* L */
92 {UFR, DBL, DFL, UBR, DFR, UBL, UFL, DBR}, /* L2 */
93 {UFR, DFL, UFL, UBR, DFR, DBL, UBL, DBR}, /* L' */
94 {UFL, DFL, UBL, UBR, UFR, DFR, DBL, DBR}, /* F */
95 {DFL, DFR, UBL, UBR, UFL, UFR, DBL, DBR}, /* F2 */
96 {DFR, UFR, UBL, UBR, DFL, UFL, DBL, DBR}, /* F' */
97 {UFR, UFL, UBR, DBR, DFR, DFL, UBL, DBL}, /* B */
98 {UFR, UFL, DBR, DBL, DFR, DFL, UBR, UBL}, /* B2 */
99 {UFR, UFL, DBL, UBL, DFR, DFL, DBR, UBR}, /* U' */
100}; 55};
101 56
102/* Transition tables */ 57static int corl_flipped[NMOVES][8] = {
58 [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 },
59 [y] = {
60 [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2,
61 [DFR] = 2, [DBR] = 1, [DBL] = 2, [DFL] = 1
62 }
63};
103 64
104int eofb_transition_table[pow2to11][19]; 65static int cofb_flipped[NMOVES][8] = {
105int eorl_transition_table[pow2to11][19]; 66 [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 },
106int eoud_transition_table[pow2to11][19]; 67 [x] = {
107int coud_transition_table[pow3to7][19]; 68 [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2,
108int cofb_transition_table[pow3to7][19]; 69 [DFR] = 2, [DBR] = 1, [DBL] = 2, [DFL] = 1
109int corl_transition_table[pow3to7][19]; 70 },
110int epud_transition_table[factorial8][19]; 71 [y] = {
111int eprl_transition_table[factorial8][19]; 72 [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1,
112int epfb_transition_table[factorial8][19]; 73 [DFR] = 1, [DBR] = 2, [DBL] = 1, [DFL] = 2
113int epose_transition_table[binom12on4][19]; 74 }
114int eposs_transition_table[binom12on4][19]; 75};
115int eposm_transition_table[binom12on4][19];
116int epe_transition_table[factorial4][19];
117int eps_transition_table[factorial4][19];
118int epm_transition_table[factorial4][19];
119int emslices_transition_table[binom12on4*binom8on4][19];
120int cp_transition_table[factorial8][19];
121 76
122/***/ 77static char equiv_alg_string[100][NMOVES] = {
123/* Functions for permuting pieces (given in array format) */ 78 [NULLMOVE] = "",
124/***/
125 79
126void apply_move_ep_array(int move, int ep[12]) { 80 [U] = " U ",
127 int aux[12]; 81 [U2] = " UU ",
128 for (int i = 0; i < 12; i++) 82 [U3] = " UUU ",
129 aux[i] = ep[i]; 83 [D] = " xx U xx ",
130 for (int i = 0; i < 12; i++) 84 [D2] = " xx UU xx ",
131 ep[i] = aux[edge_cycle[move][i]]; 85 [D3] = " xx UUU xx ",
132} 86 [R] = " yx U xxxyyy ",
87 [R2] = " yx UU xxxyyy ",
88 [R3] = " yx UUU xxxyyy ",
89 [L] = " yyyx U xxxy ",
90 [L2] = " yyyx UU xxxy ",
91 [L3] = " yyyx UUU xxxy ",
92 [F] = " x U xxx ",
93 [F2] = " x UU xxx ",
94 [F3] = " x UUU xxx ",
95 [B] = " xxx U x ",
96 [B2] = " xxx UU x ",
97 [B3] = " xxx UUU x ",
133 98
134void apply_move_cp_array(int move, int cp[8]) { 99 [Uw] = " xx U xx y ",
135 int aux[8]; 100 [Uw2] = " xx UU xx yy ",
136 for (int i = 0; i < 8; i++) 101 [Uw3] = " xx UUU xx yyy ",
137 aux[i] = cp[i]; 102 [Dw] = " U yyy ",
138 for (int i = 0; i < 8; i++) 103 [Dw2] = " UU yy ",
139 cp[i] = aux[corner_cycle[move][i]]; 104 [Dw3] = " UUU y ",
140} 105 [Rw] = " yyyx U xxxy x ",
106 [Rw2] = " yyyx UU xxxy xx ",
107 [Rw3] = " yyyx UUU xxxy xxx ",
108 [Lw] = " yx U xxxyyy xxx ",
109 [Lw2] = " yx UU xxxyyy xx ",
110 [Lw3] = " yx UUU xxxyyy x ",
111 [Fw] = " xxx U x yxxxyyy ",
112 [Fw2] = " xxx UU x yxxyyy ",
113 [Fw3] = " xxx UUU x yxyyy ",
114 [Bw] = " x U xxx yxyyy ",
115 [Bw2] = " x UU xxx yxxyyy ",
116 [Bw3] = " x UUU xxx yxxxyyy ",
141 117
142/***/ 118 [M] = " yx U xx UUU yxyyy ",
143/* Functions for permuting pieces (given in integer format) */ 119 [M2] = " yx UU xx UU xxxy ",
144/***/ 120 [M3] = " yx UUU xx U yxxxy ",
121 [S] = " x UUU xx U yyyx ",
122 [S2] = " x UU xx UU yyx ",
123 [S3] = " x U xx UUU yx ",
124 [E] = " U xx UUU xxyyy ",
125 [E2] = " UU xx UU xxyy ",
126 [E3] = " UUU xx U xxy ",
145 127
146int apply_move_ep_int(int move, int ep) { 128 [x] = " x ",
147 int a[12]; 129 [x2] = " xx ",
148 ep_int_to_array(ep, a); 130 [x3] = " xxx ",
149 apply_move_ep_array(move, a); 131 [y] = " y ",
150 return ep_array_to_int(a); 132 [y2] = " yy ",
151} 133 [y3] = " yyy ",
134 [z] = " yyy x y ",
135 [z2] = " yy xx ",
136 [z3] = " y x yyy "
137};
152 138
153int apply_move_epud_int(int move, int ep) { 139/* Transition tables, to be loaded up at the beginning */
154 int a[12]; 140static int epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
155 epud_int_to_array(ep, a); 141static int eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
156 apply_move_ep_array(move, a); 142static int eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
157 return epud_array_to_int(a); 143static int eofb_mtable[NMOVES][POW2TO11];
158} 144static int eorl_mtable[NMOVES][POW2TO11];
145static int eoud_mtable[NMOVES][POW2TO11];
146static int cp_mtable[NMOVES][FACTORIAL8];
147static int coud_mtable[NMOVES][POW3TO7];
148static int cofb_mtable[NMOVES][POW3TO7];
149static int corl_mtable[NMOVES][POW3TO7];
150static int cpos_mtable[NMOVES][FACTORIAL6];
159 151
160int apply_move_eprl_int(int move, int ep) {
161 int a[12];
162 eprl_int_to_array(ep, a);
163 apply_move_ep_array(move, a);
164 return eprl_array_to_int(a);
165}
166 152
167int apply_move_epfb_int(int move, int ep) { 153/* Local functions implementation ********************************************/
168 int a[12];
169 epfb_int_to_array(ep, a);
170 apply_move_ep_array(move, a);
171 return epfb_array_to_int(a);
172}
173 154
174int apply_move_epose_int(int move, int ep) { 155static Cube
175 int a[12]; 156apply_move_cubearray(Move m, Cube cube, PieceFilter f)
176 epose_int_to_array(ep, a); 157{
177 apply_move_ep_array(move, a); 158 /*init_moves();*/
178 return epose_array_to_int(a);
179}
180 159
181int apply_move_eposs_int(int move, int ep) { 160 CubeArray m_arr = {
182 int a[12]; 161 edge_cycle[m],
183 eposs_int_to_array(ep, a); 162 eofb_flipped[m],
184 apply_move_ep_array(move, a); 163 eorl_flipped[m],
185 return eposs_array_to_int(a); 164 eoud_flipped[m],
186} 165 corner_cycle[m],
166 coud_flipped[m],
167 corl_flipped[m],
168 cofb_flipped[m],
169 center_cycle[m]
170 };
187 171
188int apply_move_eposm_int(int move, int ep) { 172 return move_via_arrays(&m_arr, cube, f);
189 int a[12];
190 eposm_int_to_array(ep, a);
191 apply_move_ep_array(move, a);
192 return eposm_array_to_int(a);
193} 173}
194 174
195int apply_move_epe_int(int move, int ep) { 175/* Public functions **********************************************************/
196 int a[12];
197 epe_int_to_array(ep, a);
198 apply_move_ep_array(move, a);
199 return epe_array_to_int(a);
200}
201 176
202int apply_move_eps_int(int move, int ep) { 177Cube
203 int a[12]; 178apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
204 eps_int_to_array(ep, a); 179{
205 apply_move_ep_array(move, a); 180 Cube ret = {0};
206 return eps_array_to_int(a); 181 int i;
207}
208 182
209int apply_move_epm_int(int move, int ep) { 183 for (i = 0; i < alg->len; i++)
210 int a[12]; 184 if (alg->inv[i])
211 epm_int_to_array(ep, a); 185 ret = a ? apply_move(alg->move[i], ret) :
212 apply_move_ep_array(move, a); 186 apply_move_cubearray(alg->move[i], ret, f);
213 return epm_array_to_int(a);
214}
215 187
216int apply_move_emslices_int(int move, int e) { 188 ret = compose_filtered(c, inverse_cube(ret), f);
217 int a[12];
218 emslices_int_to_array(e, a);
219 apply_move_ep_array(move, a);
220 return emslices_array_to_int(a);
221}
222 189
223int apply_move_cp_int(int move, int cp) { 190 for (i = 0; i < alg->len; i++)
224 int a[8]; 191 if (!alg->inv[i])
225 cp_int_to_array(cp, a); 192 ret = a ? apply_move(alg->move[i], ret) :
226 apply_move_cp_array(move, a); 193 apply_move_cubearray(alg->move[i], ret, f);
227 return cp_array_to_int(a);
228}
229 194
230int apply_move_eofb_int(int move, int eo) { 195 return ret;
231 int a[12];
232 eo_11bits_to_array(eo, a);
233 apply_move_ep_array(move, a);
234 /* Change edge orientation */
235 if (move == F || move == F3) {
236 a[UF] = 1 - a[UF];
237 a[DF] = 1 - a[DF];
238 a[FR] = 1 - a[FR];
239 a[FL] = 1 - a[FL];
240 }
241 if (move == B || move == B3) {
242 a[UB] = 1 - a[UB];
243 a[DB] = 1 - a[DB];
244 a[BL] = 1 - a[BL];
245 a[BR] = 1 - a[BR];
246 }
247 return eo_array_to_11bits(a);
248} 196}
249 197
250int apply_move_eorl_int(int move, int eo) { 198Cube
251 int a[12]; 199apply_alg(Alg *alg, Cube cube)
252 eo_11bits_to_array(eo, a); 200{
253 apply_move_ep_array(move, a); 201 return apply_alg_generic(alg, cube, pf_all, true);
254 /* Change edge orientation */
255 if (move == R || move == R3) {
256 a[UR] = 1 - a[UR];
257 a[DR] = 1 - a[DR];
258 a[FR] = 1 - a[FR];
259 a[BR] = 1 - a[BR];
260 }
261 if (move == L || move == L3) {
262 a[UL] = 1 - a[UL];
263 a[DL] = 1 - a[DL];
264 a[FL] = 1 - a[FL];
265 a[BL] = 1 - a[BL];
266 }
267 return eo_array_to_11bits(a);
268} 202}
269 203
270int apply_move_eoud_int(int move, int eo) { 204Cube
271 int a[12]; 205apply_move(Move m, Cube cube)
272 eo_11bits_to_array(eo, a); 206{
273 apply_move_ep_array(move, a); 207 /*init_moves();*/
274 /* Change edge orientation */
275 if (move == U || move == U3) {
276 a[UF] = 1 - a[UF];
277 a[UL] = 1 - a[UL];
278 a[UB] = 1 - a[UB];
279 a[UR] = 1 - a[UR];
280 }
281 if (move == D || move == D3) {
282 a[DF] = 1 - a[DF];
283 a[DL] = 1 - a[DL];
284 a[DB] = 1 - a[DB];
285 a[DR] = 1 - a[DR];
286 }
287 return eo_array_to_11bits(a);
288}
289 208
290int apply_move_coud_int(int move, int co) { 209 return (Cube) {
291 int a[8]; 210 .epose = epose_mtable[m][cube.epose],
292 co_7trits_to_array(co, a); 211 .eposs = eposs_mtable[m][cube.eposs],
293 apply_move_cp_array(move, a); 212 .eposm = eposm_mtable[m][cube.eposm],
294 /* Change corner orientation */ 213 .eofb = eofb_mtable[m][cube.eofb],
295 if (move == R || move == R3) { 214 .eorl = eorl_mtable[m][cube.eorl],
296 a[UFR] = (a[UFR] + 2) % 3; 215 .eoud = eoud_mtable[m][cube.eoud],
297 a[UBR] = (a[UBR] + 1) % 3; 216 .coud = coud_mtable[m][cube.coud],
298 a[DBR] = (a[DBR] + 2) % 3; 217 .cofb = cofb_mtable[m][cube.cofb],
299 a[DFR] = (a[DFR] + 1) % 3; 218 .corl = corl_mtable[m][cube.corl],
300 } 219 .cp = cp_mtable[m][cube.cp],
301 if (move == L || move == L3) { 220 .cpos = cpos_mtable[m][cube.cpos]
302 a[UBL] = (a[UBL] + 2) % 3; 221 };
303 a[UFL] = (a[UFL] + 1) % 3;
304 a[DFL] = (a[DFL] + 2) % 3;
305 a[DBL] = (a[DBL] + 1) % 3;
306 }
307 if (move == F || move == F3) {
308 a[UFL] = (a[UFL] + 2) % 3;
309 a[UFR] = (a[UFR] + 1) % 3;
310 a[DFR] = (a[DFR] + 2) % 3;
311 a[DFL] = (a[DFL] + 1) % 3;
312 }
313 if (move == B || move == B3) {
314 a[UBR] = (a[UBR] + 2) % 3;
315 a[UBL] = (a[UBL] + 1) % 3;
316 a[DBL] = (a[DBL] + 2) % 3;
317 a[DBR] = (a[DBR] + 1) % 3;
318 }
319 return co_array_to_7trits(a);
320} 222}
321 223
322int apply_move_cofb_int(int move, int co) { 224static bool
323 int a[8]; 225read_mtables_file()
324 co_7trits_to_array(co, a); 226{
325 apply_move_cp_array(move, a); 227 init_env();
326 /* Change corner orientation */
327 if (move == R || move == R3) {
328 a[UFR] = (a[UFR] + 1) % 3;
329 a[UBR] = (a[UBR] + 2) % 3;
330 a[DBR] = (a[DBR] + 1) % 3;
331 a[DFR] = (a[DFR] + 2) % 3;
332 }
333 if (move == L || move == L3) {
334 a[UBL] = (a[UBL] + 1) % 3;
335 a[UFL] = (a[UFL] + 2) % 3;
336 a[DFL] = (a[DFL] + 1) % 3;
337 a[DBL] = (a[DBL] + 2) % 3;
338 }
339 if (move == U || move == U3) {
340 a[UFL] = (a[UFL] + 1) % 3;
341 a[UFR] = (a[UFR] + 2) % 3;
342 a[UBL] = (a[UBL] + 2) % 3;
343 a[UBR] = (a[UBR] + 1) % 3;
344 }
345 if (move == D || move == D3) {
346 a[DFL] = (a[DFL] + 2) % 3;
347 a[DFR] = (a[DFR] + 1) % 3;
348 a[DBL] = (a[DBL] + 1) % 3;
349 a[DBR] = (a[DBR] + 2) % 3;
350 }
351 return co_array_to_7trits(a);
352}
353 228
354int apply_move_corl_int(int move, int co) { 229 FILE *f;
355 int a[8]; 230 char fname[strlen(tabledir)+20];
356 co_7trits_to_array(co, a); 231 int m, b = sizeof(int);
357 apply_move_cp_array(move, a); 232 bool r = true;
358 /* Change corner orientation */
359 if (move == F || move == F3) {
360 a[UFR] = (a[UFR] + 2) % 3;
361 a[UFL] = (a[UFL] + 1) % 3;
362 a[DFL] = (a[DFL] + 2) % 3;
363 a[DFR] = (a[DFR] + 1) % 3;
364 }
365 if (move == B || move == B3) {
366 a[UBL] = (a[UBL] + 2) % 3;
367 a[UBR] = (a[UBR] + 1) % 3;
368 a[DBR] = (a[DBR] + 2) % 3;
369 a[DBL] = (a[DBL] + 1) % 3;
370 }
371 if (move == U || move == U3) {
372 a[UFL] = (a[UFL] + 2) % 3;
373 a[UFR] = (a[UFR] + 1) % 3;
374 a[UBL] = (a[UBL] + 1) % 3;
375 a[UBR] = (a[UBR] + 2) % 3;
376 }
377 if (move == D || move == D3) {
378 a[DFL] = (a[DFL] + 1) % 3;
379 a[DFR] = (a[DFR] + 2) % 3;
380 a[DBL] = (a[DBL] + 2) % 3;
381 a[DBR] = (a[DBR] + 1) % 3;
382 }
383 return co_array_to_7trits(a);
384}
385
386 233
234 /* Table sizes, used for reading and writing files */
235 uint64_t me[11] = {
236 [0] = FACTORIAL12/FACTORIAL8,
237 [1] = FACTORIAL12/FACTORIAL8,
238 [2] = FACTORIAL12/FACTORIAL8,
239 [3] = POW2TO11,
240 [4] = POW2TO11,
241 [5] = POW2TO11,
242 [6] = FACTORIAL8,
243 [7] = POW3TO7,
244 [8] = POW3TO7,
245 [9] = POW3TO7,
246 [10] = FACTORIAL6
247 };
387 248
388/* Initialize transition tables */ 249 strcpy(fname, tabledir);
250 strcat(fname, "/mtables");
389 251
390void init_epud_transition_table() { 252 if ((f = fopen(fname, "rb")) == NULL)
391 for (int i = 0; i < factorial8; i++) 253 return false;
392 for (int j = 0; j < 19; j++)
393 if (move_mask_drud & (1 << j))
394 epud_transition_table[i][j] = apply_move_epud_int(j, i);
395}
396 254
397void init_eprl_transition_table() { 255 for (m = 0; m < NMOVES; m++) {
398 for (int i = 0; i < factorial8; i++) 256 r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
399 for (int j = 0; j < 19; j++) 257 r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
400 if (move_mask_drrl & (1 << j)) 258 r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
401 eprl_transition_table[i][j] = apply_move_eprl_int(j, i); 259 r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
402} 260 r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
261 r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
262 r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
263 r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
264 r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
265 r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
266 r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
267 }
403 268
404void init_epfb_transition_table() { 269 fclose(f);
405 for (int i = 0; i < factorial8; i++) 270 return r;
406 for (int j = 0; j < 19; j++)
407 if (move_mask_drfb & (1 << j))
408 epfb_transition_table[i][j] = apply_move_epfb_int(j, i);
409} 271}
410 272
411void init_epose_transition_table() { 273static bool
412 for (int i = 0; i < binom12on4; i++) 274write_mtables_file()
413 for (int j = 0; j < 19; j++) 275{
414 epose_transition_table[i][j] = apply_move_epose_int(j, i); 276 init_env();
415}
416 277
417void init_eposs_transition_table() { 278 FILE *f;
418 for (int i = 0; i < binom12on4; i++) 279 char fname[strlen(tabledir)+20];
419 for (int j = 0; j < 19; j++) 280 int m, b = sizeof(int);
420 eposs_transition_table[i][j] = apply_move_eposs_int(j, i); 281 bool r = true;
421}
422 282
423void init_eposm_transition_table() { 283 /* Table sizes, used for reading and writing files */
424 for (int i = 0; i < binom12on4; i++) 284 uint64_t me[11] = {
425 for (int j = 0; j < 19; j++) 285 [0] = FACTORIAL12/FACTORIAL8,
426 eposm_transition_table[i][j] = apply_move_eposm_int(j, i); 286 [1] = FACTORIAL12/FACTORIAL8,
427} 287 [2] = FACTORIAL12/FACTORIAL8,
288 [3] = POW2TO11,
289 [4] = POW2TO11,
290 [5] = POW2TO11,
291 [6] = FACTORIAL8,
292 [7] = POW3TO7,
293 [8] = POW3TO7,
294 [9] = POW3TO7,
295 [10] = FACTORIAL6
296 };
428 297
429void init_epe_transition_table() { 298 strcpy(fname, tabledir);
430 for (int i = 0; i < factorial4; i++) { 299 strcat(fname, "/mtables");
431 for (int j = 0; j < 19; j++)
432 if (move_mask_drud & (1 << j))
433 epe_transition_table[i][j] = apply_move_epe_int(j, i);
434 }
435}
436 300
437void init_eps_transition_table() { 301 if ((f = fopen(fname, "wb")) == NULL)
438 for (int i = 0; i < factorial4; i++) { 302 return false;
439 for (int j = 0; j < 19; j++)
440 if (move_mask_drfb & (1 << j))
441 eps_transition_table[i][j] = apply_move_eps_int(j, i);
442 }
443}
444 303
445void init_epm_transition_table() { 304 for (m = 0; m < NMOVES; m++) {
446 for (int i = 0; i < factorial4; i++) { 305 r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
447 for (int j = 0; j < 19; j++) 306 r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
448 if (move_mask_drrl & (1 << j)) 307 r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
449 epm_transition_table[i][j] = apply_move_epm_int(j, i); 308 r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
450 } 309 r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
451} 310 r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
311 r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
312 r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
313 r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
314 r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
315 r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
316 }
452 317
453void init_emslices_transition_table() { 318 fclose(f);
454 for (int i = 0; i < binom12on4*binom8on4; i++) { 319 return r;
455 for (int j = 0; j < 19; j++)
456 emslices_transition_table[i][j] = apply_move_emslices_int(j, i);
457 }
458} 320}
459 321
460void init_cp_transition_table() { 322bool
461 for (int i = 0; i < factorial8; i++) 323commute(Move m1, Move m2)
462 for (int j = 0; j < 19; j++) 324{
463 cp_transition_table[i][j] = apply_move_cp_int(j, i); 325 static bool initialized = false;
464} 326 static bool commute_aux[NMOVES][NMOVES];
465 327
466void init_eofb_transition_table() { 328 if (!initialized) {
467 for (int i = 0; i < pow2to11; i++) 329 Cube c1, c2;
468 for (int j = 0; j < 19; j++) 330 int i, j;
469 eofb_transition_table[i][j] = apply_move_eofb_int(j, i);
470}
471 331
472void init_eorl_transition_table() { 332 for (i = 0; i < NMOVES; i++) {
473 for (int i = 0; i < pow2to11; i++) 333 for (j = 0; j < NMOVES; j++) {
474 for (int j = 0; j < 19; j++) 334 c1 = apply_move(i, apply_move(j, (Cube){0}));
475 eorl_transition_table[i][j] = apply_move_eorl_int(j, i); 335 c2 = apply_move(j, apply_move(i, (Cube){0}));
476} 336 commute_aux[i][j] = equal(c1, c2) && i && j;
337 }
338 }
477 339
478void init_eoud_transition_table() { 340 initialized = true;
479 for (int i = 0; i < pow2to11; i++) 341 }
480 for (int j = 0; j < 19; j++)
481 eoud_transition_table[i][j] = apply_move_eoud_int(j, i);
482}
483 342
484void init_coud_transition_table() { 343 return commute_aux[m1][m2];
485 for (int i = 0; i < pow3to7; i++)
486 for (int j = 0; j < 19; j++ )
487 coud_transition_table[i][j] = apply_move_coud_int(j, i);
488} 344}
489 345
490void init_cofb_transition_table() { 346bool
491 for (int i = 0; i < pow3to7; i++) 347possible_next(Move m1, Move m2, Move m3)
492 for (int j = 0; j < 19; j++ ) 348{
493 cofb_transition_table[i][j] = apply_move_cofb_int(j, i); 349 static bool initialized = false;
494} 350 static bool paux[NMOVES][NMOVES][NMOVES];
351
352 if (!initialized) {
353 int i, j, k;
354 bool p, q, c;
495 355
496void init_corl_transition_table() { 356 for (i = 0; i < NMOVES; i++) {
497 for (int i = 0; i < pow3to7; i++) 357 for (j = 0; j < NMOVES; j++) {
498 for (int j = 0; j < 19; j++ ) 358 for (k = 0; k < NMOVES; k++) {
499 corl_transition_table[i][j] = apply_move_corl_int(j, i); 359 p = j && base_move(j) == base_move(k);
360 q = i && base_move(i) == base_move(k);
361 c = commute(i, j);
362 paux[i][j][k] = !(p || (c && q));
363 }
364 }
365 }
366
367 initialized = true;
368 }
369
370 return paux[m1][m2][m3];
500} 371}
501 372
502void init_transition_table() { 373void
503 init_epud_transition_table(); 374init_moves() {
504 init_eprl_transition_table(); 375 static bool initialized = false;
505 init_epfb_transition_table(); 376 if (initialized)
506 init_epose_transition_table(); 377 return;
507 init_eposs_transition_table(); 378 initialized = true;
508 init_eposm_transition_table(); 379
509 init_epe_transition_table(); 380 Cube c;
510 init_eps_transition_table(); 381 CubeArray arrs;
511 init_epm_transition_table(); 382 int i;
512 init_emslices_transition_table(); 383 unsigned int ui;
513 init_cp_transition_table(); 384 Move m;
514 init_eofb_transition_table(); 385 Alg *equiv_alg[NMOVES];
515 init_eorl_transition_table(); 386
516 init_eoud_transition_table(); 387 for (i = 0; i < NMOVES; i++)
517 init_coud_transition_table(); 388 equiv_alg[i] = new_alg(equiv_alg_string[i]);
518 init_cofb_transition_table(); 389
519 init_corl_transition_table(); 390 /* Generate all move cycles and flips; I do this regardless */
391 for (i = 0; i < NMOVES; i++) {
392 if (i == U || i == x || i == y)
393 continue;
394
395 c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
396
397 arrs = (CubeArray) {
398 edge_cycle[i],
399 eofb_flipped[i],
400 eorl_flipped[i],
401 eoud_flipped[i],
402 corner_cycle[i],
403 coud_flipped[i],
404 corl_flipped[i],
405 cofb_flipped[i],
406 center_cycle[i]
407 };
408 cube_to_arrays(c, &arrs, pf_all);
409 }
410
411 if (read_mtables_file())
412 return;
413
414 fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
415
416 /* Initialize transition tables */
417 for (m = 0; m < NMOVES; m++) {
418 for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
419 c = (Cube){ .epose = ui };
420 c = apply_move_cubearray(m, c, pf_e);
421 epose_mtable[m][ui] = c.epose;
422
423 c = (Cube){ .eposs = ui };
424 c = apply_move_cubearray(m, c, pf_s);
425 eposs_mtable[m][ui] = c.eposs;
426
427 c = (Cube){ .eposm = ui };
428 c = apply_move_cubearray(m, c, pf_m);
429 eposm_mtable[m][ui] = c.eposm;
430 }
431 for (ui = 0; ui < POW2TO11; ui++ ) {
432 c = (Cube){ .eofb = ui };
433 c = apply_move_cubearray(m, c, pf_eo);
434 eofb_mtable[m][ui] = c.eofb;
435
436 c = (Cube){ .eorl = ui };
437 c = apply_move_cubearray(m, c, pf_eo);
438 eorl_mtable[m][ui] = c.eorl;
439
440 c = (Cube){ .eoud = ui };
441 c = apply_move_cubearray(m, c, pf_eo);
442 eoud_mtable[m][ui] = c.eoud;
443 }
444 for (ui = 0; ui < POW3TO7; ui++) {
445 c = (Cube){ .coud = ui };
446 c = apply_move_cubearray(m, c, pf_co);
447 coud_mtable[m][ui] = c.coud;
448
449 c = (Cube){ .corl = ui };
450 c = apply_move_cubearray(m, c, pf_co);
451 corl_mtable[m][ui] = c.corl;
452
453 c = (Cube){ .cofb = ui };
454 c = apply_move_cubearray(m, c, pf_co);
455 cofb_mtable[m][ui] = c.cofb;
456 }
457 for (ui = 0; ui < FACTORIAL8; ui++) {
458 c = (Cube){ .cp = ui };
459 c = apply_move_cubearray(m, c, pf_cp);
460 cp_mtable[m][ui] = c.cp;
461 }
462 for (ui = 0; ui < FACTORIAL6; ui++) {
463 c = (Cube){ .cpos = ui };
464 c = apply_move_cubearray(m, c, pf_cpos);
465 cpos_mtable[m][ui] = c.cpos;
466 }
467 }
468
469 if (!write_mtables_file())
470 fprintf(stderr, "Error writing mtables\n");
471
472 for (i = 0; i < NMOVES; i++)
473 free_alg(equiv_alg[i]);
520} 474}
521 475

Generated with cgit - Back to sebastiano.tronto.net