common.h (5280B)
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 bool solution_lastqt_cw(const solution_moves_t [static 1]); 10 STATIC bool coord_can_switch(const coord_t [static 1], const unsigned char *, 11 size_t, const uint8_t *); 12 STATIC bool coord_is_solved( 13 const coord_t [static 1], uint64_t, const unsigned char *); 14 15 STATIC cube_t coordinate_merge_ce(cube_t, cube_t); 16 STATIC cube_t coordinate_merge_ec(cube_t, cube_t); 17 STATIC cube_t coordinate_merge_cpco(cube_t, cube_t); 18 19 STATIC uint64_t 20 coord_coord_generic( 21 const coord_t coord[static 1], 22 cube_t c, 23 const unsigned char *data 24 ) 25 { 26 const uint32_t *data32; 27 uint32_t d; 28 cube_t tr; 29 30 data32 = (const uint32_t *)(data + INFOSIZE); 31 d = data32[coord->sym.coord(c)]; 32 tr = transform(c, COORD_TTREP(d)); 33 34 return COORD_CLASS(d) * coord->sym.max2 + coord->sym.coord2(tr); 35 } 36 37 STATIC cube_t 38 coord_cube_generic( 39 const coord_t coord[static 1], 40 uint64_t i, 41 const unsigned char *data 42 ) 43 { 44 const unsigned char *datanoinfo; 45 const uint32_t *rep32; 46 cube_t c; 47 48 datanoinfo = data + INFOSIZE; 49 rep32 = (const uint32_t *)(datanoinfo + 4 * (size_t)coord->sym.max); 50 c = coord->sym.cube(rep32[i / coord->sym.max2]); 51 52 return coord->sym.merge(c, coord->sym.cube2(i % coord->sym.max2)); 53 } 54 55 STATIC bool 56 coord_isnasty_generic( 57 const coord_t coord[static 1], 58 uint64_t i, 59 const unsigned char *data 60 ) 61 { 62 const unsigned char *datanoinfo; 63 const uint32_t *classttrep, *rep32; 64 uint32_t r; 65 66 datanoinfo = data + INFOSIZE; 67 classttrep = (const uint32_t *)datanoinfo; 68 rep32 = (const uint32_t *)(datanoinfo + 4 * (size_t)coord->sym.max); 69 r = rep32[i / coord->sym.max2]; 70 71 return COORD_ISNASTY(classttrep[r]); 72 } 73 74 STATIC size_t 75 coord_gendata_generic( 76 const coord_t coord[static 1], 77 unsigned char *data 78 ) 79 { 80 uint64_t i, j, n, t, nasty; 81 unsigned char *datanoinfo; 82 uint32_t *classttrep, *rep; 83 size_t coord_datasize; 84 cube_t c; 85 tableinfo_t info; 86 87 coord_datasize = INFOSIZE + 4*(coord->sym.classes + coord->sym.max); 88 89 if (data == NULL) 90 return coord_datasize; 91 92 datanoinfo = data + INFOSIZE; 93 classttrep = (uint32_t *)datanoinfo; 94 rep = classttrep + coord->sym.max; 95 memset(data, 0xFF, coord_datasize); 96 97 info = (tableinfo_t) { 98 .solver = "coord data for ", 99 .type = TABLETYPE_SPECIAL, 100 .infosize = INFOSIZE, 101 .fullsize = coord_datasize, 102 .hash = 0, 103 .entries = coord->sym.classes + coord->sym.max, 104 .classes = coord->sym.classes, 105 .bits = 32, 106 .base = 0, 107 .maxvalue = 0, 108 .next = 0 109 }; 110 append_name(&info, coord->name); 111 112 for (i = 0, n = 0; i < coord->sym.max; i++) { 113 if (classttrep[i] != 0xFFFFFFFF) 114 continue; 115 116 c = coord->sym.cube(i); 117 for (t = 1, nasty = 0; t < NTRANS && !nasty; t++) { 118 if (!((UINT64_C(1) << t) & coord->trans_mask)) 119 continue; 120 121 nasty = i == coord->sym.coord(transform(c, t)); 122 } 123 124 for (t = 0; t < NTRANS; t++) { 125 if (!((UINT64_C(1) << t) & coord->trans_mask)) 126 continue; 127 128 j = coord->sym.coord(transform(c, t)); 129 classttrep[j] = 130 (n << COORD_CLASS_SHIFT) | 131 (nasty << COORD_ISNASTY_SHIFT) | 132 (inverse_trans(t) << COORD_TTREP_SHIFT); 133 } 134 rep[n++] = i; 135 } 136 137 writetableinfo(&info, coord_datasize, data); 138 139 DBG_ASSERT(n == coord->sym.classes, 140 "%s coordinate data: computed %" PRIu64 " classes, " 141 "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes); 142 143 return coord_datasize; 144 } 145 146 STATIC bool 147 solution_lastqt_cw(const solution_moves_t s[static 1]) 148 { 149 return are_lastmoves_singlecw(s->nmoves, s->moves) && 150 are_lastmoves_singlecw(s->npremoves, s->premoves); 151 } 152 153 STATIC bool 154 solution_always_valid(const solution_moves_t s[static 1]) 155 { 156 return true; 157 } 158 159 STATIC bool 160 coord_can_switch( 161 const coord_t coord[static 1], 162 const unsigned char *data, 163 size_t n, 164 const uint8_t *moves 165 ) 166 { 167 /* 168 This function checks that the last move (or two moves, if parallel) 169 have a non-trivial effect on the coordinate of the solved cube. This 170 works in general for all coordinates that have been used so far, but 171 in more general cases that have not been considered yet it may fail. 172 */ 173 174 uint64_t i; 175 176 DBG_ASSERT(n > 0, "Error: cannot check if coordinate solver " 177 "can use NISS after 0 moves"); 178 179 if (!coord->allow_niss) 180 return false; 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 } 192 193 STATIC bool 194 coord_is_solved( 195 const coord_t coord[static 1], 196 uint64_t i, 197 const unsigned char *data 198 ) 199 { 200 return coord->is_solved == NULL ? i == 0 : coord->is_solved(i, data); 201 } 202 203 STATIC cube_t 204 coordinate_merge_ce(cube_t corners, cube_t edges) 205 { 206 cube_t merged; 207 208 merged = corners; 209 copy_edges(&merged, edges); 210 211 return merged; 212 } 213 214 STATIC cube_t 215 coordinate_merge_ec(cube_t edges, cube_t corners) 216 { 217 return coordinate_merge_ce(corners, edges); 218 } 219 220 STATIC cube_t 221 coordinate_merge_cpco(cube_t cp, cube_t co) 222 { 223 cube_t merged; 224 225 merged = cp; 226 copy_co(&merged, co); 227 228 return merged; 229 }