]> git.draconx.ca Git - rrace.git/blobdiff - src/game.c
Add timer display.
[rrace.git] / src / game.c
index bdb18a1c20f1318f90e75fe348fd96699db36281..2ad3a7ed083b885cfddbc3c372b5865bbc72f67b 100644 (file)
@@ -24,6 +24,7 @@
 #include <limits.h>
 #include <string.h>
 #include <time.h>
+#include <gethrxtime.h>
 #include "game.h"
 
 #define B64(x) ((x) & 0xffffffffffffffff)
@@ -123,8 +124,15 @@ void game_reset(struct board *board)
        unsigned char tiles[25];
        unsigned i;
 
-       if (!rng_is_seeded())
-               game_reseed(time(NULL));
+       if (!rng_is_seeded()) {
+               unsigned long long seed;
+
+               seed = time(NULL);
+               seed += gethrxtime();
+               seed += seed << 32;
+
+               game_reseed(seed);
+       }
 
        for (i = 0; i < 24; i++) {
                tiles[i] = (i%6) + 1;
@@ -162,14 +170,14 @@ void game_reset(struct board *board)
        }
 }
 
-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);
@@ -184,26 +192,40 @@ 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;
-}
 
-#define GOAL_MASK 0x739c0
+       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_finish(struct board *board)
+void game_begin(struct board *board)
 {
+       board->time_start = gethrxtime();
+}
+
+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 = game_elapsed(board);
        int i;
 
        for (i = 0; i < 4; i++) {
@@ -215,4 +237,6 @@ void game_finish(struct board *board)
         * disable the game since there will be no valid moves.
         */
        board->x = board->y = -1;
+
+       return t;
 }