h48

A prototype for an optimal Rubik's cube solver, work in progress.
git clone https://git.tronto.net/h48
Download | Log | Files | Refs | README | LICENSE

commit 9e698917cb5b332cdbf1969ddfe3840239106c8d
parent 99fabe8592a4022313b1cb0581881ee1bc6b1c99
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Thu,  5 Oct 2023 09:31:02 +0200

Implemented compose; some cleanup

Diffstat:
M.gitignore | 2++
MREADME.md | 3++-
Asrc/constants.h | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/cube.h | 51++++++---------------------------------------------
Msrc/cube_array.c | 27+++++++++++++++++++++++++++
Asrc/cube_array.h | 6++++++
Mtest/04_compose/31_scrambled_scrambled.out | 2+-
Dtest/last.err | 0
Dtest/last.out | 1-
Dtest/run | 0
Autils/FORMAT.txt | 24++++++++++++++++++++++++
Autils/move_B.txt | 1+
Autils/move_B2.txt | 1+
Autils/move_B3.txt | 1+
Autils/move_D.txt | 1+
Autils/move_D2.txt | 1+
Autils/move_D3.txt | 1+
Autils/move_F.txt | 1+
Autils/move_F2.txt | 1+
Autils/move_F3.txt | 1+
Autils/move_L.txt | 1+
Autils/move_L2.txt | 1+
Autils/move_L3.txt | 1+
Autils/move_R.txt | 1+
Autils/move_R2.txt | 1+
Autils/move_R3.txt | 1+
Autils/move_U.txt | 1+
Autils/move_U2.txt | 1+
Autils/move_U3.txt | 1+
Autils/solved.txt | 2++
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