cubecore

A library of core functions for working with 3x3x3 Rubik's cubes
git clone https://git.tronto.net/cubecore
Download | Log | Files | Refs | README | LICENSE

commit a18d4b0ba97b301193597a963a77a40ef7c2254b
parent ae055f1fc993d406939f57f11553d218e1efde82
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Sat, 13 Apr 2024 15:31:32 +0200

Some renaming

Diffstat:
Mcube.c | 87++++++++++++++++++++++++++++++++-----------------------------------------------
Mcube.h | 40+++++++++-------------------------------
Adebugcube.o | 0
Mtest/000_basic/basic_tests.c | 11++++-------
Mtest/001_cube_conversion/cube_conversion_tests.c | 4++--
Mtest/020_io_H48_read_write/io_H48_tests.c | 4++--
Mtest/023_io_LST_write/io_LST_tests.c | 4++--
Mtest/024_io_LST_read/io_LST_tests.c | 4++--
Mtest/030_move/move_tests.c | 4++--
Mtest/040_inverse_cube/inverse_tests.c | 8+++-----
Mtest/050_compose/compose_tests.c | 4++--
Mtest/060_transform/transform_tests.c | 4++--
Mtest/061_inverse_trans/inverse_trans_tests.c | 8++++----
Atest/last.err | 0
Atest/last.out | 1+
Mtest/test.h | 21++-------------------
16 files changed, 72 insertions(+), 132 deletions(-)

diff --git a/cube.c b/cube.c @@ -229,26 +229,6 @@ Some of these routines depend on the efficient functions implemented in the previous sections, while some other operate directly on the cube. ******************************************************************************/ -#define _premove(M, c) compose_fast(_move_cube_ ## M, c) - -#define _foreach_move(_m, _c, _d, instruction) \ - for (_m = 0; _m < 18; _m++) { _d = move(_c, _m); instruction } -#define _foreach_trans(_t, _c, _d, instruction) \ - for (_t = 0; _t < 48; _t++) { _d = transform(_c, _t); instruction } - -cube_t solvedcube(void); -bool isconsistent(cube_t); -bool issolvable(cube_t); -bool issolved(cube_t cube); -bool equal(cube_t, cube_t); -bool iserror(cube_t); -cube_t compose(cube_t, cube_t); -cube_t inverse(cube_t); -cube_t applymoves(cube_t, char *); -cube_t applytrans(cube_t, char *); -cube_t readcube(char *, char *); -void writecube(char *, cube_t, char *); - _static int permsign(uint8_t *, int); _static uint8_t readco(char *); _static uint8_t readcp(char *); @@ -269,13 +249,23 @@ _static cube_fast_t move(cube_fast_t, move_t); _static cube_fast_t transform(cube_fast_t, trans_t); cube_t -solvedcube(void) +cube_new(void) { return solved; } +cube_t +cube_clone(cube_t c) +{ + cube_t ret; + + memcpy(&ret, &c, sizeof(cube_t)); + + return ret; +} + bool -isconsistent(cube_t cube) +cube_consistent(cube_t cube) { uint8_t i, p, e, piece; bool found[12]; @@ -329,12 +319,12 @@ inconsistent_co: } bool -issolvable(cube_t cube) +cube_solvable(cube_t cube) { uint8_t i, eo, co, piece, edges[12], corners[8]; - DBG_ASSERT(isconsistent(cube), false, - "issolvable: cube is inconsistent\n"); + DBG_ASSERT(cube_consistent(cube), false, + "cube_solvable: cube is inconsistent\n"); for (i = 0; i < 12; i++) edges[i] = cube.edge[i] & _pbits; @@ -342,7 +332,7 @@ issolvable(cube_t cube) corners[i] = cube.corner[i] & _pbits; if (permsign(edges, 12) != permsign(corners, 8)) - goto issolvable_parity; + goto solvable_parity; eo = 0; for (i = 0; i < 12; i++) { @@ -350,7 +340,7 @@ issolvable(cube_t cube) eo += (piece & _eobit) >> _eoshift; } if (eo % 2 != 0) - goto issolvable_eo; + goto solvable_eo; co = 0; for (i = 0; i < 8; i++) { @@ -358,29 +348,29 @@ issolvable(cube_t cube) co += (piece & _cobits) >> _coshift; } if (co % 3 != 0) - goto issolvable_co; + goto solvable_co; return true; -issolvable_parity: +solvable_parity: DBG_LOG("EP and CP parities are different\n"); return false; -issolvable_eo: +solvable_eo: DBG_LOG("Odd number of flipped edges\n"); return false; -issolvable_co: +solvable_co: DBG_LOG("Sum of corner orientation is not multiple of 3\n"); return false; } bool -issolved(cube_t cube) +cube_solved(cube_t cube) { - return equal(cube, solved); + return cube_equal(cube, solved); } bool -equal(cube_t c1, cube_t c2) +cube_equal(cube_t c1, cube_t c2) { int i; bool ret; @@ -395,28 +385,28 @@ equal(cube_t c1, cube_t c2) } bool -iserror(cube_t cube) +cube_error(cube_t cube) { - return equal(cube, zero); + return cube_equal(cube, zero); } cube_t -compose(cube_t c1, cube_t c2) +cube_compose(cube_t c1, cube_t c2) { - DBG_ASSERT(isconsistent(c1) && isconsistent(c2), - zero, "compose error: inconsistent cube\n") + DBG_ASSERT(cube_consistent(c1) && cube_consistent(c2), + zero, "cube_compose error: inconsistent cube\n") return fasttocube(compose_fast(cubetofast(c1), cubetofast(c2))); } cube_t -inverse(cube_t cube) +cube_inverse(cube_t cube) { cube_t ret; uint8_t i, piece, orien; - DBG_ASSERT(isconsistent(cube), zero, - "inverse error: inconsistent cube\n"); + DBG_ASSERT(cube_consistent(cube), zero, + "cube_inverse error: inconsistent cube\n"); ret = zero; @@ -442,7 +432,7 @@ applymoves(cube_t cube, char *buf) uint8_t r, m; char *b; - DBG_ASSERT(isconsistent(cube), zero, + DBG_ASSERT(cube_consistent(cube), zero, "move error: inconsistent cube\n"); fast = cubetofast(cube); @@ -473,7 +463,7 @@ applytrans(cube_t cube, char *buf) cube_fast_t fast; uint8_t t; - DBG_ASSERT(isconsistent(cube), zero, + DBG_ASSERT(cube_consistent(cube), zero, "transformation error: inconsistent cube\n"); t = readtrans(buf); @@ -506,7 +496,7 @@ writecube(char *format, cube_t cube, char *buf) char *errormsg; size_t len; - if (!isconsistent(cube)) { + if (!cube_consistent(cube)) { errormsg = "ERROR: cannot write inconsistent cube"; goto writecube_error; } @@ -837,13 +827,6 @@ transform(cube_fast_t c, trans_t t) invertco_fast(compose_fast(compose_fast(tcube, c), tinv)); } -/****************************************************************************** -Section: moves, move sequences and transformations - -This section contains methods to work with moves and arrays of moves. They -do not rely on the cube structure. -******************************************************************************/ - _static_inline uint8_t inverse_trans(uint8_t); _static_inline uint8_t movebase(uint8_t); _static_inline uint8_t moveaxis(uint8_t); diff --git a/cube.h b/cube.h @@ -16,13 +16,6 @@ corners is with respect to U/D. The permutation of the center pieces is not stored. This means that the cube is assumed to be in a fixed orientation. - -TODO: define EO and CO better, explain how to use them -TODO: encode centers? - -The exact cube type structure depends on your system's configuration. If -you operate on the cube only via the functions provided below, you don't -need to worry about this. ******************************************************************************/ typedef struct { @@ -30,30 +23,15 @@ typedef struct { uint8_t edge[12]; } cube_t; -/* Returns a copy of the solved cube */ -cube_t solvedcube(void); - -/* Basic checks on the cube */ -bool isconsistent(cube_t); -bool issolvable(cube_t); -bool issolved(cube_t); -bool equal(cube_t, cube_t); - -/* All functions can return an error value, use iserror() to check this */ -bool iserror(cube_t); - -/* Apply the second cube on the first as a move sequence */ -cube_t compose(cube_t, cube_t); - -/* Invert the cube */ -cube_t inverse(cube_t); - -/* Check if a cube represent a valid state (possibly unsolvable) */ - -/* TODO comment on these and the format for moves and trans */ -/* For trans, only one trans is supported */ -cube_t applymoves(cube_t, char *); -cube_t applytrans(cube_t, char *); +cube_t cube_new(void); +cube_t cube_clone(cube_t); +bool cube_consistent(cube_t); +bool cube_solvable(cube_t); +bool cube_solved(cube_t); +bool cube_equal(cube_t, cube_t); +bool cube_error(cube_t); +cube_t cube_compose(cube_t, cube_t); +cube_t cube_inverse(cube_t); /****************************************************************************** Read / write utilities diff --git a/debugcube.o b/debugcube.o Binary files differ. diff --git a/test/000_basic/basic_tests.c b/test/000_basic/basic_tests.c @@ -1,27 +1,24 @@ #include "../test.h" -bool issolved(cube_t); -bool equal(cube_t, cube_t); - void check(cube_t cube, char *name) { - printf("%s is%s solvable\n", name, issolvable(cube) ? "" : " NOT"); - printf("%s is%s solved\n", name, issolved(cube) ? "" : " NOT"); + printf("%s is%s solvable\n", name, cube_solvable(cube) ? "" : " NOT"); + printf("%s is%s solved\n", name, cube_solved(cube) ? "" : " NOT"); } void check2(cube_t cube1, char *name1, cube_t cube2, char *name2) { printf("%s and %s are%s equal\n", name1, name2, - equal(cube1, cube2) ? "" : " NOT"); + cube_equal(cube1, cube2) ? "" : " NOT"); } int main(void) { cube_t zero, solved; memset(&zero, 0, sizeof(cube_t)); - solved = solvedcube(); + solved = cube_new(); check(solved, "Solved"); check(zero, "Zero"); diff --git a/test/001_cube_conversion/cube_conversion_tests.c b/test/001_cube_conversion/cube_conversion_tests.c @@ -14,9 +14,9 @@ int main(void) { fast = cubetofast(cube); cube2 = fasttocube(fast); - if (iserror(cube)) { + if (cube_error(cube)) { printf("Error reading cube\n"); - } else if (iserror(cube2)) { + } else if (cube_error(cube2)) { printf("Error converting cube\n"); } else { writecube("H48", cube2, cubestr); diff --git a/test/020_io_H48_read_write/io_H48_tests.c b/test/020_io_H48_read_write/io_H48_tests.c @@ -11,9 +11,9 @@ int main(void) { cube = readcube("H48", str); - if (iserror(cube)) { + if (cube_error(cube)) { printf("Error reading cube\n"); - } else if (!issolvable(cube)) { + } else if (!cube_solvable(cube)) { printf("Cube is not solvable\n"); } else { writecube("H48", cube, str); diff --git a/test/023_io_LST_write/io_LST_tests.c b/test/023_io_LST_write/io_LST_tests.c @@ -11,9 +11,9 @@ int main(void) { cube = readcube("H48", str); - if (iserror(cube)) { + if (cube_error(cube)) { printf("Error reading cube\n"); - } else if (!issolvable(cube)) { + } else if (!cube_solvable(cube)) { printf("Cube is not solvable\n"); } else { writecube("LST", cube, str); diff --git a/test/024_io_LST_read/io_LST_tests.c b/test/024_io_LST_read/io_LST_tests.c @@ -11,9 +11,9 @@ int main(void) { cube = readcube("LST", str); - if (iserror(cube)) { + if (cube_error(cube)) { printf("Error reading cube\n"); - } else if (!issolvable(cube)) { + } else if (!cube_solvable(cube)) { printf("Cube is not solvable\n"); } else { writecube("H48", cube, str); diff --git a/test/030_move/move_tests.c b/test/030_move/move_tests.c @@ -12,9 +12,9 @@ int main(void) { cube = applymoves(cube, movestr); - if (iserror(cube)) { + if (cube_error(cube)) { printf("Error moving cube\n"); - } else if (!issolvable(cube)) { + } else if (!cube_solvable(cube)) { printf("Moved cube is not solvable\n"); } else { writecube("H48", cube, cubestr); diff --git a/test/040_inverse_cube/inverse_tests.c b/test/040_inverse_cube/inverse_tests.c @@ -1,18 +1,16 @@ #include "../test.h" -cube_t inverse(cube_t); - int main(void) { char str[STRLENMAX]; cube_t cube, inv; fgets(str, STRLENMAX, stdin); cube = readcube("H48", str); - inv = inverse(cube); + inv = cube_inverse(cube); - if (iserror(inv)) { + if (cube_error(inv)) { printf("Error inverting cube\n"); - } else if (!issolvable(inv)) { + } else if (!cube_solvable(inv)) { printf("Inverted cube is not solvable\n"); } else { writecube("H48", inv, str); diff --git a/test/050_compose/compose_tests.c b/test/050_compose/compose_tests.c @@ -13,9 +13,9 @@ int main(void) { c3 = compose(c1, c2); - if (iserror(c3)) { + if (cube_error(c3)) { printf("Error composing cubes\n"); - } else if (!issolvable(c3)) { + } else if (!cube_solvable(c3)) { printf("Composed cube is not solvable\n"); } else { writecube("H48", c3, str); diff --git a/test/060_transform/transform_tests.c b/test/060_transform/transform_tests.c @@ -12,9 +12,9 @@ int main(void) { cube = applytrans(cube, transtr); - if (iserror(cube)) { + if (cube_error(cube)) { printf("Error transforming cube\n"); - } else if (!issolvable(cube)) { + } else if (!cube_solvable(cube)) { printf("Transformed cube is not solvable\n"); } else { writecube("H48", cube, cubestr); diff --git a/test/061_inverse_trans/inverse_trans_tests.c b/test/061_inverse_trans/inverse_trans_tests.c @@ -11,7 +11,7 @@ int main(void) { cube_t cube; for (t = 0; t < 48; t++) { - cube = solvedcube(); + cube = cube_new(); cube = applymoves(cube, "R"); cube = applymoves(cube, "U"); cube = applymoves(cube, "F"); @@ -20,15 +20,15 @@ int main(void) { tinv = inverse_trans(t); cube = applytrans(cube, transstr[tinv]); - if (iserror(cube)) { + if (cube_error(cube)) { printf("Error transforming cube\n"); - } else if (!issolvable(cube)) { + } else if (!cube_solvable(cube)) { printf("Transformed cube is not solvable\n"); } else { cube = applymoves(cube, "F'"); cube = applymoves(cube, "U'"); cube = applymoves(cube, "R'"); - if (!issolved(cube)) + if (!cube_solved(cube)) printf("%s: Error! Got %" PRIu8 "\n", transstr[t], tinv); } diff --git a/test/last.err b/test/last.err diff --git a/test/last.out b/test/last.out @@ -0,0 +1 @@ +UL1 UB0 DL1 UR0 BL1 DR1 BR0 DB0 FL1 UF0 FR1 DF0 DFR2 DFL0 DBL0 UFL0 UBR1 UBL0 UFR2 DBR1 diff --git a/test/test.h b/test/test.h @@ -4,24 +4,7 @@ #include <stdlib.h> #include <string.h> -#define STRLENMAX 10000 - -typedef struct { - uint8_t corner[8]; - uint8_t edge[12]; -} cube_t; +#include "../cube.h" -#ifdef CUBE_AVX2 -#include <immintrin.h> -typedef __m256i cube_fast_t; -#else +#define STRLENMAX 10000 typedef cube_t cube_fast_t; -#endif - -/* Basic functions used in most tests */ -cube_t solvedcube(void); -bool iserror(cube_t); -bool issolvable(cube_t); -bool issolved(cube_t); -cube_t readcube(char *, char *); -void writecube(char *, cube_t, char *);