aboutsummaryrefslogtreecommitdiff
path: root/src/cube_generic.h
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-06-09 12:43:49 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-06-09 12:43:49 +0200
commitc5c5017a335208881e27fc8f72c1d0145a04622a (patch)
tree7a1518e5b05f3fbde810fa3080c41099ba7d5ae8 /src/cube_generic.h
parent28ad019d62583b7e89b4e76922aa73857d5876eb (diff)
downloadnissy-core-c5c5017a335208881e27fc8f72c1d0145a04622a.tar.gz
nissy-core-c5c5017a335208881e27fc8f72c1d0145a04622a.zip
Remvoed cube_fast_t and more. More cleaning up to do.
Diffstat (limited to '')
-rw-r--r--src/cube_generic.h (renamed from src/cube_routines.h)228
1 files changed, 131 insertions, 97 deletions
diff --git a/src/cube_routines.h b/src/cube_generic.h
index 3730e90..a90aa17 100644
--- a/src/cube_routines.h
+++ b/src/cube_generic.h
@@ -1,15 +1,18 @@
1#define _move(M, c) compose_fast(c, _move_cube_ ## M) 1#define _move(M, c) compose(c, _move_cube_ ## M)
2#define _premove(M, c) compose_fast(_move_cube_ ## M, c) 2#define _premove(M, c) compose(_move_cube_ ## M, c)
3 3
4_static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]);
4_static int permsign(uint8_t *, int); 5_static int permsign(uint8_t *, int);
5_static uint8_t readco(const char *); 6_static uint8_t readco(const char *);
6_static uint8_t readcp(const char *); 7_static uint8_t readcp(const char *);
7_static uint8_t readeo(const char *); 8_static uint8_t readeo(const char *);
8_static uint8_t readep(const char *); 9_static uint8_t readep(const char *);
10_static cube_t readcube_B32(const char *);
9_static cube_t readcube_H48(const char *); 11_static cube_t readcube_H48(const char *);
10_static uint8_t readpiece_LST(const char **); 12_static uint8_t readpiece_LST(const char **);
11_static cube_t readcube_LST(const char *); 13_static cube_t readcube_LST(const char *);
12_static int writepiece_LST(uint8_t, char *); 14_static int writepiece_LST(uint8_t, char *);
15_static void writecube_B32(cube_t, char *);
13_static void writecube_H48(cube_t, char *); 16_static void writecube_H48(cube_t, char *);
14_static void writecube_LST(cube_t, char *); 17_static void writecube_LST(cube_t, char *);
15_static uint8_t b32toedge(char); 18_static uint8_t b32toedge(char);
@@ -21,10 +24,31 @@ _static uint8_t readmodifier(char);
21_static uint8_t readtrans(const char *); 24_static uint8_t readtrans(const char *);
22_static int writemoves(uint8_t *, int, char *); 25_static int writemoves(uint8_t *, int, char *);
23_static void writetrans(uint8_t, char *); 26_static void writetrans(uint8_t, char *);
24_static cube_fast_t move(cube_fast_t, uint8_t); 27_static cube_t move(cube_t, uint8_t);
25_static cube_fast_t transform_edges(cube_fast_t, uint8_t); 28_static cube_t transform_edges(cube_t, uint8_t);
26_static cube_fast_t transform_corners(cube_fast_t, uint8_t); 29_static cube_t transform_corners(cube_t, uint8_t);
27_static cube_fast_t transform(cube_fast_t, uint8_t); 30_static cube_t transform(cube_t, uint8_t);
31
32_static struct {
33 const char *name;
34 cube_t (*read)(const char *);
35 void (*write)(cube_t, char *);
36} ioformat[] =
37{
38 { .name = "B32", .read = readcube_B32, .write = writecube_B32 },
39 { .name = "LST", .read = readcube_LST, .write = writecube_LST },
40 { .name = "H48", .read = readcube_H48, .write = writecube_H48 },
41 { .name = "NONE", .read = NULL, .write = NULL },
42};
43
44_static_inline cube_t
45cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
46{
47 return static_cube(
48 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
49 e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7],
50 e[8], e[9], e[10], e[11]);
51}
28 52
29cube_t 53cube_t
30solvedcube(void) 54solvedcube(void)
@@ -35,13 +59,15 @@ solvedcube(void)
35bool 59bool
36isconsistent(cube_t cube) 60isconsistent(cube_t cube)
37{ 61{
38 uint8_t i, p, e, piece; 62 uint8_t i, p, e, piece, corner[8], edge[12];
39 bool found[12]; 63 bool found[12];
40 64
65 pieces(&cube, corner, edge);
66
41 for (i = 0; i < 12; i++) 67 for (i = 0; i < 12; i++)
42 found[i] = false; 68 found[i] = false;
43 for (i = 0; i < 12; i++) { 69 for (i = 0; i < 12; i++) {
44 piece = cube.edge[i]; 70 piece = edge[i];
45 p = piece & _pbits; 71 p = piece & _pbits;
46 e = piece & _eobit; 72 e = piece & _eobit;
47 if (p >= 12) 73 if (p >= 12)
@@ -57,7 +83,7 @@ isconsistent(cube_t cube)
57 for (i = 0; i < 8; i++) 83 for (i = 0; i < 8; i++)
58 found[i] = false; 84 found[i] = false;
59 for (i = 0; i < 8; i++) { 85 for (i = 0; i < 8; i++) {
60 piece = cube.corner[i]; 86 piece = corner[i];
61 p = piece & _pbits; 87 p = piece & _pbits;
62 e = piece & _cobits; 88 e = piece & _cobits;
63 if (p >= 8) 89 if (p >= 8)
@@ -89,22 +115,23 @@ inconsistent_co:
89bool 115bool
90issolvable(cube_t cube) 116issolvable(cube_t cube)
91{ 117{
92 uint8_t i, eo, co, piece, edges[12], corners[8]; 118 uint8_t i, eo, co, piece, edge[12], corner[8], ep[12], cp[8];
93 119
94 DBG_ASSERT(isconsistent(cube), false, 120 DBG_ASSERT(isconsistent(cube), false,
95 "issolvable: cube is inconsistent\n"); 121 "issolvable: cube is inconsistent\n");
96 122
123 pieces(&cube, corner, edge);
97 for (i = 0; i < 12; i++) 124 for (i = 0; i < 12; i++)
98 edges[i] = cube.edge[i] & _pbits; 125 ep[i] = edge[i] & _pbits;
99 for (i = 0; i < 8; i++) 126 for (i = 0; i < 8; i++)
100 corners[i] = cube.corner[i] & _pbits; 127 cp[i] = corner[i] & _pbits;
101 128
102 if (permsign(edges, 12) != permsign(corners, 8)) 129 if (permsign(ep, 12) != permsign(cp, 8))
103 goto issolvable_parity; 130 goto issolvable_parity;
104 131
105 eo = 0; 132 eo = 0;
106 for (i = 0; i < 12; i++) { 133 for (i = 0; i < 12; i++) {
107 piece = cube.edge[i]; 134 piece = edge[i];
108 eo += (piece & _eobit) >> _eoshift; 135 eo += (piece & _eobit) >> _eoshift;
109 } 136 }
110 if (eo % 2 != 0) 137 if (eo % 2 != 0)
@@ -112,7 +139,7 @@ issolvable(cube_t cube)
112 139
113 co = 0; 140 co = 0;
114 for (i = 0; i < 8; i++) { 141 for (i = 0; i < 8; i++) {
115 piece = cube.corner[i]; 142 piece = corner[i];
116 co += (piece & _cobits) >> _coshift; 143 co += (piece & _cobits) >> _coshift;
117 } 144 }
118 if (co % 3 != 0) 145 if (co % 3 != 0)
@@ -138,73 +165,45 @@ issolved(cube_t cube)
138} 165}
139 166
140bool 167bool
141equal(cube_t c1, cube_t c2)
142{
143 int i;
144 bool ret;
145
146 ret = true;
147 for (i = 0; i < 8; i++)
148 ret = ret && c1.corner[i] == c2.corner[i];
149 for (i = 0; i < 12; i++)
150 ret = ret && c1.edge[i] == c2.edge[i];
151
152 return ret;
153}
154
155bool
156iserror(cube_t cube) 168iserror(cube_t cube)
157{ 169{
158 return equal(cube, zero); 170 return equal(cube, zero);
159} 171}
160 172
161cube_t 173cube_t
162compose(cube_t c1, cube_t c2)
163{
164 DBG_ASSERT(isconsistent(c1) && isconsistent(c2),
165 zero, "compose error: inconsistent cube\n")
166
167 return fasttocube(compose_fast(cubetofast(c1), cubetofast(c2)));
168}
169
170cube_t
171inverse(cube_t cube) 174inverse(cube_t cube)
172{ 175{
173 cube_t ret; 176 uint8_t i, piece, orien, e[12], c[8], edge[12], corner[8];
174 uint8_t i, piece, orien;
175 177
176 DBG_ASSERT(isconsistent(cube), zero, 178 DBG_ASSERT(isconsistent(cube), zero,
177 "inverse error: inconsistent cube\n"); 179 "inverse error: inconsistent cube\n");
178 180
179 ret = zero; 181 pieces(&cube, corner, edge);
180 182
181 for (i = 0; i < 12; i++) { 183 for (i = 0; i < 12; i++) {
182 piece = cube.edge[i]; 184 piece = edge[i];
183 orien = piece & _eobit; 185 orien = piece & _eobit;
184 ret.edge[piece & _pbits] = i | orien; 186 e[piece & _pbits] = i | orien;
185 } 187 }
186 188
187 for (i = 0; i < 8; i++) { 189 for (i = 0; i < 8; i++) {
188 piece = cube.corner[i]; 190 piece = corner[i];
189 orien = ((piece << 1) | (piece >> 1)) & _cobits2; 191 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
190 ret.corner[piece & _pbits] = i | orien; 192 c[piece & _pbits] = i | orien;
191 } 193 }
192 194
193 return ret; 195 return cubefromarray(c, e);
194} 196}
195 197
196cube_t 198cube_t
197applymoves(cube_t cube, const char *buf) 199applymoves(cube_t cube, const char *buf)
198{ 200{
199 cube_fast_t fast;
200 uint8_t r, m; 201 uint8_t r, m;
201 const char *b; 202 const char *b;
202 203
203 DBG_ASSERT(isconsistent(cube), zero, 204 DBG_ASSERT(isconsistent(cube), zero,
204 "move error: inconsistent cube\n"); 205 "move error: inconsistent cube\n");
205 206
206 fast = cubetofast(cube);
207
208 for (b = buf; *b != '\0'; b++) { 207 for (b = buf; *b != '\0'; b++) {
209 while (*b == ' ' || *b == '\t' || *b == '\n') 208 while (*b == ' ' || *b == '\t' || *b == '\n')
210 b++; 209 b++;
@@ -214,11 +213,11 @@ applymoves(cube_t cube, const char *buf)
214 goto applymoves_error; 213 goto applymoves_error;
215 if ((m = readmodifier(*(b+1))) != 0) 214 if ((m = readmodifier(*(b+1))) != 0)
216 b++; 215 b++;
217 fast = move(fast, r + m); 216 cube = move(cube, r + m);
218 } 217 }
219 218
220applymoves_finish: 219applymoves_finish:
221 return fasttocube(fast); 220 return cube;
222 221
223applymoves_error: 222applymoves_error:
224 DBG_LOG("applymoves error\n"); 223 DBG_LOG("applymoves error\n");
@@ -228,34 +227,27 @@ applymoves_error:
228cube_t 227cube_t
229applytrans(cube_t cube, const char *buf) 228applytrans(cube_t cube, const char *buf)
230{ 229{
231 cube_fast_t fast;
232 uint8_t t; 230 uint8_t t;
233 231
234 DBG_ASSERT(isconsistent(cube), zero, 232 DBG_ASSERT(isconsistent(cube), zero,
235 "transformation error: inconsistent cube\n"); 233 "transformation error: inconsistent cube\n");
236 234
237 t = readtrans(buf); 235 t = readtrans(buf);
238 fast = cubetofast(cube);
239 fast = transform(fast, t);
240 236
241 return fasttocube(fast); 237 return transform(cube, t);
242} 238}
243 239
244cube_t 240cube_t
245readcube(const char *format, const char *buf) 241readcube(const char *format, const char *buf)
246{ 242{
247 cube_t cube; 243 int i;
248 244
249 if (!strcmp(format, "H48")) { 245 for (i = 0; ioformat[i].read != NULL; i++)
250 cube = readcube_H48(buf); 246 if (!strcmp(format, ioformat[i].name))
251 } else if (!strcmp(format, "LST")) { 247 return ioformat[i].read(buf);
252 cube = readcube_LST(buf);
253 } else {
254 DBG_LOG("Cannot read cube in the given format\n");
255 cube = zero;
256 }
257 248
258 return cube; 249 DBG_LOG("Cannot read cube in the given format\n");
250 return zero;
259} 251}
260 252
261void 253void
@@ -269,16 +261,16 @@ writecube(const char *format, cube_t cube, char *buf)
269 goto writecube_error; 261 goto writecube_error;
270 } 262 }
271 263
272 if (!strcmp(format, "H48")) { 264 int i;
273 writecube_H48(cube, buf); 265
274 } else if (!strcmp(format, "LST")) { 266 for (i = 0; ioformat[i].write != NULL; i++) {
275 writecube_LST(cube, buf); 267 if (!strcmp(format, ioformat[i].name)) {
276 } else { 268 ioformat[i].write(cube, buf);
277 errormsg = "ERROR: cannot write cube in the given format"; 269 return;
278 goto writecube_error; 270 }
279 } 271 }
280 272
281 return; 273 errormsg = "ERROR: cannot write cube in the given format";
282 274
283writecube_error: 275writecube_error:
284 DBG_LOG("writecube error, see stdout for details\n"); 276 DBG_LOG("writecube error, see stdout for details\n");
@@ -355,11 +347,31 @@ readep(const char *str)
355} 347}
356 348
357_static cube_t 349_static cube_t
350readcube_B32(const char *buf)
351{
352 int i;
353 uint8_t c[8], e[12];
354
355 for (i = 0; i < 8; i++) {
356 c[i] = b32tocorner(buf[i]);
357 DBG_ASSERT(c[i] < 255, zero,
358 "Error reading B32 corner %d (char %d)\n", i, i);
359 }
360
361 for (i = 0; i < 12; i++) {
362 e[i] = b32toedge(buf[i+9]);
363 DBG_ASSERT(e[i] < 255, zero,
364 "Error reading B32 edge %d (char %d)\n", i, i+9);
365 }
366
367 return cubefromarray(c, e);
368}
369
370_static cube_t
358readcube_H48(const char *buf) 371readcube_H48(const char *buf)
359{ 372{
360 int i; 373 int i;
361 uint8_t piece, orient; 374 uint8_t piece, orient, c[8], e[12];
362 cube_t ret = {0};
363 const char *b; 375 const char *b;
364 376
365 b = buf; 377 b = buf;
@@ -373,7 +385,7 @@ readcube_H48(const char *buf)
373 if ((orient = readeo(b)) == _error) 385 if ((orient = readeo(b)) == _error)
374 return zero; 386 return zero;
375 b++; 387 b++;
376 ret.edge[i] = piece | orient; 388 e[i] = piece | orient;
377 } 389 }
378 for (i = 0; i < 8; i++) { 390 for (i = 0; i < 8; i++) {
379 while (*b == ' ' || *b == '\t' || *b == '\n') 391 while (*b == ' ' || *b == '\t' || *b == '\n')
@@ -384,10 +396,10 @@ readcube_H48(const char *buf)
384 if ((orient = readco(b)) == _error) 396 if ((orient = readco(b)) == _error)
385 return zero; 397 return zero;
386 b++; 398 b++;
387 ret.corner[i] = piece | orient; 399 c[i] = piece | orient;
388 } 400 }
389 401
390 return ret; 402 return cubefromarray(c, e);
391} 403}
392 404
393_static uint8_t 405_static uint8_t
@@ -411,15 +423,15 @@ _static cube_t
411readcube_LST(const char *buf) 423readcube_LST(const char *buf)
412{ 424{
413 int i; 425 int i;
414 cube_t ret = {0}; 426 uint8_t c[8], e[12];
415 427
416 for (i = 0; i < 8; i++) 428 for (i = 0; i < 8; i++)
417 ret.corner[i] = readpiece_LST(&buf); 429 c[i] = readpiece_LST(&buf);
418 430
419 for (i = 0; i < 12; i++) 431 for (i = 0; i < 12; i++)
420 ret.edge[i] = readpiece_LST(&buf); 432 e[i] = readpiece_LST(&buf);
421 433
422 return ret; 434 return cubefromarray(c, e);
423} 435}
424 436
425_static int 437_static int
@@ -447,13 +459,34 @@ writepiece_LST(uint8_t piece, char *buf)
447} 459}
448 460
449_static void 461_static void
462writecube_B32(cube_t cube, char *buf)
463{
464 int i;
465 uint8_t corner[8], edge[12];
466
467 pieces(&cube, corner, edge);
468
469 for (i = 0; i < 8; i++)
470 buf[i] = cornertob32(corner[i]);
471
472 buf[8] = '=';
473
474 for (i = 0; i < 12; i++)
475 buf[i+9] = edgetob32(edge[i]);
476
477 buf[21] = '\0';
478}
479
480_static void
450writecube_H48(cube_t cube, char *buf) 481writecube_H48(cube_t cube, char *buf)
451{ 482{
452 uint8_t piece, perm, orient; 483 uint8_t piece, perm, orient, corner[8], edge[12];
453 int i; 484 int i;
454 485
486 pieces(&cube, corner, edge);
487
455 for (i = 0; i < 12; i++) { 488 for (i = 0; i < 12; i++) {
456 piece = cube.edge[i]; 489 piece = edge[i];
457 perm = piece & _pbits; 490 perm = piece & _pbits;
458 orient = (piece & _eobit) >> _eoshift; 491 orient = (piece & _eobit) >> _eoshift;
459 buf[4*i ] = edgestr[perm][0]; 492 buf[4*i ] = edgestr[perm][0];
@@ -462,7 +495,7 @@ writecube_H48(cube_t cube, char *buf)
462 buf[4*i + 3] = ' '; 495 buf[4*i + 3] = ' ';
463 } 496 }
464 for (i = 0; i < 8; i++) { 497 for (i = 0; i < 8; i++) {
465 piece = cube.corner[i]; 498 piece = corner[i];
466 perm = piece & _pbits; 499 perm = piece & _pbits;
467 orient = (piece & _cobits) >> _coshift; 500 orient = (piece & _cobits) >> _coshift;
468 buf[48 + 5*i ] = cornerstr[perm][0]; 501 buf[48 + 5*i ] = cornerstr[perm][0];
@@ -480,17 +513,18 @@ writecube_LST(cube_t cube, char *buf)
480{ 513{
481 int i; 514 int i;
482 size_t ptr; 515 size_t ptr;
483 uint8_t piece; 516 uint8_t piece, corner[8], edge[12];
484 517
485 ptr = 0; 518 ptr = 0;
519 pieces(&cube, corner, edge);
486 520
487 for (i = 0; i < 8; i++) { 521 for (i = 0; i < 8; i++) {
488 piece = cube.corner[i]; 522 piece = corner[i];
489 ptr += writepiece_LST(piece, buf + ptr); 523 ptr += writepiece_LST(piece, buf + ptr);
490 } 524 }
491 525
492 for (i = 0; i < 12; i++) { 526 for (i = 0; i < 12; i++) {
493 piece = cube.edge[i]; 527 piece = edge[i];
494 ptr += writepiece_LST(piece, buf + ptr); 528 ptr += writepiece_LST(piece, buf + ptr);
495 } 529 }
496 530
@@ -500,8 +534,8 @@ writecube_LST(cube_t cube, char *buf)
500_static uint8_t 534_static uint8_t
501b32toedge(char c) 535b32toedge(char c)
502{ 536{
503 DBG_ASSERT((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'), 255, 537 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
504 "Error reading base32 piece"); 538 return 255;
505 539
506 return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a'); 540 return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a');
507} 541}
@@ -510,8 +544,8 @@ _static uint8_t
510b32tocorner(char c) { 544b32tocorner(char c) {
511 uint8_t val; 545 uint8_t val;
512 546
513 DBG_ASSERT((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'), 255, 547 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
514 "Error reading base32 piece"); 548 return 255;
515 549
516 val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26; 550 val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26;
517 551
@@ -616,8 +650,8 @@ writetrans(uint8_t t, char *buf)
616 buf[11] = '\0'; 650 buf[11] = '\0';
617} 651}
618 652
619_static cube_fast_t 653_static cube_t
620move(cube_fast_t c, uint8_t m) 654move(cube_t c, uint8_t m)
621{ 655{
622 switch (m) { 656 switch (m) {
623 case _move_U: 657 case _move_U:
@@ -658,7 +692,7 @@ move(cube_fast_t c, uint8_t m)
658 return _move(B3, c); 692 return _move(B3, c);
659 default: 693 default:
660 DBG_LOG("move error, unknown move\n"); 694 DBG_LOG("move error, unknown move\n");
661 return zero_fast; 695 return zero;
662 } 696 }
663} 697}
664 698

Generated with cgit - Back to sebastiano.tronto.net