common.h (4581B)
1 STATIC uint64_t coord_coord_generic( 2 const coord_t [static 1], cube_t, const unsigned char *); 3 STATIC cube_t coord_cube_generic( 4 const coord_t [static 1], uint64_t, const unsigned char *); 5 STATIC bool coord_isnasty_generic( 6 const coord_t [static 1], uint64_t, const unsigned char *); 7 STATIC size_t coord_gendata_generic(const coord_t [static 1], unsigned char *); 8 9 STATIC void append_coord_name(const coord_t [static 1], char *); 10 STATIC bool solution_lastqt_cw(const solution_moves_t [static 1]); 11 STATIC bool coord_can_switch(const coord_t [static 1], const unsigned char *, 12 size_t n, const uint8_t [n]); 13 14 STATIC uint64_t 15 coord_coord_generic( 16 const coord_t coord[static 1], 17 cube_t c, 18 const unsigned char *data 19 ) 20 { 21 const unsigned char *datanoinfo; 22 const uint32_t *data32; 23 uint32_t d; 24 cube_t tr; 25 26 datanoinfo = data + INFOSIZE; 27 data32 = (const uint32_t *)datanoinfo; 28 d = data32[coord->sym.coord(c)]; 29 tr = transform(c, COORD_TTREP(d)); 30 31 return COORD_CLASS(d) * coord->sym.max2 + coord->sym.coord2(tr); 32 } 33 34 STATIC cube_t 35 coord_cube_generic( 36 const coord_t coord[static 1], 37 uint64_t i, 38 const unsigned char *data 39 ) 40 { 41 const unsigned char *datanoinfo; 42 const uint32_t *rep32; 43 cube_t c; 44 45 datanoinfo = data + INFOSIZE; 46 rep32 = (const uint32_t *)(datanoinfo + 4 * (size_t)coord->sym.max); 47 c = coord->sym.cube(rep32[i / coord->sym.max2]); 48 49 return coord->sym.merge(c, coord->sym.cube2(i % coord->sym.max2)); 50 } 51 52 STATIC bool 53 coord_isnasty_generic( 54 const coord_t coord[static 1], 55 uint64_t i, 56 const unsigned char *data 57 ) 58 { 59 const unsigned char *datanoinfo; 60 const uint32_t *classttrep, *rep32; 61 uint32_t r; 62 63 datanoinfo = data + INFOSIZE; 64 classttrep = (const uint32_t *)datanoinfo; 65 rep32 = (const uint32_t *)(datanoinfo + 4 * (size_t)coord->sym.max); 66 r = rep32[i / coord->sym.max2]; 67 68 return COORD_ISNASTY(classttrep[r]); 69 } 70 71 STATIC size_t 72 coord_gendata_generic( 73 const coord_t coord[static 1], 74 unsigned char *data 75 ) 76 { 77 uint64_t i, j, n, t, nasty; 78 unsigned char *datanoinfo; 79 uint32_t *classttrep, *rep; 80 size_t coord_datasize; 81 cube_t c; 82 tableinfo_t info; 83 84 coord_datasize = INFOSIZE + 4*(coord->sym.classes + coord->sym.max); 85 86 if (data == NULL) 87 return coord_datasize; 88 89 datanoinfo = data + INFOSIZE; 90 classttrep = (uint32_t *)datanoinfo; 91 rep = classttrep + coord->sym.max; 92 memset(data, 0xFF, coord_datasize); 93 94 info = (tableinfo_t) { 95 .solver = "coord data for ", 96 .type = TABLETYPE_SPECIAL, 97 .infosize = INFOSIZE, 98 .fullsize = coord_datasize, 99 .hash = 0, 100 .entries = coord->sym.classes + coord->sym.max, 101 .classes = coord->sym.classes, 102 .bits = 32, 103 .base = 0, 104 .maxvalue = 0, 105 .next = 0 106 }; 107 append_coord_name(coord, info.solver); 108 109 for (i = 0, n = 0; i < coord->sym.max; i++) { 110 if (classttrep[i] != 0xFFFFFFFF) 111 continue; 112 113 c = coord->sym.cube(i); 114 for (t = 1, nasty = 0; t < NTRANS && !nasty; t++) { 115 if (!((UINT64_C(1) << t) & coord->trans_mask)) 116 continue; 117 118 nasty = i == coord->sym.coord(transform(c, t)); 119 } 120 121 for (t = 0; t < NTRANS; t++) { 122 if (!((UINT64_C(1) << t) & coord->trans_mask)) 123 continue; 124 125 j = coord->sym.coord(transform(c, t)); 126 classttrep[j] = 127 (n << COORD_CLASS_SHIFT) | 128 (nasty << COORD_ISNASTY_SHIFT) | 129 (inverse_trans(t) << COORD_TTREP_SHIFT); 130 } 131 rep[n++] = i; 132 } 133 134 writetableinfo(&info, coord_datasize, data); 135 136 DBG_ASSERT(n == coord->sym.classes, SIZE_MAX, 137 "%s coordinate data: computed %" PRIu64 " classes, " 138 "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes); 139 140 return coord_datasize; 141 } 142 143 STATIC void 144 append_coord_name(const coord_t coord[static 1], char *str) 145 { 146 int i, j; 147 148 i = 0; 149 j = strlen(str); 150 while (coord->name[i]) str[j++] = coord->name[i++]; 151 152 str[j] = '\0'; 153 } 154 155 STATIC bool 156 solution_lastqt_cw(const solution_moves_t s[static 1]) 157 { 158 return are_lastmoves_singlecw(s->nmoves, s->moves) && 159 are_lastmoves_singlecw(s->npremoves, s->premoves); 160 } 161 162 STATIC bool 163 coord_can_switch( 164 const coord_t coord[static 1], 165 const unsigned char *data, 166 size_t n, 167 const uint8_t moves[n] 168 ) 169 { 170 /* 171 This function checks that the last move (or two moves, if parallel) 172 have a non-trivial effect on the coordinate of the solved cube. This 173 works in general for all coordinates that have been used so far, but 174 in more general cases that have not been considered yet it may fail. 175 */ 176 177 uint64_t i; 178 179 if (n == 0) 180 return true; 181 182 i = coord->coord(move(SOLVED_CUBE, moves[n-1]), data); 183 if (i == 0) 184 return false; 185 186 if (n == 1 || !parallel(moves[n-1], moves[n-2])) 187 return true; 188 189 i = coord->coord(move(SOLVED_CUBE, moves[n-1]), data); 190 return i != 0; 191 }