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 }