aboutsummaryrefslogtreecommitdiff
path: root/cube.h
blob: 3f9b50970dca3b8be64a48a074dc80cf5270e96c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/******************************************************************************
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: 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.
******************************************************************************/

#ifdef CUBE_AVX2
typedef __m256i cube_t;
#else
typedef struct {
	uint8_t c[8];   /* Corners */
	uint8_t e[12];  /* Edges   */
} cube_t;
#endif

/* Returns a copy of the solved cube */
cube_t solvedcube(void);

/* Basic checks on the cube */
bool issolvable(cube_t);
bool equal(cube_t, cube_t);
bool issolved(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);

/* All functions can return an error value, use iserror() to check this */
bool iserror(cube_t);

/******************************************************************************
Moves and transformations

Moves and transformations are represented each as an (unsigned) 8 bit integer.

Moves are numbered as follows:
U=0  U2=1  U'=2  D=3  D2=4  D'=5
R=6  R2=7  R'=8  L=9  L2=10 L'=11
F=12 F2=13 F'=14 B=15 B2=16 B'=17

TODO: NISS

TODO: Extend the moveset?

Transformations can be either simple rotations or a rotation composed
with a mirroring.  A composed rotation + mirror is obtained by applying
the corresponding rotation to the solved cube mirrored along the M plane.

For example, to apply the transformation RBm (mirrored RB) to a cube C:
	1. Apply a mirror along the M plane to the solved cube
	2. Rotate the mirrored cube with z' y2
	3. Apply the cube C to the transformed solved cube
	4. Apply the transformations of step 1a and 1b in reverse

See cube.c for a full list of transformations.
******************************************************************************/

typedef uint8_t move_t;
typedef uint8_t trans_t;

/* Apply a move or a transformation on the cube */
cube_t move(cube_t, move_t);
cube_t transform(cube_t, trans_t);

/******************************************************************************
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, although
not all of them are supported for both reading and writing. See below
for details. More formats may be supported in the future.

Moves are read using the standard notation. Each move (U, D, R, L, F,
B) can be followed by a modifier (1, 2, 3, '). Whitespace (spaces, tabs,
newlines) are ignored. Parantheses and other notation is not supported.
TODO: parantheses for NISS

For how transformations are read or written, see cube.c.
******************************************************************************/

/* The different formats for reading or writing the cube */
typedef enum {
	H48, /* H48 is 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, /* The SRC format can be used to generate code for internal use.
	      *
	      * In cube.c, a type called cube_array_t is defined and used for
	      * basic, non-performance-critical methods. If OUT is the output
	      * in SRC format, the following line can be used to declare a new
	      * cube object:
	      *
	      * cube_array_t cube = OUT
	      */
	AVX, /* The AVX format is analogous to SRC, but for the AVX2 internal
	      * representation of the cube.
	      */
} format_t;

/* Reads a cube from buf in the specified format, and return it.
 * Supported formats: H48.
 */
cube_t readcube(format_t format, char *buf);

/* Write the given cube to buf in the specified format.
 * Supported formats: H48, SRC, AVX.
 */
void writecube(format_t format, cube_t cube, char *buf);

/* Utilities for reading and writing moves */
int readmoves(char *buf, move_t *moves);
void writemoves(move_t *moves, int n, char *buf);
trans_t readtrans(char *buf);
void writetrans(trans_t trans, char *buf);

/******************************************************************************
Coordinates

The coordinate functions compute one aspect of the cube (for example,
the edge orientation) and they return it as an integer. They are used
for example to build pruning tables for various solving methods.
******************************************************************************/

int16_t coord_eo(cube_t); /* Edge orientation */

/******************************************************************************
Solvers

Solvers return -1 in case of error, the number of solutions otherwise

TODO
******************************************************************************/

int solve_generic(cube_t, int (*)(cube_t), uint8_t, int, move_t *);

Generated with cgit - Back to sebastiano.tronto.net