nissy-core

The "engine" of nissy, including the H48 optimal solver.
git clone https://git.tronto.net/nissy-core
Download | Log | Files | Refs | README | LICENSE

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 }