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 (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 }