aboutsummaryrefslogtreecommitdiff
path: root/src/core/cube.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/cube.h')
-rw-r--r--src/core/cube.h95
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 @@
1STATIC cube_t solvedcube(void); 1STATIC oriented_cube_t solvedcube(void);
2STATIC cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); 2STATIC cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]);
3STATIC bool isconsistent(cube_t); 3STATIC bool isconsistent(oriented_cube_t);
4STATIC bool issolvable(cube_t); 4STATIC bool issolvable(oriented_cube_t);
5STATIC bool issolved(cube_t); 5STATIC bool issolved(oriented_cube_t);
6STATIC bool iserror(cube_t); 6STATIC bool iserror(oriented_cube_t);
7STATIC void getcube_fix(long long *, long long *, long long *, long long *); 7STATIC void getcube_fix(long long *, long long *, long long *, long long *);
8STATIC cube_t getcube(int64_t, int64_t, int64_t, int64_t); 8STATIC 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 */ 10STATIC oriented_cube_t readcube(const char *);
11STATIC cube_t 11STATIC int64_t writecube(oriented_cube_t, size_t n, char [n]);
12STATIC uint8_t readco(const char *);
13STATIC uint8_t readcp(const char *);
14STATIC uint8_t readeo(const char *);
15STATIC uint8_t readep(const char *);
16
17STATIC uint8_t b32toedge(char);
18STATIC uint8_t b32tocorner(char);
19STATIC char edgetob32(uint8_t);
20STATIC char cornertob32(uint8_t);
21
22/* This is used only in tests, use SOLVED_ORIENTED_CUBE everywhere else */
23STATIC oriented_cube_t
12solvedcube(void) 24solvedcube(void)
13{ 25{
14 return SOLVED_CUBE; 26 return SOLVED_ORIENTED_CUBE;
15} 27}
16 28
17STATIC cube_t 29STATIC cube_t
@@ -24,12 +36,12 @@ cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
24} 36}
25 37
26STATIC bool 38STATIC bool
27isconsistent(cube_t cube) 39isconsistent(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
68inconsistent_ep: 83inconsistent_ep:
69inconsistent_cp: 84inconsistent_cp:
70inconsistent_eo: 85inconsistent_eo:
71inconsistent_co: 86inconsistent_co:
72 /* We used to do more logging here, hence the 4 different labels */ 87inconsistent_orientation:
88 /* We used to do more logging here, hence the different labels */
73 return false; 89 return false;
74} 90}
75 91
76STATIC bool 92STATIC bool
77issolvable(cube_t cube) 93issolvable(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
122bool 138bool
123issolved(cube_t cube) 139issolved(oriented_cube_t cube)
124{ 140{
125 return equal(cube, SOLVED_CUBE); 141 return equal(cube.cube, SOLVED_CUBE);
126} 142}
127 143
128bool 144bool
129iserror(cube_t cube) 145iserror(oriented_cube_t cube)
130{ 146{
131 return equal(cube, ZERO_CUBE); 147 return equal(cube.cube, ZERO_CUBE);
132} 148}
133 149
134STATIC void 150STATIC 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
181STATIC cube_t readcube(const char *);
182STATIC int64_t writecube(cube_t, size_t n, char [n]);
183STATIC uint8_t readco(const char *);
184STATIC uint8_t readcp(const char *);
185STATIC uint8_t readeo(const char *);
186STATIC uint8_t readep(const char *);
187
188STATIC uint8_t b32toedge(char);
189STATIC uint8_t b32tocorner(char);
190STATIC char edgetob32(uint8_t);
191STATIC char cornertob32(uint8_t);
192
193STATIC uint8_t 194STATIC uint8_t
194readco(const char *str) 195readco(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
246STATIC cube_t 247STATIC oriented_cube_t
247readcube(const char *buf) 248readcube(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
287STATIC int64_t 298STATIC int64_t
288writecube(cube_t cube, size_t buf_size, char buf[buf_size]) 299writecube(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/******************************************************************************/

Generated with cgit - Back to sebastiano.tronto.net