common.h (5326B)
1 STATIC uint64_t coord_coord_generic( 2 const coord_t [NON_NULL], cube_t, const unsigned char *); 3 STATIC cube_t coord_cube_generic( 4 const coord_t [NON_NULL], uint64_t, const unsigned char *); 5 STATIC bool coord_isnasty_generic( 6 const coord_t [NON_NULL], uint64_t, const unsigned char *); 7 STATIC size_t coord_gendata_generic(const coord_t [NON_NULL], unsigned char *); 8 9 STATIC bool solution_lastqt_cw(const solution_moves_t [NON_NULL]); 10 STATIC bool coord_can_switch(const coord_t [NON_NULL], const unsigned char *, 11 size_t, const uint8_t *); 12 STATIC bool coord_is_solved( 13 const coord_t [NON_NULL], 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[NON_NULL], 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[NON_NULL], 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[NON_NULL], 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[NON_NULL], 77 unsigned char *data 78 ) 79 { 80 uint64_t i, j, n, nasty; 81 uint8_t t; 82 unsigned char *datanoinfo; 83 uint32_t *classttrep, *rep; 84 size_t coord_datasize; 85 cube_t c; 86 tableinfo_t info; 87 88 coord_datasize = INFOSIZE + 4*(coord->sym.classes + coord->sym.max); 89 90 if (data == NULL) 91 return coord_datasize; 92 93 datanoinfo = data + INFOSIZE; 94 classttrep = (uint32_t *)datanoinfo; 95 rep = classttrep + coord->sym.max; 96 memset(data, 0xFF, coord_datasize); 97 98 info = (tableinfo_t) { 99 .solver = "coord data for ", 100 .type = TABLETYPE_SPECIAL, 101 .infosize = INFOSIZE, 102 .fullsize = coord_datasize, 103 .hash = 0, 104 .entries = coord->sym.classes + coord->sym.max, 105 .classes = coord->sym.classes, 106 .bits = 32, 107 .base = 0, 108 .maxvalue = 0, 109 .next = 0 110 }; 111 append_name(&info, coord->name); 112 113 for (i = 0, n = 0; i < coord->sym.max; i++) { 114 if (classttrep[i] != 0xFFFFFFFF) 115 continue; 116 117 c = coord->sym.cube(i); 118 for (t = 1, nasty = 0; t < NTRANS && !nasty; t++) { 119 if (!((UINT64_C(1) << t) & coord->trans_mask)) 120 continue; 121 122 nasty = i == coord->sym.coord(transform(c, t)); 123 } 124 125 for (t = 0; t < NTRANS; t++) { 126 if (!((UINT64_C(1) << (uint64_t)t) & coord->trans_mask)) 127 continue; 128 129 j = coord->sym.coord(transform(c, t)); 130 classttrep[j] = (uint32_t)( 131 (n << COORD_CLASS_SHIFT) | 132 (nasty << COORD_ISNASTY_SHIFT) | 133 (inverse_trans(t) << COORD_TTREP_SHIFT) 134 ); 135 } 136 rep[n++] = (uint32_t)i; 137 } 138 139 writetableinfo(&info, coord_datasize, data); 140 141 DBG_ASSERT(n == coord->sym.classes, 142 "%s coordinate data: computed %" PRIu64 " classes, " 143 "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes); 144 145 return coord_datasize; 146 } 147 148 STATIC bool 149 solution_lastqt_cw(const solution_moves_t s[NON_NULL]) 150 { 151 return are_lastmoves_singlecw(s->nmoves, s->moves) && 152 are_lastmoves_singlecw(s->npremoves, s->premoves); 153 } 154 155 STATIC bool 156 solution_always_valid(const solution_moves_t s[NON_NULL]) 157 { 158 return true; 159 } 160 161 STATIC bool 162 coord_can_switch( 163 const coord_t coord[NON_NULL], 164 const unsigned char *data, 165 size_t n, 166 const uint8_t *moves 167 ) 168 { 169 /* 170 This function checks that the last move (or two moves, if parallel) 171 have a non-trivial effect on the coordinate of the solved cube. This 172 works in general for all coordinates that have been used so far, but 173 in more general cases that have not been considered yet it may fail. 174 */ 175 176 uint64_t i; 177 178 DBG_ASSERT(n > 0, "Error: cannot check if coordinate solver " 179 "can use NISS after 0 moves"); 180 181 if (!coord->allow_niss) 182 return false; 183 184 i = coord->coord(move(SOLVED_CUBE, moves[n-1]), data); 185 if (i == 0) 186 return false; 187 188 if (n == 1 || !parallel(moves[n-1], moves[n-2])) 189 return true; 190 191 i = coord->coord(move(SOLVED_CUBE, moves[n-1]), data); 192 return i != 0; 193 } 194 195 STATIC bool 196 coord_is_solved( 197 const coord_t coord[NON_NULL], 198 uint64_t i, 199 const unsigned char *data 200 ) 201 { 202 return coord->is_solved == NULL ? i == 0 : coord->is_solved(i, data); 203 } 204 205 STATIC cube_t 206 coordinate_merge_ce(cube_t corners, cube_t edges) 207 { 208 cube_t merged; 209 210 merged = corners; 211 copy_edges(&merged, edges); 212 213 return merged; 214 } 215 216 STATIC cube_t 217 coordinate_merge_ec(cube_t edges, cube_t corners) 218 { 219 return coordinate_merge_ce(corners, edges); 220 } 221 222 STATIC cube_t 223 coordinate_merge_cpco(cube_t cp, cube_t co) 224 { 225 cube_t merged; 226 227 merged = cp; 228 copy_co(&merged, co); 229 230 return merged; 231 }