From 75966319fd5891c2c1bd35b1f7c93eab172fd28e Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Fri, 10 May 2024 08:55:03 +0200 Subject: Moved to src/ --- src/cube.h | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/cube.h (limited to 'src/cube.h') diff --git a/src/cube.h b/src/cube.h new file mode 100644 index 0000000..32547cf --- /dev/null +++ b/src/cube.h @@ -0,0 +1,164 @@ +/****************************************************************************** +Cube type definition + +Each piece is represented by an (unsigned) 8-bit integer. The 4 +least-significant bits determine which piece it is, the other 4 determine +the orientation. + +Edges are numbered as follows (see also cube.c): +UF=0 UB=1 DB=2 DF=3 UR=4 UL=5 DL=6 DR=7 FR=8 FL=9 BL=10 BR=11 + +Corners are numbered as follows: +UFR=0 UBL=1 DFL=2 DBR=3 UFL=4 UBR=5 DFR=6 DBL=7 + +The orientation of the edges is with respect to F/B, the orientation of +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 { + uint8_t corner[8]; + 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, const char *); +cube_t applytrans(cube_t, const char *); + +/****************************************************************************** +Read / write utilities + +Reading and writing is not done directly via stdin / stdout, but via an +array of char (called buf in the prototypes below). + +Multiple representations of the cube as text are supported: + +- H48: a human-readable format. + Each edge is represented by two letters denoting the sides it + belongs to and one number denoting its orientation (0 oriented, 1 + mis-oriented). Similarly, each corner is represented by three letters and + a number (0 oriented, 1 twisted clockwise, 2 twisted counter-clockwise). + + The solved cube looks like this: + + UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 + UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0 + + The cube after the moves R'U'F looks like this: + + FL1 BR0 DB0 UR1 UF0 UB0 DL0 FR0 UL1 DF1 BL0 DR0 + UBL1 DBR1 UFR2 DFR2 DFL2 UBL2 UFL2 DBL0 + + Whitespace (including newlines) between pieces is ignored when reading the + cube. A single whitespace character is added between pieces when writing. + +- SRC: format used to generate code for internal use. + If OUT is the output in SRC format, one can use `cube_t cube = OUT` to + declare a new cube object. + +- LST: a format for internal use and generating code. + The cube is printed as a comma-separated list of 20 integers, as they appear + in cube_t. Corners come first, followed by edge (unlike H48). +******************************************************************************/ + +cube_t readcube(const char *format, const char *buf); +void writecube(const char *format, cube_t cube, char *buf); + +/****************************************************************************** +Solvers + +The solutions are returned as a newline-separated list of characters. Moves +are separated by single spaces. + +Unless specified otherwise, all the solutions are not trivially simplifiable. +This means that sequences like U U2 or R L R will not appear in any solution. +Moreover, two consecutive parallel moves are always going to be sorted in +increasing order. For example, L R2 may never appear in a solution, but R2 L +could. +******************************************************************************/ + +int64_t solve( + /* The cube to solve. Must be solvable. */ + cube_t cube, + + /* Supported solvers: + * "optimal" - currently the same as "simple" + * "simple" - a simple, slow solver without tables + */ + const char *solver, + + /* Some solvers accept extra options,like "!filter". */ + const char *options, + + /* Can be "normal", "inverse", "mixed" or "linear". */ + const char *nisstype, + + /* The minimum number of moves. Must be >= 0. */ + int8_t minmoves, + + /* The maximum number of moves. If negative, the maximum length + * is unlimited. + */ + int8_t maxmoves, + + /* The maximum number of solutions. */ + int64_t maxsols, + + /* All solutions at most "optimal" moves from the shortest solution + * (respecting minmoves) are found. If negative, it is ignored. + */ + int8_t optimal, + + /* Some solvers require extra data to function properly (for example, + * pruning tables). This data can be generated with gendata(). + */ + const void *data, + + /* The solutions (return parameter) */ + char *solutions +); + +/* Solving n cubes optimally, one solutions per cube. Options are similar + * to solve(). + */ +void multisolve( + int n, + cube_t *cube, + const char *solver, + const void *data, + char *sols +); + +/* Returns the number of bytes written to data, -1 in case of error. + * TODO: write down how much memory every solver requires. */ +int64_t gendata(const char *solver, void *data); -- cgit v1.3