board->y = y;
}
}
+
+/* Uncomment to make every game stupidly easy -- winnable in 1 move */
+#if 0
+ /* Force empty space to the border */
+ if (board_position(board->x, board->y) & GOAL_MASK) {
+ switch (rng_uniform_int(4)) {
+ case 0: game_do_move(board, board->x, 0); break;
+ case 1: game_do_move(board, board->x, 4); break;
+ case 2: game_do_move(board, 0, board->y); break;
+ case 3: game_do_move(board, 4, board->y); break;
+ }
+ }
+
+ /* Force goal to match the current board */
+ for (i = 0; i < 3; i++) {
+ board->goal[i] = (board->game[i] & GOAL_MASK) >> GOAL_SHIFT;
+ }
+
+ /* Move empty space back to the centre */
+ if (board->x == 0 || board->x == 4) {
+ game_do_move(board, 1+rng_uniform_int(3), board->y);
+ }
+
+ if (board->y == 0 || board->y == 4) {
+ game_do_move(board, board->x, 1+rng_uniform_int(3));
+ }
+#endif
}
-int game_do_move(struct board *board, int x, int y)
+uint_fast32_t game_do_move(struct board *board, int x, int y)
{
int bx = board->x, by = board->y;
- uint_least32_t mask, val[4];
+ uint_least32_t ret = 0, mask, val[4];
int i, shl, shr;
if ((bx != x) == (by != y))
- return -1;
+ return 0;
if (bx == x) {
mask = board_mask_v(x, by, y);
for (i = 0; i < 4; i++) {
board->game[i] ^= (val[i] = board->game[i] & mask);
board->game[i] |= val[i] << shl >> shr;
+ ret |= board->game[i] ^ val[i];
}
board->x = x;
board->y = y;
- return 0;
+
+ return mask & ret;
}
-int game_check_goal(struct board *board)
+uint_fast32_t game_check_goal(struct board *board)
{
- int i, ret = 1;
+ uint_least32_t *game = board->game;
+ uint_least16_t *goal = board->goal;
+ uint_least32_t mask = 0;
+ int i;
for (i = 0; i < 3; i++)
- ret &= ((board->game[i] & GOAL_MASK) >> 6) == board->goal[i];
- return ret;
+ mask |= game[i] ^ ((0ul+goal[i]) << GOAL_SHIFT);
+ return mask & GOAL_MASK;
}
void game_begin(struct board *board)
board->time_start = gethrxtime();
}
-static int_fast32_t elapsed(struct board *board)
+int_fast32_t game_elapsed(struct board *board)
{
return (gethrxtime() - board->time_start) / 1000000;
}
int_fast32_t game_finish(struct board *board)
{
- int_fast32_t t = elapsed(board);
+ int_fast32_t t = game_elapsed(board);
int i;
for (i = 0; i < 4; i++) {