X-Git-Url: https://git.draconx.ca/gitweb/rrace.git/blobdiff_plain/ec2e7b448d7d0d404c0b3102c5b25ac9464d9fc5..31d8eda9987703c64fc63f4ddb4088cf3be5b7cc:/src/game.c diff --git a/src/game.c b/src/game.c index c478eef..4946f8d 100644 --- a/src/game.c +++ b/src/game.c @@ -168,16 +168,43 @@ void game_reset(struct board *board) 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); @@ -192,20 +219,25 @@ int game_do_move(struct board *board, int x, int 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 |= goal[i] ^ (game[i] >> GOAL_SHIFT); + return (mask << GOAL_SHIFT) & GOAL_MASK; } void game_begin(struct board *board) @@ -213,14 +245,14 @@ 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++) {