aboutsummaryrefslogtreecommitdiff
path: root/src/moves.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano.tronto@gmail.com>2020-06-21 23:01:57 +0200
committerSebastiano Tronto <sebastiano.tronto@gmail.com>2020-06-21 23:01:57 +0200
commit0e8d73bb3edcc8bdff6e3ded442b66f68265059a (patch)
tree4f92deb9ace97e79332c0e7ce390b76b81aeaae9 /src/moves.c
parent4e359b44ce111b04cc4d2b28033fba4ab4e6e989 (diff)
downloadnissy-0e8d73bb3edcc8bdff6e3ded442b66f68265059a.tar.gz
nissy-0e8d73bb3edcc8bdff6e3ded442b66f68265059a.zip
First push
Diffstat (limited to 'src/moves.c')
-rw-r--r--src/moves.c526
1 files changed, 526 insertions, 0 deletions
diff --git a/src/moves.c b/src/moves.c
new file mode 100644
index 0000000..15d5dad
--- /dev/null
+++ b/src/moves.c
@@ -0,0 +1,526 @@
1/* This is a simple program to solve the Rubik's Cube.
2 * No idea how many features I am going to implement.
3 * Open source license and whatnot.
4 * I am trying to follow the C99 standard. */
5
6/* This file contains the definitions of the basic moves of the cube.
7 * There is no object or type representing the cube.
8 * Data about the cube can be represented by arrays (describing the position
9 * of pieces of certain types), integers (representing for example a bitmask
10 * for the orientation of pieces of certain type, or the permutation index of
11 * an array representing the permutation of pieces).
12 * Each of the moves functions operates on one such piece of data.
13 *
14 * For example, a way of representing the cube can be:
15 * - An integer eo, which is a bitmask for the orientation of the edges.
16 * - An integer co, same for corners.
17 * - An array ep[12], where a[i]=j means that the edge j is in place i.
18 * - An integer cp representing the permutation index of a permutation array
19 * which is the analogue of that described for edges.
20 *
21 * Different representations will be used for different use-cases. */
22
23#include "coordinates.h"
24#include "moves.h"
25
26/* possible_next[i][j] is a bitmask representing the possible
27 * next moves we can apply. For example, if the last moves a 0 R then it does
28 * not make sense to apply R, R2 or R'. If they are U D2 it does not make
29 * sense to apply any U* or D*. */
30int possible_next[19][19];
31
32int parallel(int m1, int m2) {
33 if (m1 == 0 || m2 == 0) return 0;
34 return ((m1-1)/6 == (m2-1)/6);
35}
36
37int compute_possible_next(int last1, int last2) {
38 if (last1 == 0) return move_mask_all;
39
40 /* Removes the 2 or ' (e.g. turns U2 to U, R' to R). */
41 last2 = (last2 == 0) ? last2 : 3*((last2-1)/3) + 1;
42 last1 = 3*((last1-1)/3) + 1;
43
44 int mask = move_mask_all ^ (7 << last1);
45
46 if (parallel(last1, last2))
47 mask ^= 7 << last2;
48 else if (last1 % 6 == 4) /*Always U before D, R before L, F before B*/
49 mask ^= 7 << (last1-3);
50
51 return mask;
52}
53
54void init_possible_next() {
55 for (int i = 0; i < 19; i++)
56 for (int j = 0; j < 19; j++)
57 possible_next[i][j] = compute_possible_next(i, j);
58}
59
60/* Piece cycles depending on the move. For example edge_cycle[U2][UF]
61 * gives the piece in position UF after applying U2 to a solved cube */
62
63int edge_cycle[19][12] = {
64 {UF, UL, UB, UR, DF, DL, DB, DR, FR, FL, BL, BR}, /* - */
65 {UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR}, /* U */
66 {UB, UR, UF, UL, DF, DL, DB, DR, FR, FL, BL, BR}, /* U2 */
67 {UL, UB, UR, UF, DF, DL, DB, DR, FR, FL, BL, BR}, /* U' */
68 {UF, UL, UB, UR, DL, DB, DR, DF, FR, FL, BL, BR}, /* D */
69 {UF, UL, UB, UR, DB, DR, DF, DL, FR, FL, BL, BR}, /* D2 */
70 {UF, UL, UB, UR, DR, DF, DL, DB, FR, FL, BL, BR}, /* D' */
71 {UF, UL, UB, FR, DF, DL, DB, BR, DR, FL, BL, UR}, /* R */
72 {UF, UL, UB, DR, DF, DL, DB, UR, BR, FL, BL, FR}, /* R2 */
73 {UF, UL, UB, BR, DF, DL, DB, FR, UR, FL, BL, DR}, /* R' */
74 {UF, BL, UB, UR, DF, FL, DB, DR, FR, UL, DL, BR}, /* L */
75 {UF, DL, UB, UR, DF, UL, DB, DR, FR, BL, FL, BR}, /* L2 */
76 {UF, FL, UB, UR, DF, BL, DB, DR, FR, DL, UL, BR}, /* L' */
77 {FL, UL, UB, UR, FR, DL, DB, DR, UF, DF, BL, BR}, /* F */
78 {DF, UL, UB, UR, UF, DL, DB, DR, FL, FR, BL, BR}, /* F2 */
79 {FR, UL, UB, UR, FL, DL, DB, DR, DF, UF, BL, BR}, /* F' */
80 {UF, UL, BR, UR, DF, DL, BL, DR, FR, FL, UB, DB}, /* B */
81 {UF, UL, DB, UR, DF, DL, UB, DR, FR, FL, BR, BL}, /* B2 */
82 {UF, UL, BL, UR, DF, DL, BR, DR, FR, FL, DB, UB} /* B' */
83};
84
85int corner_cycle[19][8] = {
86 {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR}, /* - */
87 {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR}, /* U */
88 {UBL, UBR, UFR, UFL, DFR, DFL, DBL, DBR}, /* U2 */
89 {UFL, UBL, UBR, UFR, DFR, DFL, DBL, DBR}, /* U' */
90 {UFR, UFL, UBL, UBR, DFL, DBL, DBR, DFR}, /* D */
91 {UFR, UFL, UBL, UBR, DBL, DBR, DFR, DFL}, /* D2 */
92 {UFR, UFL, UBL, UBR, DBR, DFR, DFL, DBL}, /* D' */
93 {DFR, UFL, UBL, UFR, DBR, DFL, DBL, UBR}, /* R */
94 {DBR, UFL, UBL, DFR, UBR, DFL, DBL, UFR}, /* R2 */
95 {UBR, UFL, UBL, DBR, UFR, DFL, DBL, DFR}, /* R' */
96 {UFR, UBL, DBL, UBR, DFR, UFL, DFL, DBR}, /* L */
97 {UFR, DBL, DFL, UBR, DFR, UBL, UFL, DBR}, /* L2 */
98 {UFR, DFL, UFL, UBR, DFR, DBL, UBL, DBR}, /* L' */
99 {UFL, DFL, UBL, UBR, UFR, DFR, DBL, DBR}, /* F */
100 {DFL, DFR, UBL, UBR, UFL, UFR, DBL, DBR}, /* F2 */
101 {DFR, UFR, UBL, UBR, DFL, UFL, DBL, DBR}, /* F' */
102 {UFR, UFL, UBR, DBR, DFR, DFL, UBL, DBL}, /* B */
103 {UFR, UFL, DBR, DBL, DFR, DFL, UBR, UBL}, /* B2 */
104 {UFR, UFL, DBL, UBL, DFR, DFL, DBR, UBR}, /* U' */
105};
106
107/* Transition tables */
108
109int eofb_transition_table[pow2to11][19];
110int eorl_transition_table[pow2to11][19];
111int eoud_transition_table[pow2to11][19];
112int coud_transition_table[pow3to7][19];
113int cofb_transition_table[pow3to7][19];
114int corl_transition_table[pow3to7][19];
115int epud_transition_table[factorial8][19];
116int eprl_transition_table[factorial8][19];
117int epfb_transition_table[factorial8][19];
118int epose_transition_table[binom12on4][19];
119int eposs_transition_table[binom12on4][19];
120int eposm_transition_table[binom12on4][19];
121int epe_transition_table[factorial4][19];
122int eps_transition_table[factorial4][19];
123int epm_transition_table[factorial4][19];
124int emslices_transition_table[binom12on4*binom8on4][19];
125int cp_transition_table[factorial8][19];
126
127/***/
128/* Functions for permuting pieces (given in array format) */
129/***/
130
131void apply_move_ep_array(int move, int ep[12]) {
132 int aux[12];
133 for (int i = 0; i < 12; i++)
134 aux[i] = ep[i];
135 for (int i = 0; i < 12; i++)
136 ep[i] = aux[edge_cycle[move][i]];
137}
138
139void apply_move_cp_array(int move, int cp[8]) {
140 int aux[8];
141 for (int i = 0; i < 8; i++)
142 aux[i] = cp[i];
143 for (int i = 0; i < 8; i++)
144 cp[i] = aux[corner_cycle[move][i]];
145}
146
147/***/
148/* Functions for permuting pieces (given in integer format) */
149/***/
150
151int apply_move_ep_int(int move, int ep) {
152 int a[12];
153 ep_int_to_array(ep, a);
154 apply_move_ep_array(move, a);
155 return ep_array_to_int(a);
156}
157
158int apply_move_epud_int(int move, int ep) {
159 int a[12];
160 epud_int_to_array(ep, a);
161 apply_move_ep_array(move, a);
162 return epud_array_to_int(a);
163}
164
165int apply_move_eprl_int(int move, int ep) {
166 int a[12];
167 eprl_int_to_array(ep, a);
168 apply_move_ep_array(move, a);
169 return eprl_array_to_int(a);
170}
171
172int apply_move_epfb_int(int move, int ep) {
173 int a[12];
174 epfb_int_to_array(ep, a);
175 apply_move_ep_array(move, a);
176 return epfb_array_to_int(a);
177}
178
179int apply_move_epose_int(int move, int ep) {
180 int a[12];
181 epose_int_to_array(ep, a);
182 apply_move_ep_array(move, a);
183 return epose_array_to_int(a);
184}
185
186int apply_move_eposs_int(int move, int ep) {
187 int a[12];
188 eposs_int_to_array(ep, a);
189 apply_move_ep_array(move, a);
190 return eposs_array_to_int(a);
191}
192
193int apply_move_eposm_int(int move, int ep) {
194 int a[12];
195 eposm_int_to_array(ep, a);
196 apply_move_ep_array(move, a);
197 return eposm_array_to_int(a);
198}
199
200int apply_move_epe_int(int move, int ep) {
201 int a[12];
202 epe_int_to_array(ep, a);
203 apply_move_ep_array(move, a);
204 return epe_array_to_int(a);
205}
206
207int apply_move_eps_int(int move, int ep) {
208 int a[12];
209 eps_int_to_array(ep, a);
210 apply_move_ep_array(move, a);
211 return eps_array_to_int(a);
212}
213
214int apply_move_epm_int(int move, int ep) {
215 int a[12];
216 epm_int_to_array(ep, a);
217 apply_move_ep_array(move, a);
218 return epm_array_to_int(a);
219}
220
221int apply_move_emslices_int(int move, int e) {
222 int a[12];
223 emslices_int_to_array(e, a);
224 apply_move_ep_array(move, a);
225 return emslices_array_to_int(a);
226}
227
228int apply_move_cp_int(int move, int cp) {
229 int a[8];
230 cp_int_to_array(cp, a);
231 apply_move_cp_array(move, a);
232 return cp_array_to_int(a);
233}
234
235int apply_move_eofb_int(int move, int eo) {
236 int a[12];
237 eo_11bits_to_array(eo, a);
238 apply_move_ep_array(move, a);
239 /* Change edge orientation */
240 if (move == F || move == F3) {
241 a[UF] = 1 - a[UF];
242 a[DF] = 1 - a[DF];
243 a[FR] = 1 - a[FR];
244 a[FL] = 1 - a[FL];
245 }
246 if (move == B || move == B3) {
247 a[UB] = 1 - a[UB];
248 a[DB] = 1 - a[DB];
249 a[BL] = 1 - a[BL];
250 a[BR] = 1 - a[BR];
251 }
252 return eo_array_to_11bits(a);
253}
254
255int apply_move_eorl_int(int move, int eo) {
256 int a[12];
257 eo_11bits_to_array(eo, a);
258 apply_move_ep_array(move, a);
259 /* Change edge orientation */
260 if (move == R || move == R3) {
261 a[UR] = 1 - a[UR];
262 a[DR] = 1 - a[DR];
263 a[FR] = 1 - a[FR];
264 a[BR] = 1 - a[BR];
265 }
266 if (move == L || move == L3) {
267 a[UL] = 1 - a[UL];
268 a[DL] = 1 - a[DL];
269 a[FL] = 1 - a[FL];
270 a[BL] = 1 - a[BL];
271 }
272 return eo_array_to_11bits(a);
273}
274
275int apply_move_eoud_int(int move, int eo) {
276 int a[12];
277 eo_11bits_to_array(eo, a);
278 apply_move_ep_array(move, a);
279 /* Change edge orientation */
280 if (move == U || move == U3) {
281 a[UF] = 1 - a[UF];
282 a[UL] = 1 - a[UL];
283 a[UB] = 1 - a[UB];
284 a[UR] = 1 - a[UR];
285 }
286 if (move == D || move == D3) {
287 a[DF] = 1 - a[DF];
288 a[DL] = 1 - a[DL];
289 a[DB] = 1 - a[DB];
290 a[DR] = 1 - a[DR];
291 }
292 return eo_array_to_11bits(a);
293}
294
295int apply_move_coud_int(int move, int co) {
296 int a[8];
297 co_7trits_to_array(co, a);
298 apply_move_cp_array(move, a);
299 /* Change corner orientation */
300 if (move == R || move == R3) {
301 a[UFR] = (a[UFR] + 2) % 3;
302 a[UBR] = (a[UBR] + 1) % 3;
303 a[DBR] = (a[DBR] + 2) % 3;
304 a[DFR] = (a[DFR] + 1) % 3;
305 }
306 if (move == L || move == L3) {
307 a[UBL] = (a[UBL] + 2) % 3;
308 a[UFL] = (a[UFL] + 1) % 3;
309 a[DFL] = (a[DFL] + 2) % 3;
310 a[DBL] = (a[DBL] + 1) % 3;
311 }
312 if (move == F || move == F3) {
313 a[UFL] = (a[UFL] + 2) % 3;
314 a[UFR] = (a[UFR] + 1) % 3;
315 a[DFR] = (a[DFR] + 2) % 3;
316 a[DFL] = (a[DFL] + 1) % 3;
317 }
318 if (move == B || move == B3) {
319 a[UBR] = (a[UBR] + 2) % 3;
320 a[UBL] = (a[UBL] + 1) % 3;
321 a[DBL] = (a[DBL] + 2) % 3;
322 a[DBR] = (a[DBR] + 1) % 3;
323 }
324 return co_array_to_7trits(a);
325}
326
327int apply_move_cofb_int(int move, int co) {
328 int a[8];
329 co_7trits_to_array(co, a);
330 apply_move_cp_array(move, a);
331 /* Change corner orientation */
332 if (move == R || move == R3) {
333 a[UFR] = (a[UFR] + 1) % 3;
334 a[UBR] = (a[UBR] + 2) % 3;
335 a[DBR] = (a[DBR] + 1) % 3;
336 a[DFR] = (a[DFR] + 2) % 3;
337 }
338 if (move == L || move == L3) {
339 a[UBL] = (a[UBL] + 1) % 3;
340 a[UFL] = (a[UFL] + 2) % 3;
341 a[DFL] = (a[DFL] + 1) % 3;
342 a[DBL] = (a[DBL] + 2) % 3;
343 }
344 if (move == U || move == U3) {
345 a[UFL] = (a[UFL] + 1) % 3;
346 a[UFR] = (a[UFR] + 2) % 3;
347 a[UBL] = (a[UBL] + 2) % 3;
348 a[UBR] = (a[UBR] + 1) % 3;
349 }
350 if (move == D || move == D3) {
351 a[DFL] = (a[DFL] + 2) % 3;
352 a[DFR] = (a[DFR] + 1) % 3;
353 a[DBL] = (a[DBL] + 1) % 3;
354 a[DBR] = (a[DBR] + 2) % 3;
355 }
356 return co_array_to_7trits(a);
357}
358
359int apply_move_corl_int(int move, int co) {
360 int a[8];
361 co_7trits_to_array(co, a);
362 apply_move_cp_array(move, a);
363 /* Change corner orientation */
364 if (move == F || move == F3) {
365 a[UFR] = (a[UFR] + 2) % 3;
366 a[UFL] = (a[UFL] + 1) % 3;
367 a[DFL] = (a[DFL] + 2) % 3;
368 a[DFR] = (a[DFR] + 1) % 3;
369 }
370 if (move == B || move == B3) {
371 a[UBL] = (a[UBL] + 2) % 3;
372 a[UBR] = (a[UBR] + 1) % 3;
373 a[DBR] = (a[DBR] + 2) % 3;
374 a[DBL] = (a[DBL] + 1) % 3;
375 }
376 if (move == U || move == U3) {
377 a[UFL] = (a[UFL] + 2) % 3;
378 a[UFR] = (a[UFR] + 1) % 3;
379 a[UBL] = (a[UBL] + 1) % 3;
380 a[UBR] = (a[UBR] + 2) % 3;
381 }
382 if (move == D || move == D3) {
383 a[DFL] = (a[DFL] + 1) % 3;
384 a[DFR] = (a[DFR] + 2) % 3;
385 a[DBL] = (a[DBL] + 2) % 3;
386 a[DBR] = (a[DBR] + 1) % 3;
387 }
388 return co_array_to_7trits(a);
389}
390
391
392
393/* Initialize transition tables */
394
395void init_epud_transition_table() {
396 for (int i = 0; i < factorial8; i++)
397 for (int j = 0; j < 19; j++)
398 if (move_mask_drud & (1 << j))
399 epud_transition_table[i][j] = apply_move_epud_int(j, i);
400}
401
402void init_eprl_transition_table() {
403 for (int i = 0; i < factorial8; i++)
404 for (int j = 0; j < 19; j++)
405 if (move_mask_drrl & (1 << j))
406 eprl_transition_table[i][j] = apply_move_eprl_int(j, i);
407}
408
409void init_epfb_transition_table() {
410 for (int i = 0; i < factorial8; i++)
411 for (int j = 0; j < 19; j++)
412 if (move_mask_drfb & (1 << j))
413 epfb_transition_table[i][j] = apply_move_epfb_int(j, i);
414}
415
416void init_epose_transition_table() {
417 for (int i = 0; i < binom12on4; i++)
418 for (int j = 0; j < 19; j++)
419 epose_transition_table[i][j] = apply_move_epose_int(j, i);
420}
421
422void init_eposs_transition_table() {
423 for (int i = 0; i < binom12on4; i++)
424 for (int j = 0; j < 19; j++)
425 eposs_transition_table[i][j] = apply_move_eposs_int(j, i);
426}
427
428void init_eposm_transition_table() {
429 for (int i = 0; i < binom12on4; i++)
430 for (int j = 0; j < 19; j++)
431 eposm_transition_table[i][j] = apply_move_eposm_int(j, i);
432}
433
434void init_epe_transition_table() {
435 for (int i = 0; i < factorial4; i++) {
436 for (int j = 0; j < 19; j++)
437 if (move_mask_drud & (1 << j))
438 epe_transition_table[i][j] = apply_move_epe_int(j, i);
439 }
440}
441
442void init_eps_transition_table() {
443 for (int i = 0; i < factorial4; i++) {
444 for (int j = 0; j < 19; j++)
445 if (move_mask_drfb & (1 << j))
446 eps_transition_table[i][j] = apply_move_eps_int(j, i);
447 }
448}
449
450void init_epm_transition_table() {
451 for (int i = 0; i < factorial4; i++) {
452 for (int j = 0; j < 19; j++)
453 if (move_mask_drrl & (1 << j))
454 epm_transition_table[i][j] = apply_move_epm_int(j, i);
455 }
456}
457
458void init_emslices_transition_table() {
459 for (int i = 0; i < binom12on4*binom8on4; i++) {
460 for (int j = 0; j < 19; j++)
461 emslices_transition_table[i][j] = apply_move_emslices_int(j, i);
462 }
463}
464
465void init_cp_transition_table() {
466 for (int i = 0; i < factorial8; i++)
467 for (int j = 0; j < 19; j++)
468 cp_transition_table[i][j] = apply_move_cp_int(j, i);
469}
470
471void init_eofb_transition_table() {
472 for (int i = 0; i < pow2to11; i++)
473 for (int j = 0; j < 19; j++)
474 eofb_transition_table[i][j] = apply_move_eofb_int(j, i);
475}
476
477void init_eorl_transition_table() {
478 for (int i = 0; i < pow2to11; i++)
479 for (int j = 0; j < 19; j++)
480 eorl_transition_table[i][j] = apply_move_eorl_int(j, i);
481}
482
483void init_eoud_transition_table() {
484 for (int i = 0; i < pow2to11; i++)
485 for (int j = 0; j < 19; j++)
486 eoud_transition_table[i][j] = apply_move_eoud_int(j, i);
487}
488
489void init_coud_transition_table() {
490 for (int i = 0; i < pow3to7; i++)
491 for (int j = 0; j < 19; j++ )
492 coud_transition_table[i][j] = apply_move_coud_int(j, i);
493}
494
495void init_cofb_transition_table() {
496 for (int i = 0; i < pow3to7; i++)
497 for (int j = 0; j < 19; j++ )
498 cofb_transition_table[i][j] = apply_move_cofb_int(j, i);
499}
500
501void init_corl_transition_table() {
502 for (int i = 0; i < pow3to7; i++)
503 for (int j = 0; j < 19; j++ )
504 corl_transition_table[i][j] = apply_move_corl_int(j, i);
505}
506
507void init_transition_table() {
508 init_epud_transition_table();
509 init_eprl_transition_table();
510 init_epfb_transition_table();
511 init_epose_transition_table();
512 init_eposs_transition_table();
513 init_eposm_transition_table();
514 init_epe_transition_table();
515 init_eps_transition_table();
516 init_epm_transition_table();
517 init_emslices_transition_table();
518 init_cp_transition_table();
519 init_eofb_transition_table();
520 init_eorl_transition_table();
521 init_eoud_transition_table();
522 init_coud_transition_table();
523 init_cofb_transition_table();
524 init_corl_transition_table();
525}
526

Generated with cgit - Back to sebastiano.tronto.net