]> git.draconx.ca Git - rrace.git/blobdiff - src/game.c
Add a debug mode to make the game stupidly easy.
[rrace.git] / src / game.c
index c478eef5b55e97bb2043fcc936640914c7bcb93a..4946f8d137bd3679316025ba1890864de01ed508 100644 (file)
@@ -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++) {