commit 9e698917cb5b332cdbf1969ddfe3840239106c8d
parent 99fabe8592a4022313b1cb0581881ee1bc6b1c99
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Thu, 5 Oct 2023 09:31:02 +0200
Implemented compose; some cleanup
Diffstat:
30 files changed, 159 insertions(+), 48 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1 +1,3 @@
test/*/runtest
+test/run
+test/last.*
diff --git a/README.md b/README.md
@@ -5,14 +5,15 @@ Work in progress.
TODO:
* transformations
+* setup benchmarks
* coordinates: co, eo, epsep, cpsep_sym, cocpsep_sym, cphtr_sym, cocphtr_sym
* pruning tables (1 bit per entry + fallback)
* solve.c
Optimizations:
-* multi-move (up to 4/5 moves at once)
* avx2_cube.c
+* multi-move (up to 4/5 moves at once)
Things I need to learn:
diff --git a/src/constants.h b/src/constants.h
@@ -0,0 +1,71 @@
+/* Standard moves */
+#define U 0U
+#define U2 1U
+#define U3 2U
+#define D 3U
+#define D2 4U
+#define D3 5U
+#define R 6U
+#define R2 7U
+#define R3 8U
+#define L 9U
+#define L2 10U
+#define L3 11U
+#define F 12U
+#define F2 13U
+#define F3 14U
+#define B 15U
+#define B2 16U
+#define B3 17U
+
+/* Regular transformations (rotations) */
+#define UF_i 0
+#define UL_i 1
+#define UB_i 2
+#define UR_i 3
+#define DF_i 4
+#define DL_i 5
+#define DB_i 6
+#define DR_i 7
+#define RU_i 8
+#define RF_i 9
+#define RD_i 10
+#define RB_i 11
+#define LU_i 12
+#define LF_i 13
+#define LD_i 14
+#define LB_i 15
+#define FU_i 16
+#define FR_i 16
+#define FD_i 18
+#define FL_i 19
+#define BU_i 20
+#define BR_i 21
+#define BD_i 22
+#define BL_i 23
+
+/* Mirrored transformations */
+#define UF_m 24
+#define UL_m 25
+#define UB_m 26
+#define UR_m 27
+#define DF_m 28
+#define DL_m 29
+#define DB_m 30
+#define DR_m 31
+#define RU_m 32
+#define RF_m 33
+#define RD_m 34
+#define RB_m 35
+#define LU_m 36
+#define LF_m 37
+#define LD_m 38
+#define LB_m 39
+#define FU_m 40
+#define FR_m 41
+#define FD_m 42
+#define FL_m 43
+#define BU_m 44
+#define BR_m 45
+#define BD_m 46
+#define BL_m 47
diff --git a/src/cube.h b/src/cube.h
@@ -1,52 +1,13 @@
-typedef enum {
- U = 0, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3
-} move_t;
+/* TODO: ifdef for different implementations */
+#include "cube_array.h"
-typedef enum {
- UF_i = 0, UL_i, UB_i, UR_i, DF_i, DL_i, DB_i, DR_i,
- UF_m, UL_m, UB_m, UR_m, DF_m, DL_m, DB_m, DR_m,
- RU_i, RF_i, RD_i, RB_i, LU_i, LF_i, LD_i, LB_i,
- RU_m, RF_m, RD_m, RB_m, LU_m, LF_m, LD_m, LB_m,
- FU_i, FR_i, FD_i, FL_i, BU_i, BR_i, BD_i, BL_i,
- FU_m, FR_m, FD_m, FL_m, BU_m, BR_m, BD_m, BL_m
-} trans_t;
-
-typedef struct {
- uint8_t c[8];
- uint8_t e[12];
-} cube_t;
+/* For moves and transformations, see constants.h */
+typedef uint8_t move_t;
+typedef uint8_t trans_t;
extern cube_t solvedcube;
-/*
-The functions readcube() and writecube() use the following 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).
-Edge orientation is relative to the F / B axis, corner orientation is
-relative to the U / D axis.
-
-The pieces are ordered such that 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
-
-Whitespace (including newlines) between pieces is ignored when reading
-the cube, and a single whitespace character is added between pieces
-when writing.
-
-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
-
-More formats might be supported in the future.
-*/
-
+/* For the textual representation of the cube, see utils/FORMAT.txt */
cube_t readcube(char *);
void writecube(cube_t, char *);
diff --git a/src/cube_array.c b/src/cube_array.c
@@ -25,6 +25,7 @@ The third bit is needed because x+y+1 can exceed 4.
#include <stdio.h>
#endif
+#include "constants.h"
#include "cube.h"
#define _c_ufr 0U
@@ -713,6 +714,32 @@ inverse_inconsistent:
cube_t
compose(cube_t c1, cube_t c2)
{
+ uint8_t i, piece, orien, aux, auy;
+ cube_t ret = {0};
+
+#ifdef DEBUG
+ if (!isconsistent(c1) || !isconsistent(c2))
+ goto compose_inconsistent;
+#endif
+
+ for (i = 0; i < 12; i++) {
+ piece = c2.e[i] & _pbits;
+ orien = (c2.e[i] ^ c1.e[piece]) & _eobit;
+ ret.e[i] = (c1.e[piece] & _pbits) | orien;
+ }
+
+ for (i = 0; i < 8; i++) {
+ piece = c2.c[i] & _pbits;
+ aux = (c2.c[i] & _cobits) + (c1.c[piece] & _cobits);
+ auy = (aux + _ctwist_cw) >> 2U;
+ orien = (aux + auy) & _cobits2;
+ ret.c[i] = (c1.c[piece] & _pbits) | orien;
+ }
+
+ return ret;
+
+compose_inconsistent:
+ fprintf(stderr, "compose error, inconsistent cube\n");
return errorcube;
}
diff --git a/src/cube_array.h b/src/cube_array.h
@@ -0,0 +1,6 @@
+/* Public properties specific to the array implementation */
+
+typedef struct {
+ uint8_t c[8];
+ uint8_t e[12];
+} cube_t;
diff --git a/test/04_compose/31_scrambled_scrambled.out b/test/04_compose/31_scrambled_scrambled.out
@@ -1 +1 @@
-FL1 UR2 BR1 FR1 UL0 BL0 DB1 UB0 DF1 DL1 UF0 DR1 UFR2 UBR0 DFL2 UFL0 DBR0 DFR2 DBL1 UBL2
+FL1 UR1 BR1 FR1 UL0 BL0 DB1 UB0 DF1 DL1 UF0 DR1 UFR2 UBR0 DFL2 UFL0 DBR0 DFR2 DBL1 UBL2
diff --git a/test/last.err b/test/last.err
diff --git a/test/last.out b/test/last.out
@@ -1 +0,0 @@
-Error composing cubes
diff --git a/test/run b/test/run
Binary files differ.
diff --git a/utils/FORMAT.txt b/utils/FORMAT.txt
@@ -0,0 +1,24 @@
+The functions readcube() and writecube() use the following 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).
+Edge orientation is relative to the F / B axis, corner orientation is
+relative to the U / D axis.
+
+The pieces are ordered such that 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
+
+Whitespace (including newlines) between pieces is ignored when reading
+the cube, and a single whitespace character is added between pieces
+when writing.
+
+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
+
+More formats might be supported in the future.
diff --git a/utils/move_B.txt b/utils/move_B.txt
@@ -0,0 +1 @@
+UF0 BR1 BL1 DF0 UR0 UL0 DL0 DR0 FR0 FL0 UB1 DB1 UFR0 UBR1 DFL0 DBL1 UFL0 DBR2 DFR0 UBL2
diff --git a/utils/move_B2.txt b/utils/move_B2.txt
@@ -0,0 +1 @@
+UF0 DB0 UB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BR0 BL0 UFR0 DBR0 DFL0 UBL0 UFL0 DBL0 DFR0 UBR0
diff --git a/utils/move_B3.txt b/utils/move_B3.txt
@@ -0,0 +1 @@
+UF0 BL1 BR1 DF0 UR0 UL0 DL0 DR0 FR0 FL0 DB1 UB1 UFR0 DBL1 DFL0 UBR1 UFL0 UBL2 DFR0 DBR2
diff --git a/utils/move_D.txt b/utils/move_D.txt
@@ -0,0 +1 @@
+UF0 UB0 DR0 DL0 UR0 UL0 DB0 DF0 FR0 FL0 BL0 BR0 UFR0 UBL0 DBL0 DFR0 UFL0 UBR0 DFL0 DBR0
diff --git a/utils/move_D2.txt b/utils/move_D2.txt
@@ -0,0 +1 @@
+UF0 UB0 DF0 DB0 UR0 UL0 DR0 DL0 FR0 FL0 BL0 BR0 UFR0 UBL0 DBR0 DFL0 UFL0 UBR0 DBL0 DFR0
diff --git a/utils/move_D3.txt b/utils/move_D3.txt
@@ -0,0 +1 @@
+UF0 UB0 DL0 DR0 UR0 UL0 DF0 DB0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFR0 DBL0 UFL0 UBR0 DBR0 DFL0
diff --git a/utils/move_F.txt b/utils/move_F.txt
@@ -0,0 +1 @@
+FL1 UB0 DB0 FR1 UR0 UL0 DL0 DR0 UF1 DF1 BL0 BR0 UFL1 UBL0 DFR1 DBR0 DFL2 UBR0 UFR2 DBL0
diff --git a/utils/move_F2.txt b/utils/move_F2.txt
@@ -0,0 +1 @@
+DF0 UB0 DB0 UF0 UR0 UL0 DL0 DR0 FL0 FR0 BL0 BR0 DFL0 UBL0 UFR0 DBR0 DFR0 UBR0 UFL0 DBL0
diff --git a/utils/move_F3.txt b/utils/move_F3.txt
@@ -0,0 +1 @@
+FR1 UB0 DB0 FL1 UR0 UL0 DL0 DR0 DF1 UF1 BL0 BR0 DFR1 UBL0 UFL1 DBR0 UFR2 UBR0 DFL2 DBL0
diff --git a/utils/move_L.txt b/utils/move_L.txt
@@ -0,0 +1 @@
+UF0 UB0 DB0 DF0 UR0 BL0 FL0 DR0 FR0 UL0 DL0 BR0 UFR0 DBL2 UFL2 DBR0 UBL1 UBR0 DFR0 DFL1
diff --git a/utils/move_L2.txt b/utils/move_L2.txt
@@ -0,0 +1 @@
+UF0 UB0 DB0 DF0 UR0 DL0 UL0 DR0 FR0 BL0 FL0 BR0 UFR0 DFL0 UBL0 DBR0 DBL0 UBR0 DFR0 UFL0
diff --git a/utils/move_L3.txt b/utils/move_L3.txt
@@ -0,0 +1 @@
+UF0 UB0 DB0 DF0 UR0 FL0 BL0 DR0 FR0 DL0 UL0 BR0 UFR0 UFL2 DBL2 DBR0 DFL1 UBR0 DFR0 UBL1
diff --git a/utils/move_R.txt b/utils/move_R.txt
@@ -0,0 +1 @@
+UF0 UB0 DB0 DF0 FR0 UL0 DL0 BR0 DR0 FL0 BL0 UR0 DFR2 UBL0 DFL0 UBR2 UFL0 UFR1 DBR1 DBL0
diff --git a/utils/move_R2.txt b/utils/move_R2.txt
@@ -0,0 +1 @@
+UF0 UB0 DB0 DF0 DR0 UL0 DL0 UR0 BR0 FL0 BL0 FR0 DBR0 UBL0 DFL0 UFR0 UFL0 DFR0 UBR0 DBL0
diff --git a/utils/move_R3.txt b/utils/move_R3.txt
@@ -0,0 +1 @@
+UF0 UB0 DB0 DF0 BR0 UL0 DL0 FR0 UR0 FL0 BL0 DR0 UBR2 UBL0 DFL0 DFR2 UFL0 DBR1 UFR1 DBL0
diff --git a/utils/move_U.txt b/utils/move_U.txt
@@ -0,0 +1 @@
+UR0 UL0 DB0 DF0 UB0 UF0 DL0 DR0 FR0 FL0 BL0 BR0 UBR0 UFL0 DFL0 DBR0 UFR0 UBL0 DFR0 DBL0
diff --git a/utils/move_U2.txt b/utils/move_U2.txt
@@ -0,0 +1 @@
+UB0 UF0 DB0 DF0 UL0 UR0 DL0 DR0 FR0 FL0 BL0 BR0 UBL0 UFR0 DFL0 DBR0 UBR0 UFL0 DFR0 DBL0
diff --git a/utils/move_U3.txt b/utils/move_U3.txt
@@ -0,0 +1 @@
+UL0 UR0 DB0 DF0 UF0 UB0 DL0 DR0 FR0 FL0 BL0 BR0 UFL0 UBR0 DFL0 DBR0 UBL0 UFR0 DFR0 DBL0
diff --git a/utils/solved.txt b/utils/solved.txt
@@ -0,0 +1,2 @@
+
+UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0