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