From 87a15e960e31365698df7e06cd3e6b851e17c1a5 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Sun, 5 Mar 2023 10:13:01 +0100 Subject: I made a mess, but it works. Still need to implement new optimal solver. After that, a big redesign is due. --- src/movesets.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 src/movesets.c (limited to 'src/movesets.c') diff --git a/src/movesets.c b/src/movesets.c new file mode 100644 index 0000000..d8f5bc1 --- /dev/null +++ b/src/movesets.c @@ -0,0 +1,194 @@ +#define MOVESETS_C + +#include "movesets.h" + +static bool allowed_HTM(Move m); +static bool allowed_URF(Move m); +static bool allowed_eofb(Move m); +static bool allowed_drud(Move m); +static bool allowed_htr(Move m); +static bool can_append_HTM(Move l2, Move l1, Move m); +static bool can_append_HTM_cached(Alg *alg, Move m, bool inverse); +static bool cancel_niss_HTM_cached(Alg *alg); +static void init_can_append_HTM(); + +Moveset +moveset_HTM = { + .name = "HTM", + .allowed = allowed_HTM, + .can_append = can_append_HTM_cached, + .cancel_niss = cancel_niss_HTM_cached, +}; + +Moveset +moveset_URF = { + .name = "URF", + .allowed = allowed_URF, + .can_append = can_append_HTM_cached, + .cancel_niss = cancel_niss_HTM_cached, +}; + +Moveset +moveset_eofb = { + .name = "eofb", + .allowed = allowed_eofb, + .can_append = can_append_HTM_cached, + .cancel_niss = cancel_niss_HTM_cached, +}; + +Moveset +moveset_drud = { + .name = "drud", + .allowed = allowed_drud, + .can_append = can_append_HTM_cached, + .cancel_niss = cancel_niss_HTM_cached, +}; + +Moveset +moveset_htr = { + .name = "htr", + .allowed = allowed_htr, + .can_append = can_append_HTM_cached, + .cancel_niss = cancel_niss_HTM_cached, +}; + +Moveset * +all_movesets[] = { + &moveset_HTM, + &moveset_URF, + &moveset_eofb, + &moveset_drud, + &moveset_htr, + NULL +}; + +static uint64_t can_append_HTM_mask[NMOVES][NMOVES]; + +static bool +allowed_HTM(Move m) +{ + return m >= U && m <= B3; +} + +static bool +allowed_URF(Move m) +{ + Move b = base_move(m); + + return b == U || b == R || b == F; +} + +static bool +allowed_eofb(Move m) +{ + Move b = base_move(m); + + return b == U || b == D || b == R || b == L || + ((b == F || b == B) && m == b+1); +} + +static bool +allowed_drud(Move m) +{ + Move b = base_move(m); + + return b == U || b == D || + ((b == R || b == L || b == F || b == B) && m == b + 1); +} + +static bool +allowed_htr(Move m) +{ + Move b = base_move(m); + + return moveset_HTM.allowed(m) && m == b + 1; +} + +static bool +can_append_HTM(Move l2, Move l1, Move m) +{ + bool cancel, cancel_last, cancel_swap; + + cancel_last = l1 != NULLMOVE && base_move(l1) == base_move(m); + cancel_swap = l2 != NULLMOVE && base_move(l2) == base_move(m); + cancel = cancel_last || (commute(l1, l2) && cancel_swap); + + return !cancel; +} + +static bool +can_append_HTM_cached(Alg *alg, Move m, bool inverse) +{ + Move *moves, l1, l2; + uint64_t mbit; + int n; + + if (inverse) { + moves = alg->move_inverse; + n = alg->len_inverse; + } else { + moves = alg->move_normal; + n = alg->len_normal; + } + + l1 = n > 0 ? moves[n-1] : NULLMOVE; + l2 = n > 1 ? moves[n-2] : NULLMOVE; + + mbit = ((uint64_t)1) << m; + + return can_append_HTM_mask[l2][l1] & mbit; +} + +static bool +cancel_niss_HTM_cached(Alg *alg) +{ + Move i1, i2; + int n; + bool can_first, can_swap; + + n = alg->len_inverse; + i1 = n > 0 ? alg->move_inverse[n-1] : NULLMOVE; + i2 = n > 1 ? alg->move_inverse[n-2] : NULLMOVE; + + can_first = can_append_HTM_cached(alg, inverse_move(i1), false); + can_swap = can_append_HTM_cached(alg, inverse_move(i2), false); + + return can_first && (!commute(i1, i2) || can_swap); +} + +static void +init_can_append_HTM() +{ + Move l2, l1, m; + + for (l1 = 0; l1 < NMOVES; l1++) + for (l2 = 0; l2 < NMOVES; l2++) + for (m = 0; m < NMOVES; m++) + if (can_append_HTM(l2, l1, m)) + can_append_HTM_mask[l2][l1] + |= (((uint64_t)1) << m); +} + +void +init_moveset(Moveset *ms) +{ + int j; + Move m; + + for (j = 0, m = U; m < NMOVES; m++) + if (ms->allowed(m)) + ms->sorted_moves[j++] = m; + ms->sorted_moves[j] = NULLMOVE; + +/* TODO: should be here? maybe just init all movesets together anyway... */ + init_can_append_HTM(); +} + +void +init_movesets() +{ + int i; + + for (i = 0; all_movesets[i] != NULL; i++) + init_moveset(all_movesets[i]); +} -- cgit v1.3