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 259c7326f78d5495f5dc51c619932599a5279f68
parent 0032089b5c7dedf057c60fcee17cbdd2b0f8bb87
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Sun, 22 Oct 2023 12:49:20 +0200

Progess with transformation implementation

Diffstat:
MREADME.md | 3++-
Msrc/constants.h | 4++++
Msrc/cube.h | 5+++++
Msrc/cube_array.c | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/05_transform/00_solved_UFr.in | 2++
Atest/05_transform/00_solved_UFr.out | 1+
Atest/05_transform/01_solved_BLm.in | 2++
Atest/05_transform/01_solved_BLm.out | 1+
Atest/05_transform/transform_tests.c | 38++++++++++++++++++++++++++++++++++++++
Mutils/TRANSFORMATIONS.txt | 6++++++
Mutils/mirror.sh | 2+-
Autils/transform_moves.txt | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 files changed, 232 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md @@ -4,7 +4,8 @@ Work in progress. TODO: -* test SRC: scrambled cube, rename directory in io_SRC_write +* write script to generate tests for trans (see utils/transform_moves.txt) +* add tests for transformation * implement transformations (use write to SRC to make life easier) * setup benchmarks * coordinates: co, eo, epsep, cpsep_sym, cocpsep_sym, cphtr_sym, cocphtr_sym diff --git a/src/constants.h b/src/constants.h @@ -69,3 +69,7 @@ #define BRm 45 #define BDm 46 #define BLm 47 + +/* Errors */ +#define errormove 99U +#define errortrans 99U diff --git a/src/cube.h b/src/cube.h @@ -21,7 +21,12 @@ bool iserror(cube_t); int readmoves(char *, move_t *); void writemoves(move_t *, int, char *); +trans_t readtrans(char *); +void writetrans(trans_t, char *); + cube_t move(cube_t, move_t); cube_t inverse(cube_t); cube_t compose(cube_t, cube_t); + +/* See utils/TRANSFORMATIONS.txt for how transformations are applied */ cube_t transform(cube_t, trans_t); diff --git a/src/cube_array.c b/src/cube_array.c @@ -120,6 +120,57 @@ static char *movestr[] = { [B3] = "B'", }; +static char *transstr[] = { + [UFr] = "rotation UF", + [UFm] = "mirrored UF", + [ULr] = "rotation UL", + [ULm] = "mirrored UL", + [UBr] = "rotation UB", + [UBm] = "mirrored UB", + [URr] = "rotation UR", + [URm] = "mirrored UR", + [DFr] = "rotation DF", + [DFm] = "mirrored DF", + [DLr] = "rotation DL", + [DLm] = "mirrored DL", + [DBr] = "rotation DB", + [DBm] = "mirrored DB", + [DRr] = "rotation DR", + [DRm] = "mirrored DR", + [RUr] = "rotation RU", + [RUm] = "mirrored RU", + [RFr] = "rotation RF", + [RFm] = "mirrored RF", + [RDr] = "rotation RD", + [RDm] = "mirrored RD", + [RBr] = "rotation RB", + [RBm] = "mirrored RB", + [LUr] = "rotation LU", + [LUm] = "mirrored LU", + [LFr] = "rotation LF", + [LFm] = "mirrored LF", + [LDr] = "rotation LD", + [LDm] = "mirrored LD", + [LBr] = "rotation LB", + [LBm] = "mirrored LB", + [FUr] = "rotation FU", + [FUm] = "mirrored FU", + [FRr] = "rotation FR", + [FRm] = "mirrored FR", + [FDr] = "rotation FD", + [FDm] = "mirrored FD", + [FLr] = "rotation FL", + [FLm] = "mirrored FL", + [BUr] = "rotation BU", + [BUm] = "mirrored BU", + [BRr] = "rotation BR", + [BRm] = "mirrored BR", + [BDr] = "rotation BD", + [BDm] = "mirrored BD", + [BLr] = "rotation BL", + [BLm] = "mirrored BL", +}; + cube_t solvedcube = { .c = { [_c_ufr] = _c_ufr, @@ -452,6 +503,21 @@ readmoves_error: return -1; } +trans_t +readtrans(char *buf) +{ + uint8_t t; + + for (t = 0; t < 48; t++) + if (!strncmp(buf, transstr[t], 11)) + return t; + +#ifdef DEBUG + fprintf(stderr, "readtrans error\n"); +#endif + return errortrans; +} + void writemoves(move_t *m, int n, char *buf) { @@ -469,6 +535,15 @@ writemoves(move_t *m, int n, char *buf) *b = '\0'; } +void +writetrans(trans_t t, char *buf) +{ + if (t >= 48) + memcpy(buf, "error trans", 11); + else + memcpy(buf, transstr[t], 11); + buf[11] = '\0'; +} static int permsign(uint8_t *a, int n) diff --git a/test/05_transform/00_solved_UFr.in b/test/05_transform/00_solved_UFr.in @@ -0,0 +1,2 @@ +rotation UF +UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0 diff --git a/test/05_transform/00_solved_UFr.out b/test/05_transform/00_solved_UFr.out @@ -0,0 +1 @@ +UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0 diff --git a/test/05_transform/01_solved_BLm.in b/test/05_transform/01_solved_BLm.in @@ -0,0 +1,2 @@ +mirrored BL +UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0 diff --git a/test/05_transform/01_solved_BLm.out b/test/05_transform/01_solved_BLm.out @@ -0,0 +1 @@ +UF0 UB0 DB0 DF0 UR0 UL0 DL0 DR0 FR0 FL0 BL0 BR0 UFR0 UBL0 DFL0 DBR0 UFL0 UBR0 DFR0 DBL0 diff --git a/test/05_transform/transform_tests.c b/test/05_transform/transform_tests.c @@ -0,0 +1,38 @@ +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> + +#include "../../src/cube.h" +#include "../../src/constants.h" + +#define STRLENMAX 10000 + +int main() { + char str[STRLENMAX]; + trans_t t; + cube_t cube; + + fgets(str, STRLENMAX, stdin); + t = readtrans(str); + + if (t == errortrans) { + printf("Error reading trans\n"); + return 1; + } + + fgets(str, STRLENMAX, stdin); + cube = readcube(H48, str); + + cube = transform(cube, t); + + if (iserror(cube)) { + printf("Error transforming cube\n"); + } else if (!issolvable(cube)) { + printf("Transformed cube is not solvable\n"); + } else { + writecube(H48, cube, str); + printf("%s\n", str); + } + + return 0; +} diff --git a/utils/TRANSFORMATIONS.txt b/utils/TRANSFORMATIONS.txt @@ -8,6 +8,12 @@ the rotation that brings the F face on top and the D face on front. 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: + 1a. Apply a mirror along the M plane to the solved cube + 1b. 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 + The orientation of pieces after a rotation ignores the new position of centers. A rotated cube can technically be inconsistent, because the parity of the edge permutation has to be adjusted considering the diff --git a/utils/mirror.sh b/utils/mirror.sh @@ -1,3 +1,3 @@ #!/bin/sh -sed 's/R/l/g ; s/L/R/g ; s/l/L/g' +tr 'LR' 'RL' diff --git a/utils/transform_moves.txt b/utils/transform_moves.txt @@ -0,0 +1,95 @@ +UFr U U +UFr R R +UFr F F + +ULr U U +ULr R F +ULr F L + +UBr U U +UBr R L +UBr F B + +URr U U +URr R B +URr F R + +DFr U D +DFr R L +DFr F F + +DLr U D +DLr R B +DLr F L + +DBr U D +DBr R R +DBr F B + +DRr U D +DRr R F +DRr F R + +RUr U R +RUr R F +RUr F U + +RFr U R +RFr R D +RFr F F + +RDr U R +RDr R B +RDr F D + +RBr U R +RBr R U +RBr F B + +LUr U L +LUr R B +LUr F U + +LFr U L +LFr R U +LFr F F + +LDr U L +LDr R F +LDr F D + +LBr U L +LBr R D +LBr F B + +FUr U F +FUr R L +FUr F U + +FRr U F +FRr R U +FRr F R + +FDr U F +FDr R R +FDr F D + +FLr U F +FLr R D +FLr F L + +BUr U B +BUr R R +BUr F U + +BRr U B +BRr R D +BRr F R + +BDr U B +BDr R L +BDr F D + +BLr U B +BLr R U +BLr F L