nissy.h (16986B)
1 /* 2 This is libnissy (temporarily also known as h48), a Rubik's cube library. 3 4 All the functions return 0 or a positive integer in case of success and 5 a negative integer in case of error, unless otherwise specified. See 6 below for the list of error codes and their meaning. 7 8 Cubes are passed as strings in the cccccccc=eeeeeeeeeeee=r format, 9 see the README.md file for more information. 10 11 Accepted moves are any of the following: 12 U, D, R, L, F, B, Uw, Dw, Rw, Lw, Fw, Bw, M, S, E, x, y, z 13 optionally followed by a 2, a ' or a 3. 14 The standard NISS notation is also accepted: moves in parentheses () are 15 inverted and used as premoves. 16 17 A transformation must be given in the format 18 (rotation|mirrored) (2 letters) 19 for example 'rotation UF' or 'mirrored BL'. 20 */ 21 22 23 /* Constants *****************************************************************/ 24 25 /* Some constants for size for I/O buffers */ 26 #define NISSY_SIZE_CUBE 24U 27 #define NISSY_SIZE_TRANSFORMATION 12U 28 #define NISSY_SIZE_SOLVE_STATS 10U 29 #define NISSY_SIZE_DATAID 255U 30 #define NISSY_SIZE_MOVES 1000U 31 32 /* Flags for NISS options */ 33 #define NISSY_NISSFLAG_NORMAL 1U 34 #define NISSY_NISSFLAG_INVERSE 2U 35 #define NISSY_NISSFLAG_MIXED 4U 36 #define NISSY_NISSFLAG_LINEAR \ 37 (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE) 38 #define NISSY_NISSFLAG_ALL \ 39 (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE | NISSY_NISSFLAG_MIXED) 40 41 /* Status for stopping / pausing / resuming a solver */ 42 #define NISSY_STATUS_RUN 0 43 #define NISSY_STATUS_STOP 1 44 #define NISSY_STATUS_PAUSE 2 45 46 /* Possible results of move sequence comparison */ 47 #define NISSY_COMPARE_MOVES_EQUAL 0 48 #define NISSY_COMPARE_MOVES_DIFFERENT 99 49 50 /* The solved cube */ 51 #define NISSY_SOLVED_CUBE "ABCDEFGH=ABCDEFGHIJKL=A" 52 53 /* Error codes ***************************************************************/ 54 55 /* 56 The value NISSY_OK denotes a success. If returned by solve, it means 57 that no solution has been found. 58 */ 59 #define NISSY_OK 0LL 60 61 /* 62 The value NISSY_WARNING_UNSOLVABLE is a warning. It means that the 63 operation was completed succesfully, but the resulting cube is in an 64 unsolvable state. This could be intended, for example if the user has 65 provided an unsolvable cube as input. 66 */ 67 #define NISSY_WARNING_UNSOLVABLE -1LL 68 69 /* 70 The value NISSY_ERROR_INVALID_CUBE means that the provided cube is 71 invalid. It could be written in an unknown format, or be ill-formed. 72 */ 73 #define NISSY_ERROR_INVALID_CUBE -10LL 74 75 /* 76 The value NISSY_ERROR_UNSOLVABLE_CUBE means that the provided cube is in 77 an unsolvable state for the given solver. This could mean either that the 78 cube is not solvable at all (for example in case it has a single twisted 79 corner), or that it is not ready for the given step (for example if the 80 caller wants to solve a DR finish without the cube being in DR state). 81 */ 82 #define NISSY_ERROR_UNSOLVABLE_CUBE -11LL 83 84 /* 85 The value NISSY_ERROR_INVALID_MOVES means that the given moves are 86 invalid. 87 */ 88 #define NISSY_ERROR_INVALID_MOVES -20LL 89 90 /* 91 The value NISSY_ERROR_INVALID_TRANS means that the given transformation 92 is invalid. 93 */ 94 #define NISSY_ERROR_INVALID_TRANS -30LL 95 96 /* 97 The value NISSY_ERROR_INVALID_SOLVER means that the given solver is 98 not known. 99 */ 100 #define NISSY_ERROR_INVALID_SOLVER -50LL 101 102 /* 103 The value NISSY_ERROR_INVALID_VARIATION means that the given method of 104 finding variations for a solution is not known. 105 */ 106 #define NISSY_ERROR_INVALID_VARIATION -51LL 107 108 /* 109 The value NISSY_ERROR_NULL_POINTER means that one of the provided pointer 110 arguments is NULL. For example, it may be returned by solve when called 111 with a solver that requires some pre-computed data, but the provided 112 data is NULL. 113 */ 114 #define NISSY_ERROR_NULL_POINTER -60LL 115 116 /* 117 The value NISSY_ERROR_BUFFER_SIZE means that one of the buffers provided 118 is too small. For example, it could be too small to hold the result or 119 too small to hold the data generated by gendata. 120 */ 121 #define NISSY_ERROR_BUFFER_SIZE -61LL 122 123 /* 124 The value NISSY_ERROR_DATA means that the provided data is invalid. For 125 example, it may be returned by solve when called with incompatible solver 126 and data arguments. 127 */ 128 #define NISSY_ERROR_DATA -70LL 129 130 /* 131 The value NISSY_ERROR_OPTIONS means that one or more of the given options 132 are invalid. For example, it may be returned by solve when called with 133 a negative maximum number of solutions. 134 */ 135 #define NISSY_ERROR_OPTIONS -80LL 136 137 /* 138 The value NISSY_ERROR_UNKNOWN denotes an unexpected error. It probably 139 means that there some bug in this library. If you can, report any error 140 of this kind to sebastiano@tronto.net. Thanks! 141 */ 142 #define NISSY_ERROR_UNKNOWN -999LL 143 144 145 /* Library functions *********************************************************/ 146 147 /* 148 Compute the inverse of the given cube. 149 150 Parameters: 151 cube - The cube to be inverted. 152 Required size: NISSY_SIZE_CUBE. 153 result - The return parameter for the resulting cube. 154 Required size: NISSY_SIZE_CUBE. 155 156 Return values: 157 NISSY_OK - The cube was inverted succesfully. 158 NISSY_WARNING_UNSOLVABLE - The resulting cube is not solvable. This is 159 either because the given cube was not solvable, 160 or due to an unknown internal error. 161 NISSY_ERROR_INVALID_CUBE - The given cube is invalid. 162 NISSY_ERROR_UNKNOWN - An unknown error occurred. 163 */ 164 long long 165 nissy_inverse( 166 const char cube[], /* NISSY_SIZE_CUBE */ 167 char result[] /* NISSY_SIZE_CUBE */ 168 ); 169 170 /* 171 Apply the given sequence of moves on the given cube. 172 173 Parameters: 174 cube - The cube to move. 175 Required size: NISSY_SIZE_CUBE. 176 moves - The moves to apply to the cube. Must be a NULL-terminated string. 177 result - The return parameter for the resulting cube. 178 Required size: NISSY_SIZE_CUBE. 179 180 Return values: 181 NISSY_OK - The moves were applied succesfully. 182 NISSY_WARNING_UNSOLVABLE - The resulting cube is not solvable. This is 183 either because the given cube was not solvable, 184 or due to an unknown internal error. 185 NISSY_ERROR_INVALID_CUBE - The given cube is invalid. 186 NISSY_ERROR_INVALID_MOVES - The given moves are invalid. 187 NISSY_ERROR_NULL_POINTER - The 'moves' argument is NULL. 188 */ 189 long long 190 nissy_applymoves( 191 const char cube[], /* NISSY_SIZE_CUBE */ 192 const char *moves, 193 char result[] /* NISSY_SIZE_CUBE */ 194 ); 195 196 /* 197 Apply the single given transformation to the given cube. 198 199 Parameters: 200 cube - The cube to be transformed. 201 Required size: NISSY_SIZE_CUBE. 202 transformation - The transformation in "(rotation|mirrored) __" format. 203 Required size: NISSY_SIZE_TRANSFORMATION. 204 result - The return parameter for the resulting cube. 205 Required size: NISSY_SIZE_CUBE. 206 207 Return values: 208 NISSY_OK - The transformation was performed succesfully. 209 NISSY_WARNING_UNSOLVABLE - The resulting cube is not solvable. This is 210 probably due to an unknown internal error. 211 NISSY_ERROR_INVALID_CUBE - The given cube is invalid. 212 NISSY_ERROR_INVALID_TRANS - The given transformation is invalid. 213 */ 214 long long 215 nissy_applytrans( 216 const char cube[], /* NISSY_SIZE_CUBE */ 217 const char transformation[], /* NISSY_SIZE_TRANSFORMATION */ 218 char result[] /* NISSY_SIZE_CUBE */ 219 ); 220 221 /* 222 Find variations of a given move sequence, for example by changing 223 the direction of the last quarter turn(s), or linearizing a NISS move 224 sequence. The result consists of one or more move sequences, one per line, 225 and it always ends in a newline character. 226 227 Parameters: 228 moves - The moves of which to find the variation. Must be at most 229 NISSY_SIZE_MOVES long. 230 variations - Specify which kind of variations to find, for example 231 "lastqt" or "unniss". 232 result_size - The size of the result buffer. 233 result - The result buffer. 234 235 Return values: 236 NISSY_ERROR_NULL_POINTER - One of the provided pointers is NULL. 237 NISSY_ERROR_INVALID_MOVES - The given moves are invalid. 238 NISSY_ERROR_INVALID_VARIATION - The given transformer is not known. 239 NISSY_ERROR_BUFFER_SIZE - Either the result buffer is too small or the 240 given move sequence is longer than 241 NISSY_SIZE_MOVES. 242 Any value >= 0 - The number of variations found. 243 */ 244 long long 245 nissy_variations( 246 const char *moves, 247 const char *variation, 248 unsigned long long result_size, 249 char *result 250 ); 251 252 /* 253 Get the cube with the given ep, eo, cp and co values. The values must be in the 254 ranges specified below, but if the option "fix" is given any values outside its 255 range will be adjusted before using it. The option "fix" also fixes parity and 256 orientation issues, resulting always in a solvable cube. 257 258 Parameters: 259 ep - The edge permutation, 0 <= ep < 479001600 (12!) 260 eo - The edge orientation, 0 <= eo < 2047 (2^11) 261 cp - The corner permutation, 0 <= cp < 40320 (8!) 262 co - The corner orientation, 0 <= co < 2187 (3^7) 263 orient - The orientation of the cube, 0 <= orient < 24 264 options - Other options. 265 result - The return parameter for the resulting cube. 266 Required size: NISSY_SIZE_CUBE. 267 268 Return values: 269 NISSY_OK - The cube was generated succesfully. 270 NISSY_WARNING_UNSOLVABLE - The resulting cube is unsolvable. 271 NISSY_ERROR_OPTIONS - One or more of the given parameters is invalid. 272 */ 273 long long 274 nissy_getcube( 275 long long ep, 276 long long eo, 277 long long cp, 278 long long co, 279 long long orient, 280 const char *options, 281 char result[] /* NISSY_SIZE_CUBE */ 282 ); 283 284 /* 285 Compute the size of the data generated by nissy_gendata when called for 286 the given solver, and other useful information. 287 288 Parameters: 289 solver - The name of the solver. 290 dataid - An identifier for the data computed for the solver. Different 291 solvers may use equivalent data. This identifier can be used 292 e.g. as a filename or database key to save and retrieve the 293 correct data for each solver, without duplication. 294 Required size: NISSY_SIZE_DATAID. 295 296 Return values: 297 NISSY_ERROR_INVALID_SOLVER - The given solver is not known. 298 NISSY_ERROR_NULL_POINTER - The 'solver' argument is null. 299 NISSY_ERROR_UNKNOWN - An unknown error occurred. 300 Any value >= 0 - The size of the data, in bytes. 301 */ 302 long long 303 nissy_solverinfo( 304 const char *solver, 305 char dataid[] /* NISSY_SIZE_DATAID */ 306 ); 307 308 /* 309 Compute the data for the given solver and store it in generated_data. 310 311 Parameters: 312 solver - The name of the solver. 313 data_size - The size of the data buffer. It is advised to use 314 nissy_solverinfo to check how much memory is needed. 315 data - The return parameter for the generated data. 316 This buffer must have 8-byte alignment. Some solvers (such as 317 h48) will perform better if the buffer is 64-byte aligned. 318 319 Return values: 320 NISSY_ERROR_INVALID_SOLVER - The given solver is not known. 321 NISSY_ERROR_NULL_POINTER - The 'solver' argument is null. 322 NISSY_ERROR_UNKNOWN - An error occurred while generating the data. 323 NISSY_ERROR_DATA - The data buffer is invalid, for example because 324 it is not 8-byte aligned. 325 Any value >= 0 - The size of the data, in bytes. 326 */ 327 long long 328 nissy_gendata( 329 const char *solver, 330 unsigned long long data_size, 331 unsigned char *data 332 ); 333 334 /* 335 Check that the data is a valid data table for a solver. 336 337 Parameters: 338 solver - The name of the solver. 339 data_size - The size of the data buffer. 340 data - The data for the solver. Can be computed with gendata. 341 This buffer must have 8-byte alignment. Some solvers (such as 342 h48) will perform better if the buffer is 64-byte aligned, but 343 this is not relevant for the purpose of checking the integrity 344 of the data. 345 346 Return values: 347 NISSY_OK - The data is valid. 348 NISSY_ERROR_DATA - The data is invalid. 349 */ 350 long long 351 nissy_checkdata( 352 const char *solver, 353 unsigned long long data_size, 354 const unsigned char *data 355 ); 356 357 /* 358 Solve the given cube using the given solver and options. 359 360 Parameters: 361 cube - The cube to solver. 362 Required size: NISSY_SIZE_CUBE. 363 solver - The name of the solver. See doc/solvers.md for a list. 364 nissflag - The flags for NISS (linear, inverse, mixed, or 365 combinations; see the constants at the top of this file). 366 minmoves - The minimum number of moves for a solution. 367 maxmoves - The maximum number of moves for a solution. 368 maxsols - The maximum number of solutions. 369 optimal - The maximum number of moves above the optimal solution. 370 threads - The number of threads to use. Must be less than or equal 371 to the value of the compile-time constant THREADS. If set 372 to 0, the default value THREADS will be used. 373 data_size - The size of the data buffer. 374 data - The data for the solver. Can be computed with gendata. 375 This buffer must have 8-byte alignment. Some solvers 376 (such as h48) will perform better if the buffer is 377 64-byte aligned. 378 sols_size - The size of the solutions buffer. 379 sols - The return parameter for the solutions. The solutions are 380 separated by a '\n' (newline) and a '\0' (NULL character) 381 terminates the list. 382 stats - An array to store some statistics about the solve. 383 Required size: NISSY_SIZE_SOLVE_STATS. 384 poll_status - A callback function that should return the current 385 requested status for the solver (e.g. run, stop, pause, 386 resume; see the constants at the top of this file). The 387 way this status is polled and honored is solver-specific. 388 If this parameter is NULL, the status will always assumed 389 to be "run". 390 poll_status_data - Auxiliary data for the poll_status callback function. 391 392 Return values: 393 NISSY_OK - Cube solved succesfully. 394 NISSY_ERROR_INVALID_CUBE - The given cube is invalid. 395 NISSY_ERROR_UNSOLVABLE_CUBE - The given cube is valid, but not solvable with 396 the given solver. 397 NISSY_ERROR_OPTIONS - One or more of the given options are invalid. 398 NISSY_ERROR_INVALID_SOLVER - The given solver is not known. 399 NISSY_ERROR_NULL_POINTER - The 'solver' argument is null. 400 NISSY_ERROR_DATA - The data buffer is invalid. 401 Any value >= 0 - The number of solutions found. 402 */ 403 long long 404 nissy_solve( 405 const char cube[], /* NISSY_SIZE_CUBE */ 406 const char *solver, 407 unsigned nissflag, 408 unsigned minmoves, 409 unsigned maxmoves, 410 unsigned maxsolutions, 411 unsigned optimal, 412 unsigned threads, 413 unsigned long long data_size, 414 const unsigned char *data, 415 unsigned sols_size, 416 char *sols, 417 long long stats[], /* NISSY_SIZE_SOLVE_STATS */ 418 int (*poll_status)(void *), 419 void *poll_status_data 420 ); 421 422 /* 423 Count the given moves. 424 425 Parameters: 426 moves - The moves to be counted. 427 428 Return values: 429 NISSY_ERROR_INVALID_MOVES - The given moves are invalid. 430 NISSY_ERROR_NULL_POINTER - The 'moves' argument is NULL. 431 Any value >= 0 - The number of moves. 432 */ 433 long long 434 nissy_countmoves( 435 const char *moves 436 ); 437 438 /* 439 Compare the two moves sequences. Both must be at most NISSY_SIZE_MOVES long. 440 441 Parameters: 442 moves1 - The first sequence of moves to compare. 443 moves2 - The second sequence of moves to compare. 444 445 Return values: 446 NISSY_ERROR_INVALID_MOVES - One of the given moves sequences is invalid. 447 NISSY_ERROR_NULL_POINTER - One of the arguments is NULL. 448 NISSY_COMPARE_MOVES_EQUAL - The two moves sequences are indentical, up 449 to swapping parallel moves. 450 NISSY_COMPARE_MOVES_DIFFERENT - The two moves sequences are different. 451 */ 452 long long 453 nissy_comparemoves( 454 const char *moves1, 455 const char *moves2 456 ); 457 458 /* 459 Set a global logger function used by this library. Setting the logger to NULL 460 disables logging. 461 462 Parameters: 463 logger_function - A pointer to a function that takes two parameters: 464 * A C string, the string to be printed. 465 * Any other data via a void pointer. 466 user_data - Any data that will be provided by the logger when 467 calling logger_function. 468 469 Return values: 470 NISSY_OK - Logger set succesfully. No warning or error is going to be given 471 if the logger is invalid. 472 */ 473 long long 474 nissy_setlogger( 475 void (*logger_function)(const char *, void *), 476 void *user_data 477 );