From c5c5017a335208881e27fc8f72c1d0145a04622a Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Sun, 9 Jun 2024 12:43:49 +0200 Subject: Remvoed cube_fast_t and more. More cleaning up to do. --- src/cube_routines.h | 668 ---------------------------------------------------- 1 file changed, 668 deletions(-) delete mode 100644 src/cube_routines.h (limited to 'src/cube_routines.h') diff --git a/src/cube_routines.h b/src/cube_routines.h deleted file mode 100644 index 3730e90..0000000 --- a/src/cube_routines.h +++ /dev/null @@ -1,668 +0,0 @@ -#define _move(M, c) compose_fast(c, _move_cube_ ## M) -#define _premove(M, c) compose_fast(_move_cube_ ## M, c) - -_static int permsign(uint8_t *, int); -_static uint8_t readco(const char *); -_static uint8_t readcp(const char *); -_static uint8_t readeo(const char *); -_static uint8_t readep(const char *); -_static cube_t readcube_H48(const char *); -_static uint8_t readpiece_LST(const char **); -_static cube_t readcube_LST(const char *); -_static int writepiece_LST(uint8_t, char *); -_static void writecube_H48(cube_t, char *); -_static void writecube_LST(cube_t, char *); -_static uint8_t b32toedge(char); -_static uint8_t b32tocorner(char); -_static char edgetob32(uint8_t); -_static char cornertob32(uint8_t); -_static uint8_t readmove(char); -_static uint8_t readmodifier(char); -_static uint8_t readtrans(const char *); -_static int writemoves(uint8_t *, int, char *); -_static void writetrans(uint8_t, char *); -_static cube_fast_t move(cube_fast_t, uint8_t); -_static cube_fast_t transform_edges(cube_fast_t, uint8_t); -_static cube_fast_t transform_corners(cube_fast_t, uint8_t); -_static cube_fast_t transform(cube_fast_t, uint8_t); - -cube_t -solvedcube(void) -{ - return solved; -} - -bool -isconsistent(cube_t cube) -{ - uint8_t i, p, e, piece; - bool found[12]; - - for (i = 0; i < 12; i++) - found[i] = false; - for (i = 0; i < 12; i++) { - piece = cube.edge[i]; - p = piece & _pbits; - e = piece & _eobit; - if (p >= 12) - goto inconsistent_ep; - if (e != 0 && e != _eobit) - goto inconsistent_eo; - found[p] = true; - } - for (i = 0; i < 12; i++) - if (!found[i]) - goto inconsistent_ep; - - for (i = 0; i < 8; i++) - found[i] = false; - for (i = 0; i < 8; i++) { - piece = cube.corner[i]; - p = piece & _pbits; - e = piece & _cobits; - if (p >= 8) - goto inconsistent_cp; - if (e != 0 && e != _ctwist_cw && e != _ctwist_ccw) - goto inconsistent_co; - found[p] = true; - } - for (i = 0; i < 8; i++) - if (!found[i]) - goto inconsistent_co; - - return true; - -inconsistent_ep: - DBG_LOG("Inconsistent EP\n"); - return false; -inconsistent_cp: - DBG_LOG("Inconsistent CP\n"); - return false; -inconsistent_eo: - DBG_LOG("Inconsistent EO\n"); - return false; -inconsistent_co: - DBG_LOG("Inconsistent CO\n"); - return false; -} - -bool -issolvable(cube_t cube) -{ - uint8_t i, eo, co, piece, edges[12], corners[8]; - - DBG_ASSERT(isconsistent(cube), false, - "issolvable: cube is inconsistent\n"); - - for (i = 0; i < 12; i++) - edges[i] = cube.edge[i] & _pbits; - for (i = 0; i < 8; i++) - corners[i] = cube.corner[i] & _pbits; - - if (permsign(edges, 12) != permsign(corners, 8)) - goto issolvable_parity; - - eo = 0; - for (i = 0; i < 12; i++) { - piece = cube.edge[i]; - eo += (piece & _eobit) >> _eoshift; - } - if (eo % 2 != 0) - goto issolvable_eo; - - co = 0; - for (i = 0; i < 8; i++) { - piece = cube.corner[i]; - co += (piece & _cobits) >> _coshift; - } - if (co % 3 != 0) - goto issolvable_co; - - return true; - -issolvable_parity: - DBG_LOG("EP and CP parities are different\n"); - return false; -issolvable_eo: - DBG_LOG("Odd number of flipped edges\n"); - return false; -issolvable_co: - DBG_LOG("Sum of corner orientation is not multiple of 3\n"); - return false; -} - -bool -issolved(cube_t cube) -{ - return equal(cube, solved); -} - -bool -equal(cube_t c1, cube_t c2) -{ - int i; - bool ret; - - ret = true; - for (i = 0; i < 8; i++) - ret = ret && c1.corner[i] == c2.corner[i]; - for (i = 0; i < 12; i++) - ret = ret && c1.edge[i] == c2.edge[i]; - - return ret; -} - -bool -iserror(cube_t cube) -{ - return equal(cube, zero); -} - -cube_t -compose(cube_t c1, cube_t c2) -{ - DBG_ASSERT(isconsistent(c1) && isconsistent(c2), - zero, "compose error: inconsistent cube\n") - - return fasttocube(compose_fast(cubetofast(c1), cubetofast(c2))); -} - -cube_t -inverse(cube_t cube) -{ - cube_t ret; - uint8_t i, piece, orien; - - DBG_ASSERT(isconsistent(cube), zero, - "inverse error: inconsistent cube\n"); - - ret = zero; - - for (i = 0; i < 12; i++) { - piece = cube.edge[i]; - orien = piece & _eobit; - ret.edge[piece & _pbits] = i | orien; - } - - for (i = 0; i < 8; i++) { - piece = cube.corner[i]; - orien = ((piece << 1) | (piece >> 1)) & _cobits2; - ret.corner[piece & _pbits] = i | orien; - } - - return ret; -} - -cube_t -applymoves(cube_t cube, const char *buf) -{ - cube_fast_t fast; - uint8_t r, m; - const char *b; - - DBG_ASSERT(isconsistent(cube), zero, - "move error: inconsistent cube\n"); - - fast = cubetofast(cube); - - for (b = buf; *b != '\0'; b++) { - while (*b == ' ' || *b == '\t' || *b == '\n') - b++; - if (*b == '\0') - goto applymoves_finish; - if ((r = readmove(*b)) == _error) - goto applymoves_error; - if ((m = readmodifier(*(b+1))) != 0) - b++; - fast = move(fast, r + m); - } - -applymoves_finish: - return fasttocube(fast); - -applymoves_error: - DBG_LOG("applymoves error\n"); - return zero; -} - -cube_t -applytrans(cube_t cube, const char *buf) -{ - cube_fast_t fast; - uint8_t t; - - DBG_ASSERT(isconsistent(cube), zero, - "transformation error: inconsistent cube\n"); - - t = readtrans(buf); - fast = cubetofast(cube); - fast = transform(fast, t); - - return fasttocube(fast); -} - -cube_t -readcube(const char *format, const char *buf) -{ - cube_t cube; - - if (!strcmp(format, "H48")) { - cube = readcube_H48(buf); - } else if (!strcmp(format, "LST")) { - cube = readcube_LST(buf); - } else { - DBG_LOG("Cannot read cube in the given format\n"); - cube = zero; - } - - return cube; -} - -void -writecube(const char *format, cube_t cube, char *buf) -{ - char *errormsg; - size_t len; - - if (!isconsistent(cube)) { - errormsg = "ERROR: cannot write inconsistent cube"; - goto writecube_error; - } - - if (!strcmp(format, "H48")) { - writecube_H48(cube, buf); - } else if (!strcmp(format, "LST")) { - writecube_LST(cube, buf); - } else { - errormsg = "ERROR: cannot write cube in the given format"; - goto writecube_error; - } - - return; - -writecube_error: - DBG_LOG("writecube error, see stdout for details\n"); - len = strlen(errormsg); - memcpy(buf, errormsg, len); - buf[len] = '\n'; - buf[len+1] = '\0'; -} - -_static int -permsign(uint8_t *a, int n) -{ - int i, j; - uint8_t ret = 0; - - for (i = 0; i < n; i++) - for (j = i+1; j < n; j++) - ret += a[i] > a[j] ? 1 : 0; - - return ret % 2; -} - -_static uint8_t -readco(const char *str) -{ - if (*str == '0') - return 0; - if (*str == '1') - return _ctwist_cw; - if (*str == '2') - return _ctwist_ccw; - - DBG_LOG("Error reading CO\n"); - return _error; -} - -_static uint8_t -readcp(const char *str) -{ - uint8_t c; - - for (c = 0; c < 8; c++) - if (!strncmp(str, cornerstr[c], 3) || - !strncmp(str, cornerstralt[c], 3)) - return c; - - DBG_LOG("Error reading CP\n"); - return _error; -} - -_static uint8_t -readeo(const char *str) -{ - if (*str == '0') - return 0; - if (*str == '1') - return _eflip; - - DBG_LOG("Error reading EO\n"); - return _error; -} - -_static uint8_t -readep(const char *str) -{ - uint8_t e; - - for (e = 0; e < 12; e++) - if (!strncmp(str, edgestr[e], 2)) - return e; - - DBG_LOG("Error reading EP\n"); - return _error; -} - -_static cube_t -readcube_H48(const char *buf) -{ - int i; - uint8_t piece, orient; - cube_t ret = {0}; - const char *b; - - b = buf; - - for (i = 0; i < 12; i++) { - while (*b == ' ' || *b == '\t' || *b == '\n') - b++; - if ((piece = readep(b)) == _error) - return zero; - b += 2; - if ((orient = readeo(b)) == _error) - return zero; - b++; - ret.edge[i] = piece | orient; - } - for (i = 0; i < 8; i++) { - while (*b == ' ' || *b == '\t' || *b == '\n') - b++; - if ((piece = readcp(b)) == _error) - return zero; - b += 3; - if ((orient = readco(b)) == _error) - return zero; - b++; - ret.corner[i] = piece | orient; - } - - return ret; -} - -_static uint8_t -readpiece_LST(const char **b) -{ - uint8_t ret; - bool read; - - while (**b == ',' || **b == ' ' || **b == '\t' || **b == '\n') - (*b)++; - - for (ret = 0, read = false; **b >= '0' && **b <= '9'; (*b)++) { - read = true; - ret = ret * 10 + (**b) - '0'; - } - - return read ? ret : _error; -} - -_static cube_t -readcube_LST(const char *buf) -{ - int i; - cube_t ret = {0}; - - for (i = 0; i < 8; i++) - ret.corner[i] = readpiece_LST(&buf); - - for (i = 0; i < 12; i++) - ret.edge[i] = readpiece_LST(&buf); - - return ret; -} - -_static int -writepiece_LST(uint8_t piece, char *buf) -{ - char digits[3]; - int i, len; - - len = 0; - while (piece != 0) { - digits[len++] = (piece % 10) + '0'; - piece /= 10; - } - - if (len == 0) - digits[len++] = '0'; - - for (i = 0; i < len; i++) - buf[i] = digits[len-i-1]; - - buf[len] = ','; - buf[len+1] = ' '; - - return len+2; -} - -_static void -writecube_H48(cube_t cube, char *buf) -{ - uint8_t piece, perm, orient; - int i; - - for (i = 0; i < 12; i++) { - piece = cube.edge[i]; - perm = piece & _pbits; - orient = (piece & _eobit) >> _eoshift; - buf[4*i ] = edgestr[perm][0]; - buf[4*i + 1] = edgestr[perm][1]; - buf[4*i + 2] = orient + '0'; - buf[4*i + 3] = ' '; - } - for (i = 0; i < 8; i++) { - piece = cube.corner[i]; - perm = piece & _pbits; - orient = (piece & _cobits) >> _coshift; - buf[48 + 5*i ] = cornerstr[perm][0]; - buf[48 + 5*i + 1] = cornerstr[perm][1]; - buf[48 + 5*i + 2] = cornerstr[perm][2]; - buf[48 + 5*i + 3] = orient + '0'; - buf[48 + 5*i + 4] = ' '; - } - - buf[48+39] = '\0'; -} - -_static void -writecube_LST(cube_t cube, char *buf) -{ - int i; - size_t ptr; - uint8_t piece; - - ptr = 0; - - for (i = 0; i < 8; i++) { - piece = cube.corner[i]; - ptr += writepiece_LST(piece, buf + ptr); - } - - for (i = 0; i < 12; i++) { - piece = cube.edge[i]; - ptr += writepiece_LST(piece, buf + ptr); - } - - *(buf+ptr-2) = 0; -} - -_static uint8_t -b32toedge(char c) -{ - DBG_ASSERT((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'), 255, - "Error reading base32 piece"); - - return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a'); -} - -_static uint8_t -b32tocorner(char c) { - uint8_t val; - - DBG_ASSERT((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'), 255, - "Error reading base32 piece"); - - val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26; - - return (val & 7) | ((val & 24) << 2); -} - -_static char -edgetob32(uint8_t edge) -{ - return edge <= 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26); -} - -_static char -cornertob32(uint8_t corner) -{ - uint8_t val; - - val = (corner & 7) | ((corner & 96) >> 2); - - return val <= 26 ? 'A' + (char)val : 'a' + (char)(val - 26); -} - -_static uint8_t -readmove(char c) -{ - switch (c) { - case 'U': - return _move_U; - case 'D': - return _move_D; - case 'R': - return _move_R; - case 'L': - return _move_L; - case 'F': - return _move_F; - case 'B': - return _move_B; - default: - return _error; - } -} - -_static uint8_t -readmodifier(char c) -{ - switch (c) { - case '1': /* Fallthrough */ - case '2': /* Fallthrough */ - case '3': - return c - '0' - 1; - case '\'': - return 2; - default: - return 0; - } -} - -_static uint8_t -readtrans(const char *buf) -{ - uint8_t t; - - for (t = 0; t < 48; t++) - if (!strncmp(buf, transstr[t], 11)) - return t; - - DBG_LOG("readtrans error\n"); - return _error; -} - -_static int -writemoves(uint8_t *m, int n, char *buf) -{ - int i; - size_t len; - const char *s; - char *b; - - for (i = 0, b = buf; i < n; i++, b++) { - s = movestr[m[i]]; - len = strlen(s); - memcpy(b, s, len); - b += len; - *b = ' '; - } - - if (b != buf) - b--; /* Remove last space */ - *b = '\0'; - - return b - buf; -} - -_static void -writetrans(uint8_t t, char *buf) -{ - if (t >= 48) - memcpy(buf, "error trans", 11); - else - memcpy(buf, transstr[t], 11); - buf[11] = '\0'; -} - -_static cube_fast_t -move(cube_fast_t c, uint8_t m) -{ - switch (m) { - case _move_U: - return _move(U, c); - case _move_U2: - return _move(U2, c); - case _move_U3: - return _move(U3, c); - case _move_D: - return _move(D, c); - case _move_D2: - return _move(D2, c); - case _move_D3: - return _move(D3, c); - case _move_R: - return _move(R, c); - case _move_R2: - return _move(R2, c); - case _move_R3: - return _move(R3, c); - case _move_L: - return _move(L, c); - case _move_L2: - return _move(L2, c); - case _move_L3: - return _move(L3, c); - case _move_F: - return _move(F, c); - case _move_F2: - return _move(F2, c); - case _move_F3: - return _move(F3, c); - case _move_B: - return _move(B, c); - case _move_B2: - return _move(B2, c); - case _move_B3: - return _move(B3, c); - default: - DBG_LOG("move error, unknown move\n"); - return zero_fast; - } -} - -/* -TODO transform is now relegated to a separated file because it is too long. -It would be nice to make it shorter without loosing performance. -*/ -- cgit v1.3