commit 0b1930307f41db3ea7552d6b2f4666b33c64d26a
parent b218c803ae1110b08b4896be0a59177e280c9091
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Sun, 9 Jun 2024 20:06:19 +0200
More cleanup
Diffstat:
16 files changed, 550 insertions(+), 1516 deletions(-)
diff --git a/TODO.txt b/TODO.txt
@@ -1,18 +1,23 @@
Refactoring: remove cube_fast_t and add b32 format
- - fix all public functions in cube.h
- and their implementations in cube_generic
- - cube i/o format
- move all formats other than b32 to convert.{c,h}
- add tests for conversion
- convert test files (?)
- make b32 default
- replace utils/*.c with a generic convert utility
+ - cleanup cube.h
+ remove some documentation, move to new file
+ create src/cube_pulic.h for implementations of cube.h stuff
+ - switch to b32 by default (part 1)
+ add tests for b32 (write at some by hand)
+ - fix utility code in utils/*.c
+ replace h48_to_lst with convert.c
+ fix invert.c
+ fix utils/*.sh scripts to use the new convert
+ convert all utils/cubes/*.txt files in b32 format
+ - switch to b32 by default (part 2)
+ change all tests to use b32
- if all public functions work with strings, always use return value
as error code (solve already does this), and use string as buffer
to print error
Transform with big table
- make static cube actually static (how?)
+ - if not possible, cleanup in some way
Solver
- write a solver (how many tricks? some, but not all are needed)
diff --git a/old/_trans_move_arr.c b/old/_trans_move_arr.c
@@ -1,389 +0,0 @@
-static cube_t trans_move_cube[] = {
- [UFr] = {
- .c = {0, 1, 2, 3, 4, 5, 6, 7},
- .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
- },
- [ULr] = {
- .c = {4, 5, 7, 6, 1, 0, 2, 3},
- .e = {5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24}
- },
- [UBr] = {
- .c = {1, 0, 3, 2, 5, 4, 7, 6},
- .e = {1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9}
- },
- [URr] = {
- .c = {5, 4, 6, 7, 0, 1, 3, 2},
- .e = {4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26}
- },
- [DFr] = {
- .c = {2, 3, 0, 1, 6, 7, 4, 5},
- .e = {3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10}
- },
- [DLr] = {
- .c = {7, 6, 4, 5, 2, 3, 1, 0},
- .e = {6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27}
- },
- [DBr] = {
- .c = {3, 2, 1, 0, 7, 6, 5, 4},
- .e = {2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8}
- },
- [DRr] = {
- .c = {6, 7, 5, 4, 3, 2, 0, 1},
- .e = {7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25}
- },
- [RUr] = {
- .c = {64, 67, 65, 66, 37, 38, 36, 39},
- .e = {20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3}
- },
- [RFr] = {
- .c = {38, 37, 36, 39, 64, 67, 66, 65},
- .e = {24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18}
- },
- [RDr] = {
- .c = {67, 64, 66, 65, 38, 37, 39, 36},
- .e = {23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1}
- },
- [RBr] = {
- .c = {37, 38, 39, 36, 67, 64, 65, 66},
- .e = {27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16}
- },
- [LUr] = {
- .c = {65, 66, 64, 67, 36, 39, 37, 38},
- .e = {21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2}
- },
- [LFr] = {
- .c = {36, 39, 38, 37, 66, 65, 64, 67},
- .e = {25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17}
- },
- [LDr] = {
- .c = {66, 65, 67, 64, 39, 36, 38, 37},
- .e = {22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0}
- },
- [LBr] = {
- .c = {39, 36, 37, 38, 65, 66, 67, 64},
- .e = {26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19}
- },
- [FUr] = {
- .c = {68, 70, 69, 71, 32, 34, 33, 35},
- .e = {16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6}
- },
- [FRr] = {
- .c = {32, 34, 35, 33, 70, 68, 69, 71},
- .e = {8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21}
- },
- [FDr] = {
- .c = {70, 68, 71, 69, 34, 32, 35, 33},
- .e = {19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4}
- },
- [FLr] = {
- .c = {34, 32, 33, 35, 68, 70, 71, 69},
- .e = {9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23}
- },
- [BUr] = {
- .c = {69, 71, 68, 70, 33, 35, 32, 34},
- .e = {17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7}
- },
- [BRr] = {
- .c = {35, 33, 32, 34, 69, 71, 70, 68},
- .e = {11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22}
- },
- [BDr] = {
- .c = {71, 69, 70, 68, 35, 33, 34, 32},
- .e = {18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5}
- },
- [BLr] = {
- .c = {33, 35, 34, 32, 71, 69, 68, 70},
- .e = {10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20}
- },
- [UFm] = {
- .c = {4, 5, 6, 7, 0, 1, 2, 3},
- .e = {0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10}
- },
- [ULm] = {
- .c = {0, 1, 3, 2, 5, 4, 6, 7},
- .e = {4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25}
- },
- [UBm] = {
- .c = {5, 4, 7, 6, 1, 0, 3, 2},
- .e = {1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8}
- },
- [URm] = {
- .c = {1, 0, 2, 3, 4, 5, 7, 6},
- .e = {5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27}
- },
- [DFm] = {
- .c = {6, 7, 4, 5, 2, 3, 0, 1},
- .e = {3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11}
- },
- [DLm] = {
- .c = {3, 2, 0, 1, 6, 7, 5, 4},
- .e = {7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26}
- },
- [DBm] = {
- .c = {7, 6, 5, 4, 3, 2, 1, 0},
- .e = {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9}
- },
- [DRm] = {
- .c = {2, 3, 1, 0, 7, 6, 4, 5},
- .e = {6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24}
- },
- [RUm] = {
- .c = {68, 71, 69, 70, 33, 34, 32, 35},
- .e = {21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3}
- },
- [RFm] = {
- .c = {34, 33, 32, 35, 68, 71, 70, 69},
- .e = {25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18}
- },
- [RDm] = {
- .c = {71, 68, 70, 69, 34, 33, 35, 32},
- .e = {22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1}
- },
- [RBm] = {
- .c = {33, 34, 35, 32, 71, 68, 69, 70},
- .e = {26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16}
- },
- [LUm] = {
- .c = {69, 70, 68, 71, 32, 35, 33, 34},
- .e = {20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2}
- },
- [LFm] = {
- .c = {32, 35, 34, 33, 70, 69, 68, 71},
- .e = {24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17}
- },
- [LDm] = {
- .c = {70, 69, 71, 68, 35, 32, 34, 33},
- .e = {23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0}
- },
- [LBm] = {
- .c = {35, 32, 33, 34, 69, 70, 71, 68},
- .e = {27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19}
- },
- [FUm] = {
- .c = {64, 66, 65, 67, 36, 38, 37, 39},
- .e = {16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7}
- },
- [FRm] = {
- .c = {36, 38, 39, 37, 66, 64, 65, 67},
- .e = {9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20}
- },
- [FDm] = {
- .c = {66, 64, 67, 65, 38, 36, 39, 37},
- .e = {19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5}
- },
- [FLm] = {
- .c = {38, 36, 37, 39, 64, 66, 67, 65},
- .e = {8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22}
- },
- [BUm] = {
- .c = {65, 67, 64, 66, 37, 39, 36, 38},
- .e = {17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6}
- },
- [BRm] = {
- .c = {39, 37, 36, 38, 65, 67, 66, 64},
- .e = {10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23}
- },
- [BDm] = {
- .c = {67, 65, 66, 64, 39, 37, 38, 36},
- .e = {18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4}
- },
- [BLm] = {
- .c = {37, 39, 38, 36, 67, 65, 64, 66},
- .e = {11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21}
- },
-};
-
-static cube_t trans_move_cube_inverse[] = {
- [UFr] = {
- .c = {0, 1, 2, 3, 4, 5, 6, 7},
- .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
- },
- [ULr] = {
- .c = {5, 4, 6, 7, 0, 1, 3, 2},
- .e = {4, 5, 6, 7, 1, 0, 3, 2, 27, 24, 25, 26}
- },
- [UBr] = {
- .c = {1, 0, 3, 2, 5, 4, 7, 6},
- .e = {1, 0, 3, 2, 5, 4, 7, 6, 10, 11, 8, 9}
- },
- [URr] = {
- .c = {4, 5, 7, 6, 1, 0, 2, 3},
- .e = {5, 4, 7, 6, 0, 1, 2, 3, 25, 26, 27, 24}
- },
- [DFr] = {
- .c = {2, 3, 0, 1, 6, 7, 4, 5},
- .e = {3, 2, 1, 0, 6, 7, 4, 5, 9, 8, 11, 10}
- },
- [DLr] = {
- .c = {7, 6, 4, 5, 2, 3, 1, 0},
- .e = {6, 7, 4, 5, 2, 3, 0, 1, 26, 25, 24, 27}
- },
- [DBr] = {
- .c = {3, 2, 1, 0, 7, 6, 5, 4},
- .e = {2, 3, 0, 1, 7, 6, 5, 4, 11, 10, 9, 8}
- },
- [DRr] = {
- .c = {6, 7, 5, 4, 3, 2, 0, 1},
- .e = {7, 6, 5, 4, 3, 2, 1, 0, 24, 27, 26, 25}
- },
- [RUr] = {
- .c = {32, 34, 35, 33, 70, 68, 69, 71},
- .e = {8, 9, 10, 11, 16, 19, 18, 17, 20, 23, 22, 21}
- },
- [RFr] = {
- .c = {36, 39, 38, 37, 66, 65, 64, 67},
- .e = {25, 26, 27, 24, 21, 22, 23, 20, 16, 19, 18, 17}
- },
- [RDr] = {
- .c = {33, 35, 34, 32, 71, 69, 68, 70},
- .e = {10, 11, 8, 9, 17, 18, 19, 16, 21, 22, 23, 20}
- },
- [RBr] = {
- .c = {37, 38, 39, 36, 67, 64, 65, 66},
- .e = {27, 24, 25, 26, 20, 23, 22, 21, 17, 18, 19, 16}
- },
- [LUr] = {
- .c = {34, 32, 33, 35, 68, 70, 71, 69},
- .e = {9, 8, 11, 10, 19, 16, 17, 18, 22, 21, 20, 23}
- },
- [LFr] = {
- .c = {38, 37, 36, 39, 64, 67, 66, 65},
- .e = {24, 27, 26, 25, 23, 20, 21, 22, 19, 16, 17, 18}
- },
- [LDr] = {
- .c = {35, 33, 32, 34, 69, 71, 70, 68},
- .e = {11, 10, 9, 8, 18, 17, 16, 19, 23, 20, 21, 22}
- },
- [LBr] = {
- .c = {39, 36, 37, 38, 65, 66, 67, 64},
- .e = {26, 25, 24, 27, 22, 21, 20, 23, 18, 17, 16, 19}
- },
- [FUr] = {
- .c = {68, 70, 69, 71, 32, 34, 33, 35},
- .e = {16, 19, 18, 17, 9, 8, 11, 10, 5, 4, 7, 6}
- },
- [FRr] = {
- .c = {64, 67, 65, 66, 37, 38, 36, 39},
- .e = {20, 23, 22, 21, 24, 27, 26, 25, 0, 1, 2, 3}
- },
- [FDr] = {
- .c = {69, 71, 68, 70, 33, 35, 32, 34},
- .e = {17, 18, 19, 16, 11, 10, 9, 8, 4, 5, 6, 7}
- },
- [FLr] = {
- .c = {65, 66, 64, 67, 36, 39, 37, 38},
- .e = {21, 22, 23, 20, 26, 25, 24, 27, 1, 0, 3, 2}
- },
- [BUr] = {
- .c = {70, 68, 71, 69, 34, 32, 35, 33},
- .e = {19, 16, 17, 18, 8, 9, 10, 11, 7, 6, 5, 4}
- },
- [BRr] = {
- .c = {66, 65, 67, 64, 39, 36, 38, 37},
- .e = {22, 21, 20, 23, 25, 26, 27, 24, 3, 2, 1, 0}
- },
- [BDr] = {
- .c = {71, 69, 70, 68, 35, 33, 34, 32},
- .e = {18, 17, 16, 19, 10, 11, 8, 9, 6, 7, 4, 5}
- },
- [BLr] = {
- .c = {67, 64, 66, 65, 38, 37, 39, 36},
- .e = {23, 20, 21, 22, 27, 24, 25, 26, 2, 3, 0, 1}
- },
- [UFm] = {
- .c = {4, 5, 6, 7, 0, 1, 2, 3},
- .e = {0, 1, 2, 3, 5, 4, 7, 6, 9, 8, 11, 10}
- },
- [ULm] = {
- .c = {0, 1, 3, 2, 5, 4, 6, 7},
- .e = {4, 5, 6, 7, 0, 1, 2, 3, 24, 27, 26, 25}
- },
- [UBm] = {
- .c = {5, 4, 7, 6, 1, 0, 3, 2},
- .e = {1, 0, 3, 2, 4, 5, 6, 7, 11, 10, 9, 8}
- },
- [URm] = {
- .c = {1, 0, 2, 3, 4, 5, 7, 6},
- .e = {5, 4, 7, 6, 1, 0, 3, 2, 26, 25, 24, 27}
- },
- [DFm] = {
- .c = {6, 7, 4, 5, 2, 3, 0, 1},
- .e = {3, 2, 1, 0, 7, 6, 5, 4, 8, 9, 10, 11}
- },
- [DLm] = {
- .c = {2, 3, 1, 0, 7, 6, 4, 5},
- .e = {6, 7, 4, 5, 3, 2, 1, 0, 25, 26, 27, 24}
- },
- [DBm] = {
- .c = {7, 6, 5, 4, 3, 2, 1, 0},
- .e = {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9}
- },
- [DRm] = {
- .c = {3, 2, 0, 1, 6, 7, 5, 4},
- .e = {7, 6, 5, 4, 2, 3, 0, 1, 27, 24, 25, 26}
- },
- [RUm] = {
- .c = {70, 68, 69, 71, 32, 34, 35, 33},
- .e = {8, 9, 10, 11, 19, 16, 17, 18, 23, 20, 21, 22}
- },
- [RFm] = {
- .c = {66, 65, 64, 67, 36, 39, 38, 37},
- .e = {25, 26, 27, 24, 22, 21, 20, 23, 19, 16, 17, 18}
- },
- [RDm] = {
- .c = {71, 69, 68, 70, 33, 35, 34, 32},
- .e = {10, 11, 8, 9, 18, 17, 16, 19, 22, 21, 20, 23}
- },
- [RBm] = {
- .c = {67, 64, 65, 66, 37, 38, 39, 36},
- .e = {27, 24, 25, 26, 23, 20, 21, 22, 18, 17, 16, 19}
- },
- [LUm] = {
- .c = {68, 70, 71, 69, 34, 32, 33, 35},
- .e = {9, 8, 11, 10, 16, 19, 18, 17, 21, 22, 23, 20}
- },
- [LFm] = {
- .c = {64, 67, 66, 65, 38, 37, 36, 39},
- .e = {24, 27, 26, 25, 20, 23, 22, 21, 16, 19, 18, 17}
- },
- [LDm] = {
- .c = {69, 71, 70, 68, 35, 33, 32, 34},
- .e = {11, 10, 9, 8, 17, 18, 19, 16, 20, 23, 22, 21}
- },
- [LBm] = {
- .c = {65, 66, 67, 64, 39, 36, 37, 38},
- .e = {26, 25, 24, 27, 21, 22, 23, 20, 17, 18, 19, 16}
- },
- [FUm] = {
- .c = {32, 34, 33, 35, 68, 70, 69, 71},
- .e = {16, 19, 18, 17, 8, 9, 10, 11, 4, 5, 6, 7}
- },
- [FRm] = {
- .c = {37, 38, 36, 39, 64, 67, 65, 66},
- .e = {20, 23, 22, 21, 27, 24, 25, 26, 1, 0, 3, 2}
- },
- [FDm] = {
- .c = {33, 35, 32, 34, 69, 71, 68, 70},
- .e = {17, 18, 19, 16, 10, 11, 8, 9, 5, 4, 7, 6}
- },
- [FLm] = {
- .c = {36, 39, 37, 38, 65, 66, 64, 67},
- .e = {21, 22, 23, 20, 25, 26, 27, 24, 0, 1, 2, 3}
- },
- [BUm] = {
- .c = {34, 32, 35, 33, 70, 68, 71, 69},
- .e = {19, 16, 17, 18, 9, 8, 11, 10, 6, 7, 4, 5}
- },
- [BRm] = {
- .c = {39, 36, 38, 37, 66, 65, 67, 64},
- .e = {22, 21, 20, 23, 26, 25, 24, 27, 2, 3, 0, 1}
- },
- [BDm] = {
- .c = {35, 33, 34, 32, 71, 69, 70, 68},
- .e = {18, 17, 16, 19, 11, 10, 9, 8, 7, 6, 5, 4}
- },
- [BLm] = {
- .c = {38, 37, 39, 36, 67, 64, 66, 65},
- .e = {23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0}
- },
-};
diff --git a/old/gendata_bfs_attempt.c b/old/gendata_bfs_attempt.c
@@ -1,153 +0,0 @@
-_static size_t gendata_cocsep(void *);
-_static uint32_t dfs_cocsep(cube_fast_t, uint8_t, uint8_t, uint32_t *);
-
-/*
-Each element of the cocsep table is a uint32_t used as follows:
- - Lowest 8-bit block: pruning value
- - Second-lower 8-bit block: "ttrep" (transformation to representative)
- - Top 16-bit block: symcoord value
-After the data as described above, more auxiliary information is appended:
- - A uint32_t representing the number of symmetry classes
- - A uint32_t representing the highest value of the pruning table
- - One uint32_t for each "line" of the pruning table, representing the number
- of positions having that pruning value.
-*/
-_static size_t
-gendata_cocsep(void *buf)
-{
- uint32_t *buf32, cc;
- uint64_t i64;
- uint16_t n;
- uint8_t i, j;
- size_t tablesize;
-
- tablesize = _3p7 << 7U;
-
- buf32 = (uint32_t *)buf;
- memset(buf32, 0xFFU, 4*tablesize);
- memset(buf32 + tablesize, 0, 21*4);
-
-/* New impl BFS
-
- uint32_t nold = 0, nnew = 0;
- uint64_t coord;
- uint8_t m, olddepth;
- cube_fast_t c, d, oldlevel[100000], newlevel[100000];
- newlevel[0] = cubetofast(solvedcube());
- nnew = 1;
- buf32[coord_fast_cocsep(newlevel[0])] = UFr << 8U;
- n = 1;
- DBG_LOG("gendata_cocsep: found 1 position at depth 0\n");
- for (i = 1; i < 10; i++) {
- DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i);
- memcpy(oldlevel, newlevel, nnew * sizeof(cube_fast_t));
- nold = nnew;
- nnew = 0;
- for (j = 0; j < nold; j++) {
- _foreach_move(m, oldlevel[j], newlevel[nnew],
- coord = coord_fast_cocsep(newlevel[nnew]);
- olddepth = buf32[coord] & 0xFFU;
- buf32[coord] = i;
- nnew += olddepth > i;
- )
- }
- DBG_LOG("found %" PRIu32 "\n", nnew);
- }
-
-End new impl BFS */
-
- /* Pruning values */
- buf32[tablesize+1] = 9U; /* Known max pruning value */
- for (i = 0, cc = 0; i < 10; i++) {
- DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i);
- cc = dfs_cocsep(cubetofast(solvedcube()), 0, i, buf32);
- buf32[tablesize+i+2] = cc;
- DBG_LOG("found %" PRIu32 "\n", cc);
- }
-
- /* Symmetries */
- for (i64 = 0, n = 0; i64 < tablesize; i64++) {
- }
- buf32[tablesize] = (uint32_t)n;
-
- DBG_LOG("cocsep data computed, %" PRIu32 " symmetry classes\n", n);
- DBG_LOG("Maximum pruning value: %" PRIu32 "\n", buf32[tablesize+1]);
- DBG_LOG("Pruning value distribution:\n");
- for (j = 0; j < 10; j++)
- DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, buf32[tablesize+j+2]);
-
- return 4*(tablesize + 11);
-}
-
-_static uint32_t
-dfs_cocsep(cube_fast_t c, uint8_t depth, uint8_t maxdepth, uint32_t *buf32)
-{
- uint8_t m, olddepth;
- uint32_t update, cc;
- uint64_t i;
- cube_fast_t d;
-
- i = coord_fast_cocsep(c);
- olddepth = (uint8_t)(buf32[i] & 0xFFU);
- if (olddepth < depth)
- return 0;
-
- if (depth == maxdepth) {
- update = (buf32[i] & 0xFFU) == 0xFFU;
- buf32[i] = depth;
- return update;
- }
-
- cc = 0;
- _foreach_move(m, c, d,
- cc += dfs_cocsep(d, depth+1, maxdepth, buf32);
- )
-
- return cc;
-}
-
-/*
-_static uint32_t
-dfs_cocsep(
- cube_fast_t c,
- uint8_t depth,
- uint8_t maxdepth,
- uint16_t *n,
- uint32_t *buf32
-)
-{
- uint8_t m, t, tinv, olddepth;
- uint32_t cc, oldvalue;
- uint64_t i;
- cube_fast_t d;
-
- oldvalue = buf32[coord_fast_cocsep(c)];
- if (depth == maxdepth) {
- if ((oldvalue & 0xFFU) != 0xFFU)
- return 0;
-
- for (t = 0, cc = 0; t < 48; t++) {
- d = transform(c, t);
- i = coord_fast_cocsep(d);
- tinv = inverse_trans(t);
- if ((buf32[i] & 0xFFU) == 0xFFU)
- cc++;
- buf32[i] = (*n << 16U) | (tinv << 8U) | depth;
- }
- (*n)++;
-
- return cc;
- }
-
- olddepth = (uint8_t)(oldvalue & 0xFFU);
- if (olddepth != depth)
- return 0;
-
- cc = 0;
- _foreach_move(m, c, d,
- cc += dfs_cocsep(d, depth+1, maxdepth, n, buf32);
- )
-
- return cc;
-}
-*/
diff --git a/old/inverse_fast.c b/old/inverse_fast.c
@@ -1,51 +0,0 @@
-_static_inline cube_fast_t
-cleanaftershuffle(cube_fast_t c)
-{
- __m256i b;
-
- b = _mm256_set_epi8(
- ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0
- );
-
- return _mm256_andnot_si256(b, c);
-}
-
-_static_inline cube_fast_t
-inverse_fast(cube_fast_t c)
-{
- /* Method taken from Andrew Skalski's vcube[1]. The addition sequence
- * was generated using [2].
- * [1] https://github.com/Voltara/vcube
- * [2] http://wwwhomes.uni-bielefeld.de/achim/addition_chain.html
- */
- cube_fast_t v3, vi, vo, vp, ret;
-
- v3 = _mm256_shuffle_epi8(c, c);
- v3 = _mm256_shuffle_epi8(v3, c);
- vi = _mm256_shuffle_epi8(v3, v3);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, v3);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, c);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, v3);
- vi = _mm256_shuffle_epi8(vi, vi);
- vi = _mm256_shuffle_epi8(vi, c);
-
- vo = _mm256_and_si256(c, _mm256_or_si256(_eo_avx2, _co2_avx2));
- vo = _mm256_shuffle_epi8(vo, vi);
- vp = _mm256_andnot_si256(_mm256_or_si256(_eo_avx2, _co2_avx2), vi);
- ret = _mm256_or_si256(vp, vo);
- ret = cleanaftershuffle(ret);
-
- return invertco_fast(ret);
-}
diff --git a/old/inverses.c b/old/inverses.c
@@ -1,71 +0,0 @@
-static move_t inverse_move_arr[] = {
- [U] = U3,
- [U2] = U2,
- [U3] = U,
- [D] = D3,
- [D2] = D2,
- [D3] = D,
- [R] = R3,
- [R2] = R2,
- [R3] = R,
- [L] = L3,
- [L2] = L2,
- [L3] = L,
- [F] = F3,
- [F2] = F2,
- [F3] = F,
- [B] = B3,
- [B2] = B2,
- [B3] = B,
-};
-
-static trans_t inverse_trans_arr[] = {
- [UFr] = UFr,
- [ULr] = URr,
- [UBr] = UBr,
- [URr] = URr,
- [DFr] = DFr,
- [DLr] = DLr,
- [DRr] = DRr,
- [DBr] = DBr,
- [RUr] = FRr,
- [RFr] = LFr,
- [RDr] = BLr,
- [RBr] = RBr,
- [LUr] = FLr,
- [LFr] = RFr,
- [LDr] = BRr,
- [LBr] = LBr,
- [FUr] = FUr,
- [FRr] = RUr,
- [FDr] = BUr,
- [FLr] = LUr,
- [BUr] = FDr,
- [BLr] = RDr,
- [BDr] = BDr,
- [BRr] = LDr,
- [UFm] = UFm,
- [ULm] = ULm,
- [UBm] = UBm,
- [URm] = ULm,
- [DFm] = DFm,
- [DLm] = DRm,
- [DRm] = DLm,
- [DBm] = DBm,
- [RUm] = FLm,
- [RFm] = RFm,
- [RDm] = BRm,
- [RBm] = LBm,
- [LUm] = FRm,
- [LFm] = LFm,
- [LDm] = BLm,
- [LBm] = RBm,
- [FUm] = FUm,
- [FRm] = LUm,
- [FDm] = BUm,
- [FLm] = RUm,
- [BUm] = FDm,
- [BLm] = LDm,
- [BDm] = BDm,
- [BRm] = RDm,
-};
diff --git a/old/moves_trans/genmovecode.sh b/old/moves_trans/genmovecode.sh
@@ -1,19 +0,0 @@
-#!/bin/sh
-
-type="${1:-src}"
-
-gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type"
-
-genfuncs() {
- for f in move_??_*.txt; do
- move="$(echo $f | sed 's/.*_// ; s/\.txt//')"
- printf 'static inline cube_fast_t\n_move_%s' "$move"
- printf '(cube_fast_t c)\n{\n'
- printf '\tcube_fast_t m = '
- ./h48_to_"$type" <"$f" | sed '2,4s/^/\t/'
- printf ';\n\n\treturn compose_fast(c, m);\n}\n\n'
- done
-}
-
-genfuncs
-rm -f h48_to_"$type" invert
diff --git a/old/moves_trans/gentranscode.sh b/old/moves_trans/gentranscode.sh
@@ -1,42 +0,0 @@
-#!/bin/sh
-
-type="${1:-src}"
-
-gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type"
-gcc -DDEBUG invert.c ../cube.c -o invert
-
-# Old version
-genarray() {
- for f in transform_??_???.txt; do
- trans="$(echo $f | sed 's/.*_// ; s/\.txt//')"
- printf '[%s] = ' "$trans"
- if [ "$1" = "-i" ]; then
- ./invert <"$f" | ./h48_to_"$type"
- else
- ./h48_to_"$type" <"$f"
- fi
- printf ',\n'
- done
-}
-
-genfuncs() {
- for f in transform_??_???.txt; do
- trans="$(echo $f | sed 's/.*_// ; s/\.txt//')"
- printf 'static inline cube_fast_t\n_trans_%s' "$trans"
- printf '(cube_fast_t c)\n{\n'
- printf '\tcube_fast_t ret;\n\n'
- printf '\tcube_fast_t tn = '
- ./h48_to_"$type" <"$f" | sed '2,4s/^/\t/'
- printf ';\n\tcube_fast_t ti = '
- ./invert <"$f" | ./h48_to_"$type" | sed '2,4 s/^/\t/'
- printf ';\n\n\tret = compose_fast(tn, c);\n'
- printf '\tret = compose_fast(ret, ti);\n'
- if [ -n "$(echo "$trans" | grep "m")" ]; then
- printf '\tret = invertco_fast(ret);\n'
- fi
- printf '\n\treturn ret;\n}\n\n'
- done
-}
-
-genfuncs
-rm -f h48_to_"$type" invert
diff --git a/old/moves_trans/moves_src.c b/old/moves_trans/moves_src.c
@@ -1,264 +0,0 @@
-#define PERM4(r, i, j, k, l) \
- aux = r[i]; \
- r[i] = r[l]; \
- r[l] = r[k]; \
- r[k] = r[j]; \
- r[j] = aux;
-#define PERM22(r, i, j, k, l) \
- aux = r[i]; \
- r[i] = r[j]; \
- r[j] = aux; \
- aux = r[k]; \
- r[k] = r[l]; \
- r[l] = aux;
-#define CO(a, b) \
- aux = (a & _cobits) + (b & _cobits); \
- auy = (aux + _ctwist_cw) >> 2U; \
- auz = (aux + auy) & _cobits2; \
- a = (a & _pbits) | auz;
-#define CO4(r, i, j, k, l) \
- CO(r[i], _ctwist_cw) \
- CO(r[j], _ctwist_cw) \
- CO(r[k], _ctwist_ccw) \
- CO(r[l], _ctwist_ccw)
-#define EO4(r, i, j, k, l) \
- r[i] ^= _eobit; \
- r[j] ^= _eobit; \
- r[k] ^= _eobit; \
- r[l] ^= _eobit;
-
-_static_inline cube_fast_t
-_move_U(cube_fast_t c)
-{
- uint8_t aux;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_uf, _e_ul, _e_ub, _e_ur)
- PERM4(ret.corner, _c_ufr, _c_ufl, _c_ubl, _c_ubr)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_U2(cube_fast_t c)
-{
- uint8_t aux;
- cube_fast_t ret = c;
-
- PERM22(ret.edge, _e_uf, _e_ub, _e_ul, _e_ur)
- PERM22(ret.corner, _c_ufr, _c_ubl, _c_ufl, _c_ubr)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_U3(cube_fast_t c)
-{
- uint8_t aux;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_uf, _e_ur, _e_ub, _e_ul)
- PERM4(ret.corner, _c_ufr, _c_ubr, _c_ubl, _c_ufl)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_D(cube_fast_t c)
-{
- uint8_t aux;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_df, _e_dr, _e_db, _e_dl)
- PERM4(ret.corner, _c_dfr, _c_dbr, _c_dbl, _c_dfl)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_D2(cube_fast_t c)
-{
- uint8_t aux;
- cube_fast_t ret = c;
-
- PERM22(ret.edge, _e_df, _e_db, _e_dr, _e_dl)
- PERM22(ret.corner, _c_dfr, _c_dbl, _c_dbr, _c_dfl)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_D3(cube_fast_t c)
-{
- uint8_t aux;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_df, _e_dl, _e_db, _e_dr)
- PERM4(ret.corner, _c_dfr, _c_dfl, _c_dbl, _c_dbr)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_R(cube_fast_t c)
-{
- uint8_t aux, auy, auz;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_ur, _e_br, _e_dr, _e_fr)
- PERM4(ret.corner, _c_ufr, _c_ubr, _c_dbr, _c_dfr)
-
- CO4(ret.corner, _c_ubr, _c_dfr, _c_ufr, _c_dbr)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_R2(cube_fast_t c)
-{
- uint8_t aux;
- cube_fast_t ret = c;
-
- PERM22(ret.edge, _e_ur, _e_dr, _e_fr, _e_br)
- PERM22(ret.corner, _c_ufr, _c_dbr, _c_ubr, _c_dfr)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_R3(cube_fast_t c)
-{
- uint8_t aux, auy, auz;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_ur, _e_fr, _e_dr, _e_br)
- PERM4(ret.corner, _c_ufr, _c_dfr, _c_dbr, _c_ubr)
-
- CO4(ret.corner, _c_ubr, _c_dfr, _c_ufr, _c_dbr)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_L(cube_fast_t c)
-{
- uint8_t aux, auy, auz;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_ul, _e_fl, _e_dl, _e_bl)
- PERM4(ret.corner, _c_ufl, _c_dfl, _c_dbl, _c_ubl)
-
- CO4(ret.corner, _c_ufl, _c_dbl, _c_dfl, _c_ubl)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_L2(cube_fast_t c)
-{
- uint8_t aux;
- cube_fast_t ret = c;
-
- PERM22(ret.edge, _e_ul, _e_dl, _e_fl, _e_bl)
- PERM22(ret.corner, _c_ufl, _c_dbl, _c_ubl, _c_dfl)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_L3(cube_fast_t c)
-{
- uint8_t aux, auy, auz;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_ul, _e_bl, _e_dl, _e_fl)
- PERM4(ret.corner, _c_ufl, _c_ubl, _c_dbl, _c_dfl)
-
- CO4(ret.corner, _c_ufl, _c_dbl, _c_dfl, _c_ubl)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_F(cube_fast_t c)
-{
- uint8_t aux, auy, auz;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_uf, _e_fr, _e_df, _e_fl)
- PERM4(ret.corner, _c_ufr, _c_dfr, _c_dfl, _c_ufl)
-
- EO4(ret.edge, _e_uf, _e_fr, _e_df, _e_fl)
- CO4(ret.corner, _c_ufr, _c_dfl, _c_dfr, _c_ufl)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_F2(cube_fast_t c)
-{
- uint8_t aux;
- cube_fast_t ret = c;
-
- PERM22(ret.edge, _e_uf, _e_df, _e_fr, _e_fl)
- PERM22(ret.corner, _c_ufr, _c_dfl, _c_ufl, _c_dfr)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_F3(cube_fast_t c)
-{
- uint8_t aux, auy, auz;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_uf, _e_fl, _e_df, _e_fr)
- PERM4(ret.corner, _c_ufr, _c_ufl, _c_dfl, _c_dfr)
-
- EO4(ret.edge, _e_uf, _e_fr, _e_df, _e_fl)
- CO4(ret.corner, _c_ufr, _c_dfl, _c_dfr, _c_ufl)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_B(cube_fast_t c)
-{
- uint8_t aux, auy, auz;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_ub, _e_bl, _e_db, _e_br)
- PERM4(ret.corner, _c_ubr, _c_ubl, _c_dbl, _c_dbr)
-
- EO4(ret.edge, _e_ub, _e_br, _e_db, _e_bl)
- CO4(ret.corner, _c_ubl, _c_dbr, _c_dbl, _c_ubr)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_B2(cube_fast_t c)
-{
- uint8_t aux;
- cube_fast_t ret = c;
-
- PERM22(ret.edge, _e_ub, _e_db, _e_br, _e_bl)
- PERM22(ret.corner, _c_ubr, _c_dbl, _c_ubl, _c_dbr)
-
- return ret;
-}
-
-_static_inline cube_fast_t
-_move_B3(cube_fast_t c)
-{
- uint8_t aux, auy, auz;
- cube_fast_t ret = c;
-
- PERM4(ret.edge, _e_ub, _e_br, _e_db, _e_bl)
- PERM4(ret.corner, _c_ubr, _c_dbr, _c_dbl, _c_ubl)
-
- EO4(ret.edge, _e_ub, _e_br, _e_db, _e_bl)
- CO4(ret.corner, _c_ubl, _c_dbr, _c_dbl, _c_ubr)
-
- return ret;
-}
diff --git a/old/moves_trans/v2/genmovecode.sh b/old/moves_trans/v2/genmovecode.sh
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-type="${1:-src}"
-
-gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type"
-
-lineavx() { printf '#define _move_cube_%s ' "$1"; }
-linesrc() { printf '_static cube_fast_t _move_cube_%s = ' "$1"; }
-sedavx() { sed '1,2s/$/ \\/ ; 3s/$/)/ ; 3q'; }
-sedsrc() { sed '3s/$/ };/ ; 3q'; }
-
-gen() {
- for f in move_??_*.txt; do
- move="$(echo $f | sed 's/.*_// ; s/\.txt//')"
- line$type "$move"
- ./h48_to_"$type" <"$f" | sed$type
- done
-}
-
-gen
-rm -f h48_to_"$type" invert
diff --git a/old/moves_trans/v2/gentranscode.sh b/old/moves_trans/v2/gentranscode.sh
@@ -1,24 +0,0 @@
-#!/bin/sh
-
-type="${1:-src}"
-
-gcc -DDEBUG h48_to_"$type".c ../cube.c -o h48_to_"$type"
-gcc -DDEBUG invert.c ../cube.c -o invert
-
-lineavx() { printf '#define _trans_cube_%s ' "$1"; }
-linesrc() { printf '_static cube_fast_t _trans_cube_%s = ' "$1"; }
-sedavx() { sed '1,2s/$/ \\/ ; 3s/$/)/ ; 3q'; }
-sedsrc() { sed '3s/$/ };/ ; 3q'; }
-
-gen() {
- for f in transform_??_???.txt; do
- trans="$(echo $f | sed 's/.*_// ; s/\.txt//')"
- line$type "$trans"
- ./h48_to_"$type" <"$f" | sed$type
- line$type "${trans}_inverse"
- ./invert <"$f" | ./h48_to_"$type" | sed$type
- done
-}
-
-gen
-rm -f h48_to_"$type" invert
diff --git a/src/cube.c b/src/cube.c
@@ -31,8 +31,10 @@
#include "cube_portable.h"
#endif
+#include "io_move_trans.h"
#include "constant_cubes.h"
#include "cube_generic.h"
+#include "io_cube.h"
/* TODO: work in progress */
#if 0
diff --git a/src/cube_avx2.h b/src/cube_avx2.h
@@ -25,6 +25,7 @@ _static_inline cube_t compose_epcpeo(cube_t, cube_t);
_static_inline cube_t compose_edges(cube_t, cube_t);
_static_inline cube_t compose_corners(cube_t, cube_t);
_static_inline cube_t compose(cube_t, cube_t);
+_static_inline cube_t inverse(cube_t);
_static_inline int64_t coord_co(cube_t);
_static_inline int64_t coord_csep(cube_t);
@@ -135,6 +136,58 @@ compose(cube_t c1, cube_t c2)
return s;
}
+_static_inline cube_t
+cleanaftershuffle(cube_t c)
+{
+ __m256i b;
+
+ b = _mm256_set_epi8(
+ ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0
+ );
+
+ return _mm256_andnot_si256(b, c);
+}
+
+_static_inline cube_t
+inverse(cube_t c)
+{
+ /* Method taken from Andrew Skalski's vcube[1]. The addition sequence
+ * was generated using [2].
+ * [1] https://github.com/Voltara/vcube
+ * [2] http://wwwhomes.uni-bielefeld.de/achim/addition_chain.html
+ */
+ cube_t v3, vi, vo, vp, ret;
+
+ v3 = _mm256_shuffle_epi8(c, c);
+ v3 = _mm256_shuffle_epi8(v3, c);
+ vi = _mm256_shuffle_epi8(v3, v3);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, v3);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, c);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, v3);
+ vi = _mm256_shuffle_epi8(vi, vi);
+ vi = _mm256_shuffle_epi8(vi, c);
+
+ vo = _mm256_and_si256(c, _mm256_or_si256(_eo_avx2, _co2_avx2));
+ vo = _mm256_shuffle_epi8(vo, vi);
+ vp = _mm256_andnot_si256(_mm256_or_si256(_eo_avx2, _co2_avx2), vi);
+ ret = _mm256_or_si256(vp, vo);
+ ret = cleanaftershuffle(ret);
+
+ return invertco(ret);
+}
+
_static_inline int64_t
coord_co(cube_t c)
{
diff --git a/src/cube_generic.h b/src/cube_generic.h
@@ -1,62 +1,27 @@
#define _move(M, c) compose(c, _move_cube_ ## M)
#define _premove(M, c) compose(_move_cube_ ## M, c)
-_static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]);
+_static cube_t solvedcube();
+_static bool isconsistent(cube_t);
+_static bool issolvable(cube_t);
+_static bool issolved(cube_t);
+_static bool iserror(cube_t);
+_static cube_t applymoves(cube_t, const char *);
+_static cube_t applytrans(cube_t, const char *);
+
_static int permsign(uint8_t *, int);
-_static uint8_t readco(const char *);
-_static uint8_t readcp(const char *);
-_static uint8_t readeo(const char *);
-_static uint8_t readep(const char *);
-_static cube_t readcube_B32(const char *);
-_static cube_t readcube_H48(const char *);
-_static uint8_t readpiece_LST(const char **);
-_static cube_t readcube_LST(const char *);
-_static int writepiece_LST(uint8_t, char *);
-_static void writecube_B32(cube_t, char *);
-_static void writecube_H48(cube_t, char *);
-_static void writecube_LST(cube_t, char *);
-_static uint8_t b32toedge(char);
-_static uint8_t b32tocorner(char);
-_static char edgetob32(uint8_t);
-_static char cornertob32(uint8_t);
-_static uint8_t readmove(char);
-_static uint8_t readmodifier(char);
-_static uint8_t readtrans(const char *);
-_static int writemoves(uint8_t *, int, char *);
-_static void writetrans(uint8_t, char *);
_static cube_t move(cube_t, uint8_t);
_static cube_t transform_edges(cube_t, uint8_t);
_static cube_t transform_corners(cube_t, uint8_t);
_static cube_t transform(cube_t, uint8_t);
-_static struct {
- const char *name;
- cube_t (*read)(const char *);
- void (*write)(cube_t, char *);
-} ioformat[] =
-{
- { .name = "B32", .read = readcube_B32, .write = writecube_B32 },
- { .name = "LST", .read = readcube_LST, .write = writecube_LST },
- { .name = "H48", .read = readcube_H48, .write = writecube_H48 },
- { .name = "NONE", .read = NULL, .write = NULL },
-};
-
-_static_inline cube_t
-cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
-{
- return static_cube(
- c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
- e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7],
- e[8], e[9], e[10], e[11]);
-}
-
-cube_t
-solvedcube(void)
+_static cube_t
+solvedcube()
{
return solved;
}
-bool
+_static bool
isconsistent(cube_t cube)
{
uint8_t i, p, e, piece, corner[8], edge[12];
@@ -112,7 +77,7 @@ inconsistent_co:
return false;
}
-bool
+_static bool
issolvable(cube_t cube)
{
uint8_t i, eo, co, piece, edge[12], corner[8], ep[12], cp[8];
@@ -170,32 +135,7 @@ iserror(cube_t cube)
return equal(cube, zero);
}
-cube_t
-inverse(cube_t cube)
-{
- uint8_t i, piece, orien, e[12], c[8], edge[12], corner[8];
-
- DBG_ASSERT(isconsistent(cube), zero,
- "inverse error: inconsistent cube\n");
-
- pieces(&cube, corner, edge);
-
- for (i = 0; i < 12; i++) {
- piece = edge[i];
- orien = piece & _eobit;
- e[piece & _pbits] = i | orien;
- }
-
- for (i = 0; i < 8; i++) {
- piece = corner[i];
- orien = ((piece << 1) | (piece >> 1)) & _cobits2;
- c[piece & _pbits] = i | orien;
- }
-
- return cubefromarray(c, e);
-}
-
-cube_t
+_static cube_t
applymoves(cube_t cube, const char *buf)
{
uint8_t r, m;
@@ -224,7 +164,7 @@ applymoves_error:
return zero;
}
-cube_t
+_static cube_t
applytrans(cube_t cube, const char *buf)
{
uint8_t t;
@@ -237,49 +177,6 @@ applytrans(cube_t cube, const char *buf)
return transform(cube, t);
}
-cube_t
-readcube(const char *format, const char *buf)
-{
- int i;
-
- for (i = 0; ioformat[i].read != NULL; i++)
- if (!strcmp(format, ioformat[i].name))
- return ioformat[i].read(buf);
-
- DBG_LOG("Cannot read cube in the given format\n");
- return zero;
-}
-
-void
-writecube(const char *format, cube_t cube, char *buf)
-{
- char *errormsg;
- size_t len;
-
- if (!isconsistent(cube)) {
- errormsg = "ERROR: cannot write inconsistent cube";
- goto writecube_error;
- }
-
- int i;
-
- for (i = 0; ioformat[i].write != NULL; i++) {
- if (!strcmp(format, ioformat[i].name)) {
- ioformat[i].write(cube, buf);
- return;
- }
- }
-
- errormsg = "ERROR: cannot write cube in the given format";
-
-writecube_error:
- DBG_LOG("writecube error, see stdout for details\n");
- len = strlen(errormsg);
- memcpy(buf, errormsg, len);
- buf[len] = '\n';
- buf[len+1] = '\0';
-}
-
_static int
permsign(uint8_t *a, int n)
{
@@ -293,363 +190,6 @@ permsign(uint8_t *a, int n)
return ret % 2;
}
-_static uint8_t
-readco(const char *str)
-{
- if (*str == '0')
- return 0;
- if (*str == '1')
- return _ctwist_cw;
- if (*str == '2')
- return _ctwist_ccw;
-
- DBG_LOG("Error reading CO\n");
- return _error;
-}
-
-_static uint8_t
-readcp(const char *str)
-{
- uint8_t c;
-
- for (c = 0; c < 8; c++)
- if (!strncmp(str, cornerstr[c], 3) ||
- !strncmp(str, cornerstralt[c], 3))
- return c;
-
- DBG_LOG("Error reading CP\n");
- return _error;
-}
-
-_static uint8_t
-readeo(const char *str)
-{
- if (*str == '0')
- return 0;
- if (*str == '1')
- return _eflip;
-
- DBG_LOG("Error reading EO\n");
- return _error;
-}
-
-_static uint8_t
-readep(const char *str)
-{
- uint8_t e;
-
- for (e = 0; e < 12; e++)
- if (!strncmp(str, edgestr[e], 2))
- return e;
-
- DBG_LOG("Error reading EP\n");
- return _error;
-}
-
-_static cube_t
-readcube_B32(const char *buf)
-{
- int i;
- uint8_t c[8], e[12];
-
- for (i = 0; i < 8; i++) {
- c[i] = b32tocorner(buf[i]);
- DBG_ASSERT(c[i] < 255, zero,
- "Error reading B32 corner %d (char %d)\n", i, i);
- }
-
- for (i = 0; i < 12; i++) {
- e[i] = b32toedge(buf[i+9]);
- DBG_ASSERT(e[i] < 255, zero,
- "Error reading B32 edge %d (char %d)\n", i, i+9);
- }
-
- return cubefromarray(c, e);
-}
-
-_static cube_t
-readcube_H48(const char *buf)
-{
- int i;
- uint8_t piece, orient, c[8], e[12];
- const char *b;
-
- b = buf;
-
- for (i = 0; i < 12; i++) {
- while (*b == ' ' || *b == '\t' || *b == '\n')
- b++;
- if ((piece = readep(b)) == _error)
- return zero;
- b += 2;
- if ((orient = readeo(b)) == _error)
- return zero;
- b++;
- e[i] = piece | orient;
- }
- for (i = 0; i < 8; i++) {
- while (*b == ' ' || *b == '\t' || *b == '\n')
- b++;
- if ((piece = readcp(b)) == _error)
- return zero;
- b += 3;
- if ((orient = readco(b)) == _error)
- return zero;
- b++;
- c[i] = piece | orient;
- }
-
- return cubefromarray(c, e);
-}
-
-_static uint8_t
-readpiece_LST(const char **b)
-{
- uint8_t ret;
- bool read;
-
- while (**b == ',' || **b == ' ' || **b == '\t' || **b == '\n')
- (*b)++;
-
- for (ret = 0, read = false; **b >= '0' && **b <= '9'; (*b)++) {
- read = true;
- ret = ret * 10 + (**b) - '0';
- }
-
- return read ? ret : _error;
-}
-
-_static cube_t
-readcube_LST(const char *buf)
-{
- int i;
- uint8_t c[8], e[12];
-
- for (i = 0; i < 8; i++)
- c[i] = readpiece_LST(&buf);
-
- for (i = 0; i < 12; i++)
- e[i] = readpiece_LST(&buf);
-
- return cubefromarray(c, e);
-}
-
-_static int
-writepiece_LST(uint8_t piece, char *buf)
-{
- char digits[3];
- int i, len;
-
- len = 0;
- while (piece != 0) {
- digits[len++] = (piece % 10) + '0';
- piece /= 10;
- }
-
- if (len == 0)
- digits[len++] = '0';
-
- for (i = 0; i < len; i++)
- buf[i] = digits[len-i-1];
-
- buf[len] = ',';
- buf[len+1] = ' ';
-
- return len+2;
-}
-
-_static void
-writecube_B32(cube_t cube, char *buf)
-{
- int i;
- uint8_t corner[8], edge[12];
-
- pieces(&cube, corner, edge);
-
- for (i = 0; i < 8; i++)
- buf[i] = cornertob32(corner[i]);
-
- buf[8] = '=';
-
- for (i = 0; i < 12; i++)
- buf[i+9] = edgetob32(edge[i]);
-
- buf[21] = '\0';
-}
-
-_static void
-writecube_H48(cube_t cube, char *buf)
-{
- uint8_t piece, perm, orient, corner[8], edge[12];
- int i;
-
- pieces(&cube, corner, edge);
-
- for (i = 0; i < 12; i++) {
- piece = edge[i];
- perm = piece & _pbits;
- orient = (piece & _eobit) >> _eoshift;
- buf[4*i ] = edgestr[perm][0];
- buf[4*i + 1] = edgestr[perm][1];
- buf[4*i + 2] = orient + '0';
- buf[4*i + 3] = ' ';
- }
- for (i = 0; i < 8; i++) {
- piece = corner[i];
- perm = piece & _pbits;
- orient = (piece & _cobits) >> _coshift;
- buf[48 + 5*i ] = cornerstr[perm][0];
- buf[48 + 5*i + 1] = cornerstr[perm][1];
- buf[48 + 5*i + 2] = cornerstr[perm][2];
- buf[48 + 5*i + 3] = orient + '0';
- buf[48 + 5*i + 4] = ' ';
- }
-
- buf[48+39] = '\0';
-}
-
-_static void
-writecube_LST(cube_t cube, char *buf)
-{
- int i;
- size_t ptr;
- uint8_t piece, corner[8], edge[12];
-
- ptr = 0;
- pieces(&cube, corner, edge);
-
- for (i = 0; i < 8; i++) {
- piece = corner[i];
- ptr += writepiece_LST(piece, buf + ptr);
- }
-
- for (i = 0; i < 12; i++) {
- piece = edge[i];
- ptr += writepiece_LST(piece, buf + ptr);
- }
-
- *(buf+ptr-2) = 0;
-}
-
-_static uint8_t
-b32toedge(char c)
-{
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
- return 255;
-
- return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a');
-}
-
-_static uint8_t
-b32tocorner(char c) {
- uint8_t val;
-
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
- return 255;
-
- val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26;
-
- return (val & 7) | ((val & 24) << 2);
-}
-
-_static char
-edgetob32(uint8_t edge)
-{
- return edge <= 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26);
-}
-
-_static char
-cornertob32(uint8_t corner)
-{
- uint8_t val;
-
- val = (corner & 7) | ((corner & 96) >> 2);
-
- return val <= 26 ? 'A' + (char)val : 'a' + (char)(val - 26);
-}
-
-_static uint8_t
-readmove(char c)
-{
- switch (c) {
- case 'U':
- return _move_U;
- case 'D':
- return _move_D;
- case 'R':
- return _move_R;
- case 'L':
- return _move_L;
- case 'F':
- return _move_F;
- case 'B':
- return _move_B;
- default:
- return _error;
- }
-}
-
-_static uint8_t
-readmodifier(char c)
-{
- switch (c) {
- case '1': /* Fallthrough */
- case '2': /* Fallthrough */
- case '3':
- return c - '0' - 1;
- case '\'':
- return 2;
- default:
- return 0;
- }
-}
-
-_static uint8_t
-readtrans(const char *buf)
-{
- uint8_t t;
-
- for (t = 0; t < 48; t++)
- if (!strncmp(buf, transstr[t], 11))
- return t;
-
- DBG_LOG("readtrans error\n");
- return _error;
-}
-
-_static int
-writemoves(uint8_t *m, int n, char *buf)
-{
- int i;
- size_t len;
- const char *s;
- char *b;
-
- for (i = 0, b = buf; i < n; i++, b++) {
- s = movestr[m[i]];
- len = strlen(s);
- memcpy(b, s, len);
- b += len;
- *b = ' ';
- }
-
- if (b != buf)
- b--; /* Remove last space */
- *b = '\0';
-
- return b - buf;
-}
-
-_static void
-writetrans(uint8_t t, char *buf)
-{
- if (t >= 48)
- memcpy(buf, "error trans", 11);
- else
- memcpy(buf, transstr[t], 11);
- buf[11] = '\0';
-}
-
_static cube_t
move(cube_t c, uint8_t m)
{
diff --git a/src/cube_portable.h b/src/cube_portable.h
@@ -22,6 +22,7 @@ _static_inline void compose_corners_inplace(cube_t, cube_t, cube_t *);
_static_inline cube_t compose_edges(cube_t, cube_t);
_static_inline cube_t compose_corners(cube_t, cube_t);
_static_inline cube_t compose(cube_t, cube_t);
+_static_inline cube_t inverse(cube_t);
_static_inline int64_t coord_co(cube_t);
_static_inline int64_t coord_csep(cube_t);
@@ -133,6 +134,27 @@ compose(cube_t c1, cube_t c2)
return ret;
}
+cube_t
+inverse(cube_t cube)
+{
+ uint8_t i, piece, orien;
+ cube_t ret;
+
+ for (i = 0; i < 12; i++) {
+ piece = cube.edge[i];
+ orien = piece & _eobit;
+ ret.edge[piece & _pbits] = i | orien;
+ }
+
+ for (i = 0; i < 8; i++) {
+ piece = cube.corner[i];
+ orien = ((piece << 1) | (piece >> 1)) & _cobits2;
+ ret.corner[piece & _pbits] = i | orien;
+ }
+
+ return ret;
+}
+
_static_inline int64_t
coord_co(cube_t c)
{
diff --git a/src/io_cube.h b/src/io_cube.h
@@ -0,0 +1,359 @@
+_static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]);
+
+_static uint8_t readco(const char *);
+_static uint8_t readcp(const char *);
+_static uint8_t readeo(const char *);
+_static uint8_t readep(const char *);
+_static cube_t readcube_B32(const char *);
+_static cube_t readcube_H48(const char *);
+_static uint8_t readpiece_LST(const char **);
+_static cube_t readcube_LST(const char *);
+
+_static int writepiece_LST(uint8_t, char *);
+_static void writecube_B32(cube_t, char *);
+_static void writecube_H48(cube_t, char *);
+_static void writecube_LST(cube_t, char *);
+
+_static uint8_t b32toedge(char);
+_static uint8_t b32tocorner(char);
+_static char edgetob32(uint8_t);
+_static char cornertob32(uint8_t);
+
+_static struct {
+ const char *name;
+ cube_t (*read)(const char *);
+ void (*write)(cube_t, char *);
+} ioformat[] =
+{
+ { .name = "B32", .read = readcube_B32, .write = writecube_B32 },
+ { .name = "LST", .read = readcube_LST, .write = writecube_LST },
+ { .name = "H48", .read = readcube_H48, .write = writecube_H48 },
+ { .name = "NONE", .read = NULL, .write = NULL },
+};
+
+_static_inline cube_t
+cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
+{
+ return static_cube(
+ c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
+ e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7],
+ e[8], e[9], e[10], e[11]);
+}
+
+cube_t
+readcube(const char *format, const char *buf)
+{
+ int i;
+
+ for (i = 0; ioformat[i].read != NULL; i++)
+ if (!strcmp(format, ioformat[i].name))
+ return ioformat[i].read(buf);
+
+ DBG_LOG("Cannot read cube in the given format\n");
+ return zero;
+}
+
+void
+writecube(const char *format, cube_t cube, char *buf)
+{
+ char *errormsg;
+ size_t len;
+
+ if (!isconsistent(cube)) {
+ errormsg = "ERROR: cannot write inconsistent cube";
+ goto writecube_error;
+ }
+
+ int i;
+
+ for (i = 0; ioformat[i].write != NULL; i++) {
+ if (!strcmp(format, ioformat[i].name)) {
+ ioformat[i].write(cube, buf);
+ return;
+ }
+ }
+
+ errormsg = "ERROR: cannot write cube in the given format";
+
+writecube_error:
+ DBG_LOG("writecube error, see stdout for details\n");
+ len = strlen(errormsg);
+ memcpy(buf, errormsg, len);
+ buf[len] = '\n';
+ buf[len+1] = '\0';
+}
+
+_static uint8_t
+readco(const char *str)
+{
+ if (*str == '0')
+ return 0;
+ if (*str == '1')
+ return _ctwist_cw;
+ if (*str == '2')
+ return _ctwist_ccw;
+
+ DBG_LOG("Error reading CO\n");
+ return _error;
+}
+
+_static uint8_t
+readcp(const char *str)
+{
+ uint8_t c;
+
+ for (c = 0; c < 8; c++)
+ if (!strncmp(str, cornerstr[c], 3) ||
+ !strncmp(str, cornerstralt[c], 3))
+ return c;
+
+ DBG_LOG("Error reading CP\n");
+ return _error;
+}
+
+_static uint8_t
+readeo(const char *str)
+{
+ if (*str == '0')
+ return 0;
+ if (*str == '1')
+ return _eflip;
+
+ DBG_LOG("Error reading EO\n");
+ return _error;
+}
+
+_static uint8_t
+readep(const char *str)
+{
+ uint8_t e;
+
+ for (e = 0; e < 12; e++)
+ if (!strncmp(str, edgestr[e], 2))
+ return e;
+
+ DBG_LOG("Error reading EP\n");
+ return _error;
+}
+
+_static cube_t
+readcube_B32(const char *buf)
+{
+ int i;
+ uint8_t c[8], e[12];
+
+ for (i = 0; i < 8; i++) {
+ c[i] = b32tocorner(buf[i]);
+ DBG_ASSERT(c[i] < 255, zero,
+ "Error reading B32 corner %d (char %d)\n", i, i);
+ }
+
+ for (i = 0; i < 12; i++) {
+ e[i] = b32toedge(buf[i+9]);
+ DBG_ASSERT(e[i] < 255, zero,
+ "Error reading B32 edge %d (char %d)\n", i, i+9);
+ }
+
+ return cubefromarray(c, e);
+}
+
+_static cube_t
+readcube_H48(const char *buf)
+{
+ int i;
+ uint8_t piece, orient, c[8], e[12];
+ const char *b;
+
+ b = buf;
+
+ for (i = 0; i < 12; i++) {
+ while (*b == ' ' || *b == '\t' || *b == '\n')
+ b++;
+ if ((piece = readep(b)) == _error)
+ return zero;
+ b += 2;
+ if ((orient = readeo(b)) == _error)
+ return zero;
+ b++;
+ e[i] = piece | orient;
+ }
+ for (i = 0; i < 8; i++) {
+ while (*b == ' ' || *b == '\t' || *b == '\n')
+ b++;
+ if ((piece = readcp(b)) == _error)
+ return zero;
+ b += 3;
+ if ((orient = readco(b)) == _error)
+ return zero;
+ b++;
+ c[i] = piece | orient;
+ }
+
+ return cubefromarray(c, e);
+}
+
+_static uint8_t
+readpiece_LST(const char **b)
+{
+ uint8_t ret;
+ bool read;
+
+ while (**b == ',' || **b == ' ' || **b == '\t' || **b == '\n')
+ (*b)++;
+
+ for (ret = 0, read = false; **b >= '0' && **b <= '9'; (*b)++) {
+ read = true;
+ ret = ret * 10 + (**b) - '0';
+ }
+
+ return read ? ret : _error;
+}
+
+_static cube_t
+readcube_LST(const char *buf)
+{
+ int i;
+ uint8_t c[8], e[12];
+
+ for (i = 0; i < 8; i++)
+ c[i] = readpiece_LST(&buf);
+
+ for (i = 0; i < 12; i++)
+ e[i] = readpiece_LST(&buf);
+
+ return cubefromarray(c, e);
+}
+
+_static int
+writepiece_LST(uint8_t piece, char *buf)
+{
+ char digits[3];
+ int i, len;
+
+ len = 0;
+ while (piece != 0) {
+ digits[len++] = (piece % 10) + '0';
+ piece /= 10;
+ }
+
+ if (len == 0)
+ digits[len++] = '0';
+
+ for (i = 0; i < len; i++)
+ buf[i] = digits[len-i-1];
+
+ buf[len] = ',';
+ buf[len+1] = ' ';
+
+ return len+2;
+}
+
+_static void
+writecube_B32(cube_t cube, char *buf)
+{
+ int i;
+ uint8_t corner[8], edge[12];
+
+ pieces(&cube, corner, edge);
+
+ for (i = 0; i < 8; i++)
+ buf[i] = cornertob32(corner[i]);
+
+ buf[8] = '=';
+
+ for (i = 0; i < 12; i++)
+ buf[i+9] = edgetob32(edge[i]);
+
+ buf[21] = '\0';
+}
+
+_static void
+writecube_H48(cube_t cube, char *buf)
+{
+ uint8_t piece, perm, orient, corner[8], edge[12];
+ int i;
+
+ pieces(&cube, corner, edge);
+
+ for (i = 0; i < 12; i++) {
+ piece = edge[i];
+ perm = piece & _pbits;
+ orient = (piece & _eobit) >> _eoshift;
+ buf[4*i ] = edgestr[perm][0];
+ buf[4*i + 1] = edgestr[perm][1];
+ buf[4*i + 2] = orient + '0';
+ buf[4*i + 3] = ' ';
+ }
+ for (i = 0; i < 8; i++) {
+ piece = corner[i];
+ perm = piece & _pbits;
+ orient = (piece & _cobits) >> _coshift;
+ buf[48 + 5*i ] = cornerstr[perm][0];
+ buf[48 + 5*i + 1] = cornerstr[perm][1];
+ buf[48 + 5*i + 2] = cornerstr[perm][2];
+ buf[48 + 5*i + 3] = orient + '0';
+ buf[48 + 5*i + 4] = ' ';
+ }
+
+ buf[48+39] = '\0';
+}
+
+_static void
+writecube_LST(cube_t cube, char *buf)
+{
+ int i;
+ size_t ptr;
+ uint8_t piece, corner[8], edge[12];
+
+ ptr = 0;
+ pieces(&cube, corner, edge);
+
+ for (i = 0; i < 8; i++) {
+ piece = corner[i];
+ ptr += writepiece_LST(piece, buf + ptr);
+ }
+
+ for (i = 0; i < 12; i++) {
+ piece = edge[i];
+ ptr += writepiece_LST(piece, buf + ptr);
+ }
+
+ *(buf+ptr-2) = 0;
+}
+
+_static uint8_t
+b32toedge(char c)
+{
+ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
+ return 255;
+
+ return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a');
+}
+
+_static uint8_t
+b32tocorner(char c) {
+ uint8_t val;
+
+ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
+ return 255;
+
+ val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26;
+
+ return (val & 7) | ((val & 24) << 2);
+}
+
+_static char
+edgetob32(uint8_t edge)
+{
+ return edge <= 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26);
+}
+
+_static char
+cornertob32(uint8_t corner)
+{
+ uint8_t val;
+
+ val = (corner & 7) | ((corner & 96) >> 2);
+
+ return val <= 26 ? 'A' + (char)val : 'a' + (char)(val - 26);
+}
diff --git a/src/io_move_trans.h b/src/io_move_trans.h
@@ -0,0 +1,87 @@
+_static uint8_t readmove(char);
+_static uint8_t readmodifier(char);
+_static uint8_t readtrans(const char *);
+_static int writemoves(uint8_t *, int, char *);
+_static void writetrans(uint8_t, char *);
+
+_static uint8_t
+readmove(char c)
+{
+ switch (c) {
+ case 'U':
+ return _move_U;
+ case 'D':
+ return _move_D;
+ case 'R':
+ return _move_R;
+ case 'L':
+ return _move_L;
+ case 'F':
+ return _move_F;
+ case 'B':
+ return _move_B;
+ default:
+ return _error;
+ }
+}
+
+_static uint8_t
+readmodifier(char c)
+{
+ switch (c) {
+ case '1': /* Fallthrough */
+ case '2': /* Fallthrough */
+ case '3':
+ return c - '0' - 1;
+ case '\'':
+ return 2;
+ default:
+ return 0;
+ }
+}
+
+_static uint8_t
+readtrans(const char *buf)
+{
+ uint8_t t;
+
+ for (t = 0; t < 48; t++)
+ if (!strncmp(buf, transstr[t], 11))
+ return t;
+
+ DBG_LOG("readtrans error\n");
+ return _error;
+}
+
+_static int
+writemoves(uint8_t *m, int n, char *buf)
+{
+ int i;
+ size_t len;
+ const char *s;
+ char *b;
+
+ for (i = 0, b = buf; i < n; i++, b++) {
+ s = movestr[m[i]];
+ len = strlen(s);
+ memcpy(b, s, len);
+ b += len;
+ *b = ' ';
+ }
+
+ if (b != buf)
+ b--; /* Remove last space */
+ *b = '\0';
+
+ return b - buf;
+}
+
+_static void
+writetrans(uint8_t t, char *buf)
+{
+ if (t >= 48)
+ memcpy(buf, "error trans", 11);
+ else
+ memcpy(buf, transstr[t], 11);
+ buf[11] = '\0';
+}