diff options
Diffstat (limited to 'src/core/cube.h')
| -rw-r--r-- | src/core/cube.h | 95 |
1 files changed, 52 insertions, 43 deletions
diff --git a/src/core/cube.h b/src/core/cube.h index a045e55..91bb284 100644 --- a/src/core/cube.h +++ b/src/core/cube.h | |||
| @@ -1,17 +1,29 @@ | |||
| 1 | STATIC cube_t solvedcube(void); | 1 | STATIC oriented_cube_t solvedcube(void); |
| 2 | STATIC cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); | 2 | STATIC cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); |
| 3 | STATIC bool isconsistent(cube_t); | 3 | STATIC bool isconsistent(oriented_cube_t); |
| 4 | STATIC bool issolvable(cube_t); | 4 | STATIC bool issolvable(oriented_cube_t); |
| 5 | STATIC bool issolved(cube_t); | 5 | STATIC bool issolved(oriented_cube_t); |
| 6 | STATIC bool iserror(cube_t); | 6 | STATIC bool iserror(oriented_cube_t); |
| 7 | STATIC void getcube_fix(long long *, long long *, long long *, long long *); | 7 | STATIC void getcube_fix(long long *, long long *, long long *, long long *); |
| 8 | STATIC cube_t getcube(int64_t, int64_t, int64_t, int64_t); | 8 | STATIC cube_t getcube(int64_t, int64_t, int64_t, int64_t); |
| 9 | 9 | ||
| 10 | /* This is used only in tests, use SOLVED_CUBE directly everywhere else */ | 10 | STATIC oriented_cube_t readcube(const char *); |
| 11 | STATIC cube_t | 11 | STATIC int64_t writecube(oriented_cube_t, size_t n, char [n]); |
| 12 | STATIC uint8_t readco(const char *); | ||
| 13 | STATIC uint8_t readcp(const char *); | ||
| 14 | STATIC uint8_t readeo(const char *); | ||
| 15 | STATIC uint8_t readep(const char *); | ||
| 16 | |||
| 17 | STATIC uint8_t b32toedge(char); | ||
| 18 | STATIC uint8_t b32tocorner(char); | ||
| 19 | STATIC char edgetob32(uint8_t); | ||
| 20 | STATIC char cornertob32(uint8_t); | ||
| 21 | |||
| 22 | /* This is used only in tests, use SOLVED_ORIENTED_CUBE everywhere else */ | ||
| 23 | STATIC oriented_cube_t | ||
| 12 | solvedcube(void) | 24 | solvedcube(void) |
| 13 | { | 25 | { |
| 14 | return SOLVED_CUBE; | 26 | return SOLVED_ORIENTED_CUBE; |
| 15 | } | 27 | } |
| 16 | 28 | ||
| 17 | STATIC cube_t | 29 | STATIC cube_t |
| @@ -24,12 +36,12 @@ cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) | |||
| 24 | } | 36 | } |
| 25 | 37 | ||
| 26 | STATIC bool | 38 | STATIC bool |
| 27 | isconsistent(cube_t cube) | 39 | isconsistent(oriented_cube_t cube) |
| 28 | { | 40 | { |
| 29 | uint8_t i, p, e, piece, corner[8], edge[12]; | 41 | uint8_t i, p, e, piece, corner[8], edge[12]; |
| 30 | bool found[12]; | 42 | bool found[12]; |
| 31 | 43 | ||
| 32 | pieces(&cube, corner, edge); | 44 | pieces(&cube.cube, corner, edge); |
| 33 | 45 | ||
| 34 | for (i = 0; i < 12; i++) | 46 | for (i = 0; i < 12; i++) |
| 35 | found[i] = false; | 47 | found[i] = false; |
| @@ -63,25 +75,29 @@ isconsistent(cube_t cube) | |||
| 63 | if (!found[i]) | 75 | if (!found[i]) |
| 64 | goto inconsistent_cp; | 76 | goto inconsistent_cp; |
| 65 | 77 | ||
| 78 | if (cube.orientation >= 24) | ||
| 79 | goto inconsistent_orientation; | ||
| 80 | |||
| 66 | return true; | 81 | return true; |
| 67 | 82 | ||
| 68 | inconsistent_ep: | 83 | inconsistent_ep: |
| 69 | inconsistent_cp: | 84 | inconsistent_cp: |
| 70 | inconsistent_eo: | 85 | inconsistent_eo: |
| 71 | inconsistent_co: | 86 | inconsistent_co: |
| 72 | /* We used to do more logging here, hence the 4 different labels */ | 87 | inconsistent_orientation: |
| 88 | /* We used to do more logging here, hence the different labels */ | ||
| 73 | return false; | 89 | return false; |
| 74 | } | 90 | } |
| 75 | 91 | ||
| 76 | STATIC bool | 92 | STATIC bool |
| 77 | issolvable(cube_t cube) | 93 | issolvable(oriented_cube_t cube) |
| 78 | { | 94 | { |
| 79 | uint8_t i, eo, co, piece, edge[12], corner[8], ep[12], cp[8]; | 95 | uint8_t i, eo, co, piece, edge[12], corner[8], ep[12], cp[8]; |
| 80 | 96 | ||
| 81 | DBG_ASSERT(isconsistent(cube), false, | 97 | DBG_ASSERT(isconsistent(cube), false, |
| 82 | "issolvable: cube is inconsistent\n"); | 98 | "issolvable: cube is inconsistent\n"); |
| 83 | 99 | ||
| 84 | pieces(&cube, corner, edge); | 100 | pieces(&cube.cube, corner, edge); |
| 85 | for (i = 0; i < 12; i++) | 101 | for (i = 0; i < 12; i++) |
| 86 | ep[i] = edge[i] & PBITS; | 102 | ep[i] = edge[i] & PBITS; |
| 87 | for (i = 0; i < 8; i++) | 103 | for (i = 0; i < 8; i++) |
| @@ -120,15 +136,15 @@ issolvable_co: | |||
| 120 | } | 136 | } |
| 121 | 137 | ||
| 122 | bool | 138 | bool |
| 123 | issolved(cube_t cube) | 139 | issolved(oriented_cube_t cube) |
| 124 | { | 140 | { |
| 125 | return equal(cube, SOLVED_CUBE); | 141 | return equal(cube.cube, SOLVED_CUBE); |
| 126 | } | 142 | } |
| 127 | 143 | ||
| 128 | bool | 144 | bool |
| 129 | iserror(cube_t cube) | 145 | iserror(oriented_cube_t cube) |
| 130 | { | 146 | { |
| 131 | return equal(cube, ZERO_CUBE); | 147 | return equal(cube.cube, ZERO_CUBE); |
| 132 | } | 148 | } |
| 133 | 149 | ||
| 134 | STATIC void | 150 | STATIC void |
| @@ -175,21 +191,6 @@ getcube(int64_t ep, int64_t eo, int64_t cp, int64_t co) | |||
| 175 | return cubefromarray(carr, earr); | 191 | return cubefromarray(carr, earr); |
| 176 | } | 192 | } |
| 177 | 193 | ||
| 178 | |||
| 179 | /******************************************************************************/ | ||
| 180 | |||
| 181 | STATIC cube_t readcube(const char *); | ||
| 182 | STATIC int64_t writecube(cube_t, size_t n, char [n]); | ||
| 183 | STATIC uint8_t readco(const char *); | ||
| 184 | STATIC uint8_t readcp(const char *); | ||
| 185 | STATIC uint8_t readeo(const char *); | ||
| 186 | STATIC uint8_t readep(const char *); | ||
| 187 | |||
| 188 | STATIC uint8_t b32toedge(char); | ||
| 189 | STATIC uint8_t b32tocorner(char); | ||
| 190 | STATIC char edgetob32(uint8_t); | ||
| 191 | STATIC char cornertob32(uint8_t); | ||
| 192 | |||
| 193 | STATIC uint8_t | 194 | STATIC uint8_t |
| 194 | readco(const char *str) | 195 | readco(const char *str) |
| 195 | { | 196 | { |
| @@ -243,11 +244,11 @@ readep(const char *str) | |||
| 243 | return UINT8_ERROR; | 244 | return UINT8_ERROR; |
| 244 | } | 245 | } |
| 245 | 246 | ||
| 246 | STATIC cube_t | 247 | STATIC oriented_cube_t |
| 247 | readcube(const char *buf) | 248 | readcube(const char *buf) |
| 248 | { | 249 | { |
| 249 | int i; | 250 | int i; |
| 250 | uint8_t c[8], e[12]; | 251 | uint8_t c[8], e[12], orientation; |
| 251 | 252 | ||
| 252 | for (i = 0; i < 8; i++) { | 253 | for (i = 0; i < 8; i++) { |
| 253 | c[i] = b32tocorner(buf[i]); | 254 | c[i] = b32tocorner(buf[i]); |
| @@ -258,14 +259,14 @@ readcube(const char *buf) | |||
| 258 | } else { | 259 | } else { |
| 259 | LOG("(char '%c')\n", buf[i]); | 260 | LOG("(char '%c')\n", buf[i]); |
| 260 | } | 261 | } |
| 261 | return ZERO_CUBE; | 262 | return ZERO_ORIENTED_CUBE; |
| 262 | } | 263 | } |
| 263 | } | 264 | } |
| 264 | 265 | ||
| 265 | if (buf[8] != '=') { | 266 | if (buf[8] != '=') { |
| 266 | LOG("Error reading separator: a single '=' " | 267 | LOG("Error reading separator: a single '=' " |
| 267 | "must be used to separate edges and corners\n"); | 268 | "must be used to separate edges and corners\n"); |
| 268 | return ZERO_CUBE; | 269 | return ZERO_ORIENTED_CUBE; |
| 269 | } | 270 | } |
| 270 | 271 | ||
| 271 | for (i = 0; i < 12; i++) { | 272 | for (i = 0; i < 12; i++) { |
| @@ -277,15 +278,25 @@ readcube(const char *buf) | |||
| 277 | } else { | 278 | } else { |
| 278 | LOG("(char '%c')\n", buf[i+9]); | 279 | LOG("(char '%c')\n", buf[i+9]); |
| 279 | } | 280 | } |
| 280 | return ZERO_CUBE; | 281 | return ZERO_ORIENTED_CUBE; |
| 281 | } | 282 | } |
| 282 | } | 283 | } |
| 283 | 284 | ||
| 284 | return cubefromarray(c, e); | 285 | orientation = (uint8_t)(buf[22] - 'A'); |
| 286 | if (orientation >= 24) { | ||
| 287 | LOG("Error reading orientation: impossible value %" PRIu8 | ||
| 288 | " (%c)\n", orientation, buf[22]); | ||
| 289 | return ZERO_ORIENTED_CUBE; | ||
| 290 | } | ||
| 291 | |||
| 292 | return (oriented_cube_t) { | ||
| 293 | .cube = cubefromarray(c, e), | ||
| 294 | .orientation = orientation | ||
| 295 | }; | ||
| 285 | } | 296 | } |
| 286 | 297 | ||
| 287 | STATIC int64_t | 298 | STATIC int64_t |
| 288 | writecube(cube_t cube, size_t buf_size, char buf[buf_size]) | 299 | writecube(oriented_cube_t cube, size_t buf_size, char buf[buf_size]) |
| 289 | { | 300 | { |
| 290 | int i; | 301 | int i; |
| 291 | uint8_t corner[8], edge[12]; | 302 | uint8_t corner[8], edge[12]; |
| @@ -297,7 +308,7 @@ writecube(cube_t cube, size_t buf_size, char buf[buf_size]) | |||
| 297 | return NISSY_ERROR_BUFFER_SIZE; | 308 | return NISSY_ERROR_BUFFER_SIZE; |
| 298 | } | 309 | } |
| 299 | 310 | ||
| 300 | pieces(&cube, corner, edge); | 311 | pieces(&cube.cube, corner, edge); |
| 301 | 312 | ||
| 302 | for (i = 0; i < 8; i++) | 313 | for (i = 0; i < 8; i++) |
| 303 | buf[i] = cornertob32(corner[i]); | 314 | buf[i] = cornertob32(corner[i]); |
| @@ -307,9 +318,8 @@ writecube(cube_t cube, size_t buf_size, char buf[buf_size]) | |||
| 307 | for (i = 0; i < 12; i++) | 318 | for (i = 0; i < 12; i++) |
| 308 | buf[i+9] = edgetob32(edge[i]); | 319 | buf[i+9] = edgetob32(edge[i]); |
| 309 | 320 | ||
| 310 | /* TODO */ | ||
| 311 | buf[21] = '='; | 321 | buf[21] = '='; |
| 312 | buf[22] = 'A'; | 322 | buf[22] = (char)cube.orientation + 'A'; |
| 313 | buf[23] = '\0'; | 323 | buf[23] = '\0'; |
| 314 | 324 | ||
| 315 | return NISSY_OK; | 325 | return NISSY_OK; |
| @@ -351,4 +361,3 @@ cornertob32(uint8_t corner) | |||
| 351 | 361 | ||
| 352 | return val < 26 ? 'A' + (char)val : 'a' + (char)(val - 26); | 362 | return val < 26 ? 'A' + (char)val : 'a' + (char)(val - 26); |
| 353 | } | 363 | } |
| 354 | /******************************************************************************/ | ||
