]> git.draconx.ca Git - rrace.git/commitdiff
Track elapsed time of the game.
authorNick Bowler <nbowler@draconx.ca>
Thu, 10 Mar 2022 04:44:39 +0000 (23:44 -0500)
committerNick Bowler <nbowler@draconx.ca>
Sat, 12 Mar 2022 21:13:09 +0000 (16:13 -0500)
Since this is a speed solving game, it is kind of important to know
how much time it took to solve the puzzle.  Start by adding a timer to
the game state so we can print elapsed time at the end.  Related GUI
elements will be coming later.

The game will no longer start immediately.  When the program is
launched, it will begin in a winning state.

Makefile.am
m4/.gitignore
m4/gnulib-cache.m4
src/game.c
src/game.h
src/motif.c
src/motif_ui.c

index fba2274ec0883166e27ff61c498d1c920a73536d..60ec4761f4792825c058ccf83bd5f0a6f9edb2ec 100644 (file)
@@ -25,7 +25,8 @@ endif
 rrace_motif_SOURCES = src/game.c src/x11.c src/game.h src/motif.h \
                       src/colour.h src/ewmhicon.c src/ewmhicon.h
 rrace_motif_LDADD = $(libmotifmain_a_OBJECTS) $(libmotifui_a_OBJECTS) \
-                    $(libglohelp_a_OBJECTS) libgnu.a $(MOTIF_LIBS)
+                    $(libglohelp_a_OBJECTS) libgnu.a $(MOTIF_LIBS) \
+                    $(LIB_CLOCK_GETTIME) $(LIB_GETHRXTIME)
 $(rrace_motif_OBJECTS): $(gnulib_headers)
 
 EXTRA_LIBRARIES += libmotifmain.a
@@ -72,7 +73,7 @@ check_PROGRAMS = t/boardmove t/boardbit t/ewmhicon t/rng-test
 EXTRA_DIST += t/xos256ss.c
 
 t_boardmove_SOURCES = t/boardmove.c src/game.c
-t_boardmove_LDADD = libgnu.a
+t_boardmove_LDADD = libgnu.a $(LIB_CLOCK_GETTIME) $(LIB_GETHRXTIME)
 $(t_boardmove_OBJECTS): $(gnulib_headers)
 
 t_boardbit_SOURCES = t/boardbit.c
index ff430e2cb36c94e22a766b684ac07b0dea7beb98..a6713567cbde6b414613b4cb21304ffe955c5920 100644 (file)
@@ -1,8 +1,12 @@
 /00gnulib.m4
 /absolute-header.m4
+/clock_time.m4
 /extensions.m4
 /extern-inline.m4
+/gethrxtime.m4
 /getopt.m4
+/gettime.m4
+/gettimeofday.m4
 /gnulib-common.m4
 /gnulib-comp.m4
 /gnulib-tool.m4
 /pid_t.m4
 /ssize_t.m4
 /stddef_h.m4
+/sys_socket_h.m4
+/sys_time_h.m4
 /sys_types_h.m4
+/time_h.m4
+/timespec.m4
 /unistd_h.m4
 /vararrays.m4
 /warn-on-use.m4
index d1c7383fae70c26177203ff4e715a7f9f2eb15d4..165069a5f7b960db3a18aa30e69ebcf00181f75f 100644 (file)
 #  --no-libtool \
 #  --macro-prefix=gl \
 #  --no-vc-files \
+#  gethrxtime \
 #  getopt-gnu \
 #  inline
 
 # Specification in the form of a few gnulib-tool.m4 macro invocations:
 gl_LOCAL_DIR([])
 gl_MODULES([
+  gethrxtime
   getopt-gnu
   inline
 ])
index f7cc2bb706b519c7b4ed60b4f7ec1b29bcae6f6f..c478eef5b55e97bb2043fcc936640914c7bcb93a 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;
@@ -200,8 +208,19 @@ int game_check_goal(struct board *board)
        return ret;
 }
 
-void game_finish(struct board *board)
+void game_begin(struct board *board)
+{
+       board->time_start = gethrxtime();
+}
+
+static int_fast32_t 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 i;
 
        for (i = 0; i < 4; i++) {
@@ -213,4 +232,6 @@ void game_finish(struct board *board)
         * disable the game since there will be no valid moves.
         */
        board->x = board->y = -1;
+
+       return t;
 }
index 6a02a428551db68e5cee0c4909901ccc95737c84..99b51338a00078a2349b69bb352c3b0fd72de2a0 100644 (file)
@@ -20,6 +20,7 @@
 #define RRACE_GAME_H_
 
 #include <inttypes.h>
+#include <xtime.h>
 
 enum {
        TILE_EMPTY,
@@ -65,8 +66,10 @@ struct board {
         */
        uint_least16_t goal[3];
 
-       /* (x, y) position of the current empty position. */
+       /* (x, y) position of the current empty space. */
        uint_least8_t x, y;
+
+       xtime_t time_start;
 };
 
 /* Return the board bitmap with all bits in column x set */
@@ -178,9 +181,15 @@ void game_reseed(unsigned long long seed);
  */
 void game_reset(struct board *board);
 
+/*
+ * Reset the game start time.
+ */
+void game_begin(struct board *board);
+
 /*
  * Disable new moves and clear all tile bits other than the 9 goal tiles.
+ * Returns the total elapsed time (in ms).
  */
-void game_finish(struct board *board);
+int_fast32_t game_finish(struct board *board);
 
 #endif
index d7eb5e880c63240286a540ff1b1d8de59574aa5e..12959f7664e3a6e02199816a323f3ed16927f1a2 100644 (file)
@@ -140,9 +140,12 @@ static void proc_new_game(Widget w, XEvent *e, String *argv, Cardinal *argc)
                shell = XtParent(shell);
 
        game_reset(&state.board);
+
        x11_redraw_goal(&state, -1);
        x11_redraw_game(&state, -1);
        x11_redraw_icon(&state, shell);
+
+       game_begin(&state.board);
 }
 
 static const XtActionsRec menu_actions[] = {
@@ -154,6 +157,7 @@ static XtAppContext app_initialize(int argc, char **argv)
 {
        XtAppContext app;
        Widget shell;
+       int i;
 
        if (argc > 0)
                progname = argv[0];
@@ -162,7 +166,13 @@ static XtAppContext app_initialize(int argc, char **argv)
        XtAppAddActions(app, (void *)menu_actions, XtNumber(menu_actions));
        ui_initialize(&state, shell);
        x11_initialize(&state, shell);
+
+       /* Begin with the game in winning state */
        game_reset(&state.board);
+       for (i = 0; i < 3; i++)
+               state.board.game[i] = state.board.goal[i] << GOAL_SHIFT;
+       game_finish(&state.board);
+
        state.use_ewmh_icons = ewmh_probe_wm_icon(shell);
        XtRealizeWidget(shell);
 
index eca3e797605d5f42d910439144ac425782a31b4c..c31d8392ac7a828694128c2ec6e617a4faff9e85 100644 (file)
@@ -224,8 +224,18 @@ static void do_input_move(struct app_state *state, int x, int y)
                uint_least32_t mask;
 
                if (game_check_goal(&state->board)) {
-                       printf("You win!\n");
-                       game_finish(&state->board);
+                       int_fast32_t ms = game_finish(&state->board);
+                       unsigned min, sec;
+
+                       /* Negative time just means clock jumps and
+                        * display headaches. */
+                       if (ms < 0)
+                               ms = 0;
+
+                       sec = ms / 1000, ms %= 1000;
+                       min = sec / 60, sec %= 60;
+                       printf("You won!  Time was %u:%.2u:%.3u\n",
+                              min, sec, (unsigned)ms);
                }
 
                /* Figure out which tiles changed */