nissy-nx

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

alg_tests.c (6134B)


      1 #include "alg_tests.h"
      2 
      3 bool testmethod_append_move(void *);
      4 bool testmethod_new_alg(void *);
      5 /*
      6 bool testmethod_compose_alg(void *);
      7 bool testmethod_inverse_alg(void *);
      8 bool testmethod_on_inverse(void *);
      9 bool testmethod_unniss(void *);
     10 */
     11 
     12 typedef struct {
     13 	Move *move;
     14 	bool *inv;
     15 	int len;
     16 	Move m;
     17 	bool inverse;
     18 } append_move_t;
     19 
     20 Move m_app1[] = {F, x, D3};
     21 bool i_app1[] = {true, false, false};
     22 append_move_t append_move_case1 = {
     23 	.move = m_app1,
     24 	.inv = i_app1,
     25 	.len = 3,
     26 	.m = L3,
     27 	.inverse = false,
     28 };
     29 
     30 Move m_app2[] = {S, U, x2, M2};
     31 bool i_app2[] = {true, false, true, true};
     32 append_move_t append_move_case2 = {
     33 	.move = m_app2,
     34 	.inv = i_app2,
     35 	.len = 4,
     36 	.m = R,
     37 	.inverse = true,
     38 };
     39 
     40 Move m_app3[] = {U, U, U, U, U};
     41 bool i_app3[] = {false, false, false, false, false};
     42 append_move_t append_move_case3 = {
     43 	.move = m_app3,
     44 	.inv = i_app3,
     45 	.len = 5,
     46 	.m = U,
     47 	.inverse = false,
     48 };
     49 
     50 append_move_t *append_move_cases[] = {
     51 	&append_move_case1,
     52 	&append_move_case2,
     53 	&append_move_case3,
     54 };
     55 
     56 Test test_append_move = {
     57 	.name  = "Appending a move to and alg",
     58 	.t     = testmethod_append_move,
     59 	.cases = (void **)append_move_cases,
     60 };
     61 
     62 typedef struct {
     63 	char *str;
     64 	Move *move;
     65 	bool *inv;
     66 	int len;
     67 	Move *move_normal;
     68 	int len_normal;
     69 	Move *move_inverse;
     70 	int len_inverse;
     71 } new_alg_t;
     72 
     73 /* Alg F U B' (L3 D) x M (S) y3 */
     74 Move m_new1[] = {F, U, B3, L3, D, x, M, S, y3};
     75 Move mn_new1[] = {F, U, B3, x, M, y3};
     76 Move mi_new1[] = {L3, D, S};
     77 bool i_new1[] = {false, false, false, true, true, false, false, true, false};
     78 new_alg_t new_alg_case1 = {
     79 	.str = "F U B' (L3 D) x M (S) y3",
     80 	.move = m_new1,
     81 	.inv = i_new1,
     82 	.len = 9,
     83 	.move_normal = mn_new1,
     84 	.len_normal = 6,
     85 	.move_inverse = mi_new1,
     86 	.len_inverse = 3,
     87 };
     88 new_alg_t *new_alg_cases[] = {&new_alg_case1};
     89 
     90 Test test_new_alg = {
     91 	.name  = "Initializing an alg from a string",
     92 	.t     = testmethod_new_alg,
     93 	.cases = (void **)new_alg_cases,
     94 };
     95 
     96 Test *alg_all_tests[] = {
     97 	&test_append_move,
     98 	&test_new_alg,
     99 /*
    100 	&test_append_alg,
    101 	&test_compose_alg,
    102 	&test_inverse_alg,
    103 	&test_on_inverse,
    104 	&test_unniss,
    105 */
    106 	NULL
    107 };
    108 TestSuite alg_suite = {
    109 	.setup    = NULL,
    110 	.tests    = alg_all_tests,
    111 	.teardown = NULL,
    112 };
    113 
    114 TestSuite *alg_suites[] = {
    115 	&alg_suite,
    116 	NULL
    117 };
    118 
    119 bool
    120 testmethod_append_move(void *a)
    121 {
    122 	append_move_t *b = (append_move_t *)a;
    123 	int li, ln;
    124 	Alg *alg;
    125 
    126 	/* Small to test reallocation */
    127 	alg = malloc(sizeof(Alg));
    128 	alg->allocated    = 5;
    129 	alg->move         = malloc(alg->allocated * sizeof(Move));
    130 	alg->inv          = malloc(alg->allocated * sizeof(bool));
    131 	alg->len          = b->len;
    132 	memcpy(alg->move, b->move, alg->len * sizeof(Move));
    133 	memcpy(alg->inv,  b->inv,  alg->len * sizeof(bool));
    134 	alg->move_normal  = malloc(alg->allocated * sizeof(Move));
    135 	alg->move_inverse = malloc(alg->allocated * sizeof(Move));
    136 
    137 	li = ln = 0;
    138 	for (int i = 0; i < alg->len; i++) {
    139 		if (alg->inv[i])
    140 			alg->move_inverse[li++] = alg->move[i];
    141 		else
    142 			alg->move_normal[ln++] = alg->move[i];
    143 	}
    144 	alg->len_inverse = li;
    145 	alg->len_normal = ln;
    146 
    147 	append_move(alg, b->m, b->inverse);
    148 
    149 	if (alg->len != b->len + 1) {
    150 		printf("Alg has wrong len (%d instead of %d)\n",
    151 			alg->len, b->len + 1);
    152 		goto append_move_fail;
    153 	}
    154 	if (alg->move[alg->len-1] != b->m) {
    155 		printf("Wrong last move (%s instead of %s)\n",
    156 			move_string(alg->move[alg->len-1]),
    157 			move_string(b->m));
    158 		goto append_move_fail;
    159 	}
    160 	if (alg->inv[alg->len-1] != b->inverse) {
    161 		printf("Wrong inverse flag for last move "
    162 			"(%s instead of %s)\n",
    163 			b->inverse ? "normal" : "inverse",
    164 			b->inverse ? "inverse" : "normal");
    165 		goto append_move_fail;
    166 	}
    167 	if (b->inverse) {
    168 		if (alg->len_inverse != li + 1 ||
    169 		    alg->len_normal  != ln) {
    170 			printf("%d moves on normal (should be %d)"
    171 			       " and %d on inverse (should be %d)\n",
    172 			       alg->len_normal, ln,
    173 			       alg->len_inverse, li + 1);
    174 			goto append_move_fail;
    175 		}
    176 		if (alg->move_inverse[alg->len_inverse-1] != b->m) {
    177 			printf("Wrong move on inverse (%s instead of %s)\n",
    178 				move_string(alg->move_inverse[alg->len-1]),
    179 				move_string(b->m));
    180 			goto append_move_fail;
    181 		}
    182 	} else {
    183 		if (alg->len_inverse != li ||
    184 		    alg->len_normal  != ln + 1) {
    185 			printf("%d moves on normal (should be %d)"
    186 			       " and %d on inverse (should be %d)\n",
    187 			       alg->len_normal, ln,
    188 			       alg->len_inverse, li + 1);
    189 			goto append_move_fail;
    190 		}
    191 		if (alg->move_normal[alg->len_normal-1] != b->m) {
    192 			printf("Wrong move on normal (%s instead of %s)\n",
    193 				move_string(alg->move_normal[alg->len-1]),
    194 				move_string(b->m));
    195 			goto append_move_fail;
    196 		}
    197 	}
    198 
    199 	free(alg);
    200 	return true;
    201 
    202 append_move_fail:
    203 	free(alg);
    204 	return false;
    205 }
    206 
    207 bool
    208 testmethod_new_alg(void *a)
    209 {
    210 	new_alg_t *b = (new_alg_t *)a;
    211 	Alg *alg = new_alg(b->str);
    212 
    213 	if (alg->len != b->len) {
    214 		printf("Algs have different length (%d instead of %d)\n",
    215 			alg->len, b->len);
    216 		goto new_alg_fail;
    217 	}
    218 
    219 	for (int i = 0; i < alg->len; i++) {
    220 		if (alg->move[i] != b->move[i] || alg->inv[i] != b->inv[i]) {
    221 			printf("Algs differ on move %d\n", i);
    222 			printf("Expected: %s\nActual:   ", b->str);
    223 			print_alg(alg, false);
    224 			goto new_alg_fail;
    225 		}
    226 	}
    227 
    228 	if (alg->len_normal != b->len_normal) {
    229 		printf("Algs have different number of moves on normal"
    230 			" (%d instead of %d)\n",
    231 			alg->len_normal, b->len_normal);
    232 		goto new_alg_fail;
    233 	}
    234 	for (int i = 0; i < alg->len_normal; i++) {
    235 		if (alg->move_normal[i] != b->move_normal[i]) {
    236 			printf("Algs have different move %d on normal"
    237 				" (%s instead of %s)\n", i,
    238 				move_string(alg->move_normal[i]),
    239 				move_string(b->move_normal[i]));
    240 			goto new_alg_fail;
    241 		}
    242 	}
    243 
    244 	if (alg->len_inverse != b->len_inverse) {
    245 		printf("Algs have different number of moves on inverse"
    246 			" (%d instead of %d)\n",
    247 			alg->len_inverse, b->len_inverse);
    248 		goto new_alg_fail;
    249 	}
    250 	for (int i = 0; i < alg->len_inverse; i++) {
    251 		if (alg->move_inverse[i] != b->move_inverse[i]) {
    252 			printf("Algs have different move %d on inverse:\n"
    253 				" (%s instead of %s)\n", i,
    254 				move_string(alg->move_inverse[i]),
    255 				move_string(b->move_inverse[i]));
    256 			goto new_alg_fail;
    257 		}
    258 	}
    259 
    260 	free(alg);
    261 	return true;
    262 
    263 new_alg_fail:
    264 	free(alg);
    265 	return false;
    266 }