aboutsummaryrefslogtreecommitdiff
path: root/cube.c
diff options
context:
space:
mode:
Diffstat (limited to 'cube.c')
-rw-r--r--cube.c87
1 files changed, 35 insertions, 52 deletions
diff --git a/cube.c b/cube.c
index 9ca9e68..663f271 100644
--- a/cube.c
+++ b/cube.c
@@ -229,26 +229,6 @@ Some of these routines depend on the efficient functions implemented in the
229previous sections, while some other operate directly on the cube. 229previous sections, while some other operate directly on the cube.
230******************************************************************************/ 230******************************************************************************/
231 231
232#define _premove(M, c) compose_fast(_move_cube_ ## M, c)
233
234#define _foreach_move(_m, _c, _d, instruction) \
235 for (_m = 0; _m < 18; _m++) { _d = move(_c, _m); instruction }
236#define _foreach_trans(_t, _c, _d, instruction) \
237 for (_t = 0; _t < 48; _t++) { _d = transform(_c, _t); instruction }
238
239cube_t solvedcube(void);
240bool isconsistent(cube_t);
241bool issolvable(cube_t);
242bool issolved(cube_t cube);
243bool equal(cube_t, cube_t);
244bool iserror(cube_t);
245cube_t compose(cube_t, cube_t);
246cube_t inverse(cube_t);
247cube_t applymoves(cube_t, char *);
248cube_t applytrans(cube_t, char *);
249cube_t readcube(char *, char *);
250void writecube(char *, cube_t, char *);
251
252_static int permsign(uint8_t *, int); 232_static int permsign(uint8_t *, int);
253_static uint8_t readco(char *); 233_static uint8_t readco(char *);
254_static uint8_t readcp(char *); 234_static uint8_t readcp(char *);
@@ -269,13 +249,23 @@ _static cube_fast_t move(cube_fast_t, move_t);
269_static cube_fast_t transform(cube_fast_t, trans_t); 249_static cube_fast_t transform(cube_fast_t, trans_t);
270 250
271cube_t 251cube_t
272solvedcube(void) 252cube_new(void)
273{ 253{
274 return solved; 254 return solved;
275} 255}
276 256
257cube_t
258cube_clone(cube_t c)
259{
260 cube_t ret;
261
262 memcpy(&ret, &c, sizeof(cube_t));
263
264 return ret;
265}
266
277bool 267bool
278isconsistent(cube_t cube) 268cube_consistent(cube_t cube)
279{ 269{
280 uint8_t i, p, e, piece; 270 uint8_t i, p, e, piece;
281 bool found[12]; 271 bool found[12];
@@ -329,12 +319,12 @@ inconsistent_co:
329} 319}
330 320
331bool 321bool
332issolvable(cube_t cube) 322cube_solvable(cube_t cube)
333{ 323{
334 uint8_t i, eo, co, piece, edges[12], corners[8]; 324 uint8_t i, eo, co, piece, edges[12], corners[8];
335 325
336 DBG_ASSERT(isconsistent(cube), false, 326 DBG_ASSERT(cube_consistent(cube), false,
337 "issolvable: cube is inconsistent\n"); 327 "cube_solvable: cube is inconsistent\n");
338 328
339 for (i = 0; i < 12; i++) 329 for (i = 0; i < 12; i++)
340 edges[i] = cube.edge[i] & _pbits; 330 edges[i] = cube.edge[i] & _pbits;
@@ -342,7 +332,7 @@ issolvable(cube_t cube)
342 corners[i] = cube.corner[i] & _pbits; 332 corners[i] = cube.corner[i] & _pbits;
343 333
344 if (permsign(edges, 12) != permsign(corners, 8)) 334 if (permsign(edges, 12) != permsign(corners, 8))
345 goto issolvable_parity; 335 goto solvable_parity;
346 336
347 eo = 0; 337 eo = 0;
348 for (i = 0; i < 12; i++) { 338 for (i = 0; i < 12; i++) {
@@ -350,7 +340,7 @@ issolvable(cube_t cube)
350 eo += (piece & _eobit) >> _eoshift; 340 eo += (piece & _eobit) >> _eoshift;
351 } 341 }
352 if (eo % 2 != 0) 342 if (eo % 2 != 0)
353 goto issolvable_eo; 343 goto solvable_eo;
354 344
355 co = 0; 345 co = 0;
356 for (i = 0; i < 8; i++) { 346 for (i = 0; i < 8; i++) {
@@ -358,29 +348,29 @@ issolvable(cube_t cube)
358 co += (piece & _cobits) >> _coshift; 348 co += (piece & _cobits) >> _coshift;
359 } 349 }
360 if (co % 3 != 0) 350 if (co % 3 != 0)
361 goto issolvable_co; 351 goto solvable_co;
362 352
363 return true; 353 return true;
364 354
365issolvable_parity: 355solvable_parity:
366 DBG_LOG("EP and CP parities are different\n"); 356 DBG_LOG("EP and CP parities are different\n");
367 return false; 357 return false;
368issolvable_eo: 358solvable_eo:
369 DBG_LOG("Odd number of flipped edges\n"); 359 DBG_LOG("Odd number of flipped edges\n");
370 return false; 360 return false;
371issolvable_co: 361solvable_co:
372 DBG_LOG("Sum of corner orientation is not multiple of 3\n"); 362 DBG_LOG("Sum of corner orientation is not multiple of 3\n");
373 return false; 363 return false;
374} 364}
375 365
376bool 366bool
377issolved(cube_t cube) 367cube_solved(cube_t cube)
378{ 368{
379 return equal(cube, solved); 369 return cube_equal(cube, solved);
380} 370}
381 371
382bool 372bool
383equal(cube_t c1, cube_t c2) 373cube_equal(cube_t c1, cube_t c2)
384{ 374{
385 int i; 375 int i;
386 bool ret; 376 bool ret;
@@ -395,28 +385,28 @@ equal(cube_t c1, cube_t c2)
395} 385}
396 386
397bool 387bool
398iserror(cube_t cube) 388cube_error(cube_t cube)
399{ 389{
400 return equal(cube, zero); 390 return cube_equal(cube, zero);
401} 391}
402 392
403cube_t 393cube_t
404compose(cube_t c1, cube_t c2) 394cube_compose(cube_t c1, cube_t c2)
405{ 395{
406 DBG_ASSERT(isconsistent(c1) && isconsistent(c2), 396 DBG_ASSERT(cube_consistent(c1) && cube_consistent(c2),
407 zero, "compose error: inconsistent cube\n") 397 zero, "cube_compose error: inconsistent cube\n")
408 398
409 return fasttocube(compose_fast(cubetofast(c1), cubetofast(c2))); 399 return fasttocube(compose_fast(cubetofast(c1), cubetofast(c2)));
410} 400}
411 401
412cube_t 402cube_t
413inverse(cube_t cube) 403cube_inverse(cube_t cube)
414{ 404{
415 cube_t ret; 405 cube_t ret;
416 uint8_t i, piece, orien; 406 uint8_t i, piece, orien;
417 407
418 DBG_ASSERT(isconsistent(cube), zero, 408 DBG_ASSERT(cube_consistent(cube), zero,
419 "inverse error: inconsistent cube\n"); 409 "cube_inverse error: inconsistent cube\n");
420 410
421 ret = zero; 411 ret = zero;
422 412
@@ -442,7 +432,7 @@ applymoves(cube_t cube, char *buf)
442 uint8_t r, m; 432 uint8_t r, m;
443 char *b; 433 char *b;
444 434
445 DBG_ASSERT(isconsistent(cube), zero, 435 DBG_ASSERT(cube_consistent(cube), zero,
446 "move error: inconsistent cube\n"); 436 "move error: inconsistent cube\n");
447 437
448 fast = cubetofast(cube); 438 fast = cubetofast(cube);
@@ -473,7 +463,7 @@ applytrans(cube_t cube, char *buf)
473 cube_fast_t fast; 463 cube_fast_t fast;
474 uint8_t t; 464 uint8_t t;
475 465
476 DBG_ASSERT(isconsistent(cube), zero, 466 DBG_ASSERT(cube_consistent(cube), zero,
477 "transformation error: inconsistent cube\n"); 467 "transformation error: inconsistent cube\n");
478 468
479 t = readtrans(buf); 469 t = readtrans(buf);
@@ -506,7 +496,7 @@ writecube(char *format, cube_t cube, char *buf)
506 char *errormsg; 496 char *errormsg;
507 size_t len; 497 size_t len;
508 498
509 if (!isconsistent(cube)) { 499 if (!cube_consistent(cube)) {
510 errormsg = "ERROR: cannot write inconsistent cube"; 500 errormsg = "ERROR: cannot write inconsistent cube";
511 goto writecube_error; 501 goto writecube_error;
512 } 502 }
@@ -837,13 +827,6 @@ transform(cube_fast_t c, trans_t t)
837 invertco_fast(compose_fast(compose_fast(tcube, c), tinv)); 827 invertco_fast(compose_fast(compose_fast(tcube, c), tinv));
838} 828}
839 829
840/******************************************************************************
841Section: moves, move sequences and transformations
842
843This section contains methods to work with moves and arrays of moves. They
844do not rely on the cube structure.
845******************************************************************************/
846
847_static_inline uint8_t inverse_trans(uint8_t); 830_static_inline uint8_t inverse_trans(uint8_t);
848_static_inline uint8_t movebase(uint8_t); 831_static_inline uint8_t movebase(uint8_t);
849_static_inline uint8_t moveaxis(uint8_t); 832_static_inline uint8_t moveaxis(uint8_t);

Generated with cgit - Back to sebastiano.tronto.net