aboutsummaryrefslogtreecommitdiff
path: root/src/moves.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/moves.c')
-rw-r--r--src/moves.c409
1 files changed, 73 insertions, 336 deletions
diff --git a/src/moves.c b/src/moves.c
index 02880ca..51012db 100644
--- a/src/moves.c
+++ b/src/moves.c
@@ -1,79 +1,18 @@
1#define MOVES_C
2
1#include "moves.h" 3#include "moves.h"
2 4
3/* Local functions ***********************************************************/ 5/* Local functions ***********************************************************/
4 6
5static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
6static void cleanup_aux(Alg *alg, Alg *ret, bool inv); 7static void cleanup_aux(Alg *alg, Alg *ret, bool inv);
7static bool read_mtables_file();
8static bool write_mtables_file();
9 8
10/* Tables and other data *****************************************************/ 9/* Tables and other data *****************************************************/
11 10
12/* Every move is translated to a an <U, x, y> alg before filling the 11/* Moves are represented as cubes and applied using compose(). Every move is *
13 transition tables, see init_moves() */ 12 * translated to a an <U, x, y> alg before filling the transition tables. *
14 13 * See init_moves(). */
15static int edge_cycle[NMOVES][12] =
16{
17 [U] = { UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR },
18 [x] = { DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR },
19 [y] = { UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL }
20};
21
22static int corner_cycle[NMOVES][8] =
23{
24 [U] = { UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR },
25 [x] = { DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR },
26 [y] = { UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL }
27};
28
29static int center_cycle[NMOVES][6] =
30{
31 [x] = { F_center, B_center, R_center, L_center, D_center, U_center },
32 [y] = { U_center, D_center, B_center, F_center, R_center, L_center }
33};
34
35static int eofb_flipped[NMOVES][12] = {
36 [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
37 [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 }
38};
39 14
40static int eorl_flipped[NMOVES][12] = { 15static Cube move_array[NMOVES];
41 [x] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
42 [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 }
43};
44
45static int eoud_flipped[NMOVES][12] = {
46 [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 },
47 [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
48 [y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
49};
50
51static int coud_flipped[NMOVES][8] = {
52 [x] = {
53 [UFR] = 2, [UBR] = 1, [UFL] = 1, [UBL] = 2,
54 [DBR] = 2, [DFR] = 1, [DBL] = 1, [DFL] = 2
55 }
56};
57
58static int corl_flipped[NMOVES][8] = {
59 [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 },
60 [y] = {
61 [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2,
62 [DFR] = 2, [DBR] = 1, [DBL] = 2, [DFL] = 1
63 }
64};
65
66static int cofb_flipped[NMOVES][8] = {
67 [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 },
68 [x] = {
69 [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2,
70 [DFR] = 2, [DBR] = 1, [DBL] = 2, [DFL] = 1
71 },
72 [y] = {
73 [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1,
74 [DFR] = 1, [DBR] = 2, [DBL] = 1, [DFL] = 2
75 }
76};
77 16
78static char equiv_alg_string[100][NMOVES] = { 17static char equiv_alg_string[100][NMOVES] = {
79 [NULLMOVE] = "", 18 [NULLMOVE] = "",
@@ -137,89 +76,34 @@ static char equiv_alg_string[100][NMOVES] = {
137 [z3] = " y x yyy " 76 [z3] = " y x yyy "
138}; 77};
139 78
140/* Transition tables, to be loaded up at the beginning */
141int epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
142int eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
143int eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
144int eofb_mtable[NMOVES][POW2TO11];
145int eorl_mtable[NMOVES][POW2TO11];
146int eoud_mtable[NMOVES][POW2TO11];
147int cp_mtable[NMOVES][FACTORIAL8];
148int coud_mtable[NMOVES][POW3TO7];
149int cofb_mtable[NMOVES][POW3TO7];
150int corl_mtable[NMOVES][POW3TO7];
151int cpos_mtable[NMOVES][FACTORIAL6];
152
153
154/* Local functions implementation ********************************************/
155
156static Cube
157apply_move_cubearray(Move m, Cube cube, PieceFilter f)
158{
159 /*init_moves();*/
160
161 CubeArray m_arr = {
162 edge_cycle[m],
163 eofb_flipped[m],
164 eorl_flipped[m],
165 eoud_flipped[m],
166 corner_cycle[m],
167 coud_flipped[m],
168 corl_flipped[m],
169 cofb_flipped[m],
170 center_cycle[m]
171 };
172
173 return move_via_arrays(&m_arr, cube, f);
174}
175 79
176/* Public functions **********************************************************/ 80/* Public functions **********************************************************/
177 81
178Cube 82void
179apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a) 83apply_alg(Alg *alg, Cube *cube)
180{ 84{
181 Cube ret = {0}; 85 Cube aux;
182 int i; 86 int i;
183 87
88 copy_cube(cube, &aux);
89 make_solved(cube);
90
184 for (i = 0; i < alg->len; i++) 91 for (i = 0; i < alg->len; i++)
185 if (alg->inv[i]) 92 if (alg->inv[i])
186 ret = a ? apply_move(alg->move[i], ret) : 93 apply_move(alg->move[i], cube);
187 apply_move_cubearray(alg->move[i], ret, f);
188 94
189 ret = compose_filtered(c, inverse_cube(ret), f); 95 invert_cube(cube);
96 compose(&aux, cube);
190 97
191 for (i = 0; i < alg->len; i++) 98 for (i = 0; i < alg->len; i++)
192 if (!alg->inv[i]) 99 if (!alg->inv[i])
193 ret = a ? apply_move(alg->move[i], ret) : 100 apply_move(alg->move[i], cube);
194 apply_move_cubearray(alg->move[i], ret, f);
195
196 return ret;
197} 101}
198 102
199Cube 103void
200apply_alg(Alg *alg, Cube cube) 104apply_move(Move m, Cube *cube)
201{ 105{
202 return apply_alg_generic(alg, cube, pf_all, true); 106 compose(&move_array[m], cube);
203}
204
205Cube
206apply_move(Move m, Cube cube)
207{
208 /*init_moves();*/
209
210 return (Cube) {
211 .epose = epose_mtable[m][cube.epose],
212 .eposs = eposs_mtable[m][cube.eposs],
213 .eposm = eposm_mtable[m][cube.eposm],
214 .eofb = eofb_mtable[m][cube.eofb],
215 .eorl = eorl_mtable[m][cube.eorl],
216 .eoud = eoud_mtable[m][cube.eoud],
217 .coud = coud_mtable[m][cube.coud],
218 .cofb = cofb_mtable[m][cube.cofb],
219 .corl = corl_mtable[m][cube.corl],
220 .cp = cp_mtable[m][cube.cp],
221 .cpos = cpos_mtable[m][cube.cpos]
222 };
223} 107}
224 108
225Alg * 109Alg *
@@ -279,31 +163,27 @@ cleanup_aux(Alg *alg, Alg *ret, bool inv)
279{ 163{
280 int i, j; 164 int i, j;
281 Cube c, d; 165 Cube c, d;
282 Move m, mm; 166 Move m;
283 Alg *equiv_alg; 167 Alg *equiv_alg;
284 168
285 c = (Cube){0}; 169 make_solved(&c);
286 for (i = 0; i < alg->len; i++) { 170 for (i = 0; i < alg->len; i++) {
287 if (alg->inv[i] != inv) 171 if (alg->inv[i] != inv)
288 continue; 172 continue;
289 173
290 equiv_alg = new_alg(equiv_alg_string[alg->move[i]]); 174 equiv_alg = new_alg(equiv_alg_string[alg->move[i]]);
291 175
292 for (j = 0; j < equiv_alg->len; j++) { 176 for (j = 0; j < equiv_alg->len; j++)
293 m = equiv_alg->move[j]; 177 if (equiv_alg->move[j] == U)
294 if (m == U) { 178 append_move(ret, 3 * c.xp[U_center] + 1, inv);
295 mm = 3*what_center_at(c, U_center) + 1; 179 else
296 append_move(ret, mm, inv); 180 apply_move(equiv_alg->move[j], &c);
297 } else {
298 c = apply_move(m, c);
299 }
300 }
301 181
302 free_alg(equiv_alg); 182 free_alg(equiv_alg);
303 } 183 }
304 184
305 m = NULLMOVE; 185 m = NULLMOVE;
306 switch (what_center_at(c, F_center)) { 186 switch (c.xp[F_center]) {
307 case U_center: 187 case U_center:
308 m = x3; 188 m = x3;
309 break; 189 break;
@@ -317,7 +197,7 @@ cleanup_aux(Alg *alg, Alg *ret, bool inv)
317 m = y3; 197 m = y3;
318 break; 198 break;
319 case B_center: 199 case B_center:
320 if (what_center_at(c, U_center) == U_center) 200 if (c.xp[U_center] == U_center)
321 m = y2; 201 m = y2;
322 else 202 else
323 m = x2; 203 m = x2;
@@ -325,120 +205,24 @@ cleanup_aux(Alg *alg, Alg *ret, bool inv)
325 default: 205 default:
326 break; 206 break;
327 } 207 }
328 d = apply_move(m, (Cube){0}); 208
209 make_solved(&d);
210 apply_move(m, &d);
329 if (m != NULLMOVE) 211 if (m != NULLMOVE)
330 append_move(ret, m, inv); 212 append_move(ret, m, inv);
331 213
332 m = NULLMOVE; 214 m = NULLMOVE;
333 if (what_center_at(c, U_center) == what_center_at(d, D_center)) { 215 if (c.xp[U_center] == d.xp[D_center]) {
334 m = z2; 216 m = z2;
335 } else if (what_center_at(c, U_center) == what_center_at(d, R_center)) { 217 } else if (c.xp[U_center] == d.xp[R_center]) {
336 m = z3; 218 m = z3;
337 } else if (what_center_at(c, U_center) == what_center_at(d, L_center)) { 219 } else if (c.xp[U_center] == d.xp[L_center]) {
338 m = z; 220 m = z;
339 } 221 }
340 if (m != NULLMOVE) 222 if (m != NULLMOVE)
341 append_move(ret, m, inv); 223 append_move(ret, m, inv);
342} 224}
343 225
344static bool
345read_mtables_file()
346{
347 init_env();
348
349 FILE *f;
350 char fname[strlen(tabledir)+20];
351 int m, b = sizeof(int);
352 bool r = true;
353
354 /* Table sizes, used for reading and writing files */
355 uint64_t me[11] = {
356 [0] = FACTORIAL12/FACTORIAL8,
357 [1] = FACTORIAL12/FACTORIAL8,
358 [2] = FACTORIAL12/FACTORIAL8,
359 [3] = POW2TO11,
360 [4] = POW2TO11,
361 [5] = POW2TO11,
362 [6] = FACTORIAL8,
363 [7] = POW3TO7,
364 [8] = POW3TO7,
365 [9] = POW3TO7,
366 [10] = FACTORIAL6
367 };
368
369 strcpy(fname, tabledir);
370 strcat(fname, "/mtables");
371
372 if ((f = fopen(fname, "rb")) == NULL)
373 return false;
374
375 for (m = 0; m < NMOVES; m++) {
376 r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
377 r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
378 r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
379 r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
380 r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
381 r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
382 r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
383 r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
384 r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
385 r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
386 r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
387 }
388
389 fclose(f);
390 return r;
391}
392
393static bool
394write_mtables_file()
395{
396 init_env();
397
398 FILE *f;
399 char fname[strlen(tabledir)+20];
400 int m, b = sizeof(int);
401 bool r = true;
402
403 /* Table sizes, used for reading and writing files */
404 uint64_t me[11] = {
405 [0] = FACTORIAL12/FACTORIAL8,
406 [1] = FACTORIAL12/FACTORIAL8,
407 [2] = FACTORIAL12/FACTORIAL8,
408 [3] = POW2TO11,
409 [4] = POW2TO11,
410 [5] = POW2TO11,
411 [6] = FACTORIAL8,
412 [7] = POW3TO7,
413 [8] = POW3TO7,
414 [9] = POW3TO7,
415 [10] = FACTORIAL6
416 };
417
418 strcpy(fname, tabledir);
419 strcat(fname, "/mtables");
420
421 if ((f = fopen(fname, "wb")) == NULL)
422 return false;
423
424 for (m = 0; m < NMOVES; m++) {
425 r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
426 r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
427 r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
428 r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
429 r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
430 r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
431 r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
432 r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
433 r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
434 r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
435 r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
436 }
437
438 fclose(f);
439 return r;
440}
441
442void 226void
443init_moves() { 227init_moves() {
444 static bool initialized = false; 228 static bool initialized = false;
@@ -446,101 +230,54 @@ init_moves() {
446 return; 230 return;
447 initialized = true; 231 initialized = true;
448 232
449 Cube c;
450 CubeArray arrs;
451 int i;
452 unsigned int ui;
453 Move m; 233 Move m;
454 Alg *equiv_alg[NMOVES]; 234 Alg *equiv_alg[NMOVES];
455 235
456 init_cube(); 236 static const Cube mcu = {
457 237 .ep = { UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR },
458 for (i = 0; i < NMOVES; i++) 238 .cp = { UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR },
459 equiv_alg[i] = new_alg(equiv_alg_string[i]); 239 };
460 240 static const Cube mcx = {
461 /* Generate all move cycles and flips; I do this regardless */ 241 .ep = { DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR },
462 for (i = 0; i < NMOVES; i++) { 242 .eo = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
463 if (i == U || i == x || i == y) 243 .cp = { DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR },
464 continue; 244 .co = { [UFR] = 2, [UBR] = 1, [UFL] = 1, [UBL] = 2,
465 245 [DBR] = 2, [DFR] = 1, [DBL] = 1, [DFL] = 2 },
466 c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false); 246 .xp = { F_center, B_center, R_center,
467 247 L_center, D_center, U_center },
468 arrs = (CubeArray) { 248 };
469 edge_cycle[i], 249 static const Cube mcy = {
470 eofb_flipped[i], 250 .ep = { UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL },
471 eorl_flipped[i], 251 .eo = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 },
472 eoud_flipped[i], 252 .cp = { UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL },
473 corner_cycle[i], 253 .xp = { U_center, D_center, B_center,
474 coud_flipped[i], 254 F_center, R_center, L_center },
475 corl_flipped[i], 255 };
476 cofb_flipped[i],
477 center_cycle[i]
478 };
479 cube_to_arrays(c, &arrs, pf_all);
480 }
481 256
482 if (read_mtables_file()) 257 move_array[U] = mcu;
483 return; 258 move_array[x] = mcx;
259 move_array[y] = mcy;
484 260
485 fprintf(stderr, "Cannot load %s, generating it\n", "mtables"); 261 for (m = 0; m < NMOVES; m++)
262 equiv_alg[m] = new_alg(equiv_alg_string[m]);
486 263
487 /* Initialize transition tables */
488 for (m = 0; m < NMOVES; m++) { 264 for (m = 0; m < NMOVES; m++) {
489 for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) { 265 switch (m) {
490 c = (Cube){ .epose = ui }; 266 case NULLMOVE:
491 c = apply_move_cubearray(m, c, pf_e); 267 make_solved(&move_array[m]);
492 epose_mtable[m][ui] = c.epose; 268 break;
493 269 case U:
494 c = (Cube){ .eposs = ui }; 270 case x:
495 c = apply_move_cubearray(m, c, pf_s); 271 case y:
496 eposs_mtable[m][ui] = c.eposs; 272 break;
497 273 default:
498 c = (Cube){ .eposm = ui }; 274 make_solved(&move_array[m]);
499 c = apply_move_cubearray(m, c, pf_m); 275 apply_alg(equiv_alg[m], &move_array[m]);
500 eposm_mtable[m][ui] = c.eposm; 276 break;
501 }
502 for (ui = 0; ui < POW2TO11; ui++ ) {
503 c = (Cube){ .eofb = ui };
504 c = apply_move_cubearray(m, c, pf_eo);
505 eofb_mtable[m][ui] = c.eofb;
506
507 c = (Cube){ .eorl = ui };
508 c = apply_move_cubearray(m, c, pf_eo);
509 eorl_mtable[m][ui] = c.eorl;
510
511 c = (Cube){ .eoud = ui };
512 c = apply_move_cubearray(m, c, pf_eo);
513 eoud_mtable[m][ui] = c.eoud;
514 }
515 for (ui = 0; ui < POW3TO7; ui++) {
516 c = (Cube){ .coud = ui };
517 c = apply_move_cubearray(m, c, pf_co);
518 coud_mtable[m][ui] = c.coud;
519
520 c = (Cube){ .corl = ui };
521 c = apply_move_cubearray(m, c, pf_co);
522 corl_mtable[m][ui] = c.corl;
523
524 c = (Cube){ .cofb = ui };
525 c = apply_move_cubearray(m, c, pf_co);
526 cofb_mtable[m][ui] = c.cofb;
527 }
528 for (ui = 0; ui < FACTORIAL8; ui++) {
529 c = (Cube){ .cp = ui };
530 c = apply_move_cubearray(m, c, pf_cp);
531 cp_mtable[m][ui] = c.cp;
532 }
533 for (ui = 0; ui < FACTORIAL6; ui++) {
534 c = (Cube){ .cpos = ui };
535 c = apply_move_cubearray(m, c, pf_cpos);
536 cpos_mtable[m][ui] = c.cpos;
537 } 277 }
538 } 278 }
539 279
540 if (!write_mtables_file()) 280 for (m = 0; m < NMOVES; m++)
541 fprintf(stderr, "Error writing mtables\n"); 281 free_alg(equiv_alg[m]);
542
543 for (i = 0; i < NMOVES; i++)
544 free_alg(equiv_alg[i]);
545} 282}
546 283

Generated with cgit - Back to sebastiano.tronto.net