nissy-nx

A Rubik's cube optimal solver
git clone https://git.tronto.net/nissy-nx
Download | Log | Files | Refs | README | LICENSE

movesets.c (3719B)


      1 #define MOVESETS_C
      2 
      3 #include "movesets.h"
      4 
      5 static bool allowed_HTM(Move m);
      6 static bool allowed_URF(Move m);
      7 static bool allowed_eofb(Move m);
      8 static bool allowed_drud(Move m);
      9 static bool allowed_htr(Move m);
     10 static bool can_append_HTM(Move l2, Move l1, Move m);
     11 static bool can_append_HTM_cached(Alg *alg, Move m, bool inverse);
     12 static bool cancel_niss_HTM_cached(Alg *alg);
     13 static void init_can_append_HTM();
     14 
     15 Moveset
     16 moveset_HTM = {
     17 	.name        = "HTM",
     18 	.allowed     = allowed_HTM,
     19 	.can_append  = can_append_HTM_cached,
     20 	.cancel_niss = cancel_niss_HTM_cached,
     21 };
     22 
     23 Moveset
     24 moveset_URF = {
     25 	.name        = "URF",
     26 	.allowed     = allowed_URF,
     27 	.can_append  = can_append_HTM_cached,
     28 	.cancel_niss = cancel_niss_HTM_cached,
     29 };
     30 
     31 Moveset
     32 moveset_eofb = {
     33 	.name        = "eofb",
     34 	.allowed     = allowed_eofb,
     35 	.can_append  = can_append_HTM_cached,
     36 	.cancel_niss = cancel_niss_HTM_cached,
     37 };
     38 
     39 Moveset
     40 moveset_drud = {
     41 	.name        = "drud",
     42 	.allowed     = allowed_drud,
     43 	.can_append  = can_append_HTM_cached,
     44 	.cancel_niss = cancel_niss_HTM_cached,
     45 };
     46 
     47 Moveset
     48 moveset_htr = {
     49 	.name        = "htr",
     50 	.allowed     = allowed_htr,
     51 	.can_append  = can_append_HTM_cached,
     52 	.cancel_niss = cancel_niss_HTM_cached,
     53 };
     54 
     55 Moveset *
     56 all_movesets[] = {
     57 	&moveset_HTM,
     58 	&moveset_URF,
     59 	&moveset_eofb,
     60 	&moveset_drud,
     61 	&moveset_htr,
     62 	NULL
     63 };
     64 
     65 static uint64_t can_append_HTM_mask[NMOVES][NMOVES];
     66 
     67 static bool
     68 allowed_HTM(Move m)
     69 {
     70 	return m >= U && m <= B3;
     71 }
     72 
     73 static bool
     74 allowed_URF(Move m)
     75 {
     76 	Move b = base_move(m);
     77 
     78 	return b == U || b == R || b == F;
     79 }
     80 
     81 static bool
     82 allowed_eofb(Move m)
     83 {
     84 	Move b = base_move(m);
     85 
     86 	return b == U || b == D || b == R || b == L ||
     87 	       ((b == F || b == B) && m == b+1);
     88 }
     89 
     90 static bool
     91 allowed_drud(Move m)
     92 {
     93 	Move b = base_move(m);
     94 
     95 	return b == U || b == D ||
     96 	       ((b == R || b == L || b == F || b == B) && m == b + 1);
     97 }
     98 
     99 static bool
    100 allowed_htr(Move m)
    101 {
    102 	Move b = base_move(m);
    103 
    104 	return moveset_HTM.allowed(m) && m == b + 1;
    105 }
    106 
    107 static bool
    108 can_append_HTM(Move l2, Move l1, Move m)
    109 {
    110 	bool cancel, cancel_last, cancel_swap;
    111 
    112 	cancel_last = l1 != NULLMOVE && base_move(l1) == base_move(m);
    113 	cancel_swap = l2 != NULLMOVE && base_move(l2) == base_move(m);
    114 	cancel = cancel_last || (commute(l1, l2) && cancel_swap);
    115 
    116 	return !cancel;
    117 }
    118 
    119 static bool
    120 can_append_HTM_cached(Alg *alg, Move m, bool inverse)
    121 {
    122 	Move *moves, l1, l2;
    123 	uint64_t mbit;
    124 	int n;
    125 
    126 	if (inverse) {
    127 		moves = alg->move_inverse;
    128 		n = alg->len_inverse;
    129 	} else {
    130 		moves = alg->move_normal;
    131 		n = alg->len_normal;
    132 	}
    133 
    134 	l1 = n > 0 ? moves[n-1] : NULLMOVE;
    135 	l2 = n > 1 ? moves[n-2] : NULLMOVE;
    136 
    137 	mbit = ((uint64_t)1) << m;
    138 
    139 	return can_append_HTM_mask[l2][l1] & mbit;
    140 }
    141 
    142 static bool
    143 cancel_niss_HTM_cached(Alg *alg)
    144 {
    145 	Move i1, i2;
    146 	int n;
    147 	bool can_first, can_swap;
    148 
    149 	n = alg->len_inverse;
    150 	i1 = n > 0 ? alg->move_inverse[n-1] : NULLMOVE;
    151 	i2 = n > 1 ? alg->move_inverse[n-2] : NULLMOVE;
    152 
    153 	can_first = can_append_HTM_cached(alg, inverse_move(i1), false);
    154 	can_swap  = can_append_HTM_cached(alg, inverse_move(i2), false);
    155 
    156 	return can_first && (!commute(i1, i2) || can_swap);
    157 }
    158 
    159 static void
    160 init_can_append_HTM()
    161 {
    162 	Move l2, l1, m;
    163 
    164 	for (l1 = 0; l1 < NMOVES; l1++)
    165 		for (l2 = 0; l2 < NMOVES; l2++)
    166 			for (m = 0; m < NMOVES; m++)
    167 				if (can_append_HTM(l2, l1, m))
    168 					can_append_HTM_mask[l2][l1]
    169 					    |= (((uint64_t)1) << m);
    170 }
    171 
    172 void
    173 init_moveset(Moveset *ms)
    174 {
    175 	int j;
    176 	Move m;
    177 
    178 	for (j = 0, m = U; m < NMOVES; m++)
    179 		if (ms->allowed(m))
    180 			ms->sorted_moves[j++] = m;
    181 	ms->sorted_moves[j] = NULLMOVE;
    182 
    183 /* TODO: should be here? maybe just init all movesets together anyway... */
    184 	init_can_append_HTM();
    185 }
    186 
    187 void
    188 init_movesets()
    189 {
    190 	int i;
    191 
    192 	for (i = 0; all_movesets[i] != NULL; i++)
    193 		init_moveset(all_movesets[i]);
    194 }