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.
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) \
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
$(rrace_motif_OBJECTS): $(gnulib_headers)
EXTRA_LIBRARIES += libmotifmain.a
EXTRA_DIST += t/xos256ss.c
t_boardmove_SOURCES = t/boardmove.c src/game.c
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
$(t_boardmove_OBJECTS): $(gnulib_headers)
t_boardbit_SOURCES = t/boardbit.c
/00gnulib.m4
/absolute-header.m4
/00gnulib.m4
/absolute-header.m4
/extensions.m4
/extern-inline.m4
/extensions.m4
/extern-inline.m4
+/gettime.m4
+/gettimeofday.m4
/gnulib-common.m4
/gnulib-comp.m4
/gnulib-tool.m4
/gnulib-common.m4
/gnulib-comp.m4
/gnulib-tool.m4
/pid_t.m4
/ssize_t.m4
/stddef_h.m4
/pid_t.m4
/ssize_t.m4
/stddef_h.m4
+/sys_socket_h.m4
+/sys_time_h.m4
+/time_h.m4
+/timespec.m4
/unistd_h.m4
/vararrays.m4
/warn-on-use.m4
/unistd_h.m4
/vararrays.m4
/warn-on-use.m4
# --no-libtool \
# --macro-prefix=gl \
# --no-vc-files \
# --no-libtool \
# --macro-prefix=gl \
# --no-vc-files \
# getopt-gnu \
# inline
# Specification in the form of a few gnulib-tool.m4 macro invocations:
gl_LOCAL_DIR([])
gl_MODULES([
# getopt-gnu \
# inline
# Specification in the form of a few gnulib-tool.m4 macro invocations:
gl_LOCAL_DIR([])
gl_MODULES([
#include <limits.h>
#include <string.h>
#include <time.h>
#include <limits.h>
#include <string.h>
#include <time.h>
#include "game.h"
#define B64(x) ((x) & 0xffffffffffffffff)
#include "game.h"
#define B64(x) ((x) & 0xffffffffffffffff)
unsigned char tiles[25];
unsigned i;
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;
for (i = 0; i < 24; i++) {
tiles[i] = (i%6) + 1;
-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++) {
int i;
for (i = 0; i < 4; i++) {
* disable the game since there will be no valid moves.
*/
board->x = board->y = -1;
* disable the game since there will be no valid moves.
*/
board->x = board->y = -1;
#define RRACE_GAME_H_
#include <inttypes.h>
#define RRACE_GAME_H_
#include <inttypes.h>
*/
uint_least16_t goal[3];
*/
uint_least16_t goal[3];
- /* (x, y) position of the current empty position. */
+ /* (x, y) position of the current empty space. */
};
/* Return the board bitmap with all bits in column x set */
};
/* Return the board bitmap with all bits in column x set */
*/
void game_reset(struct board *board);
*/
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.
/*
* 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);
shell = XtParent(shell);
game_reset(&state.board);
shell = XtParent(shell);
game_reset(&state.board);
x11_redraw_goal(&state, -1);
x11_redraw_game(&state, -1);
x11_redraw_icon(&state, shell);
x11_redraw_goal(&state, -1);
x11_redraw_game(&state, -1);
x11_redraw_icon(&state, shell);
+
+ game_begin(&state.board);
}
static const XtActionsRec menu_actions[] = {
}
static const XtActionsRec menu_actions[] = {
{
XtAppContext app;
Widget shell;
{
XtAppContext app;
Widget shell;
if (argc > 0)
progname = argv[0];
if (argc > 0)
progname = argv[0];
XtAppAddActions(app, (void *)menu_actions, XtNumber(menu_actions));
ui_initialize(&state, shell);
x11_initialize(&state, shell);
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);
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);
state.use_ewmh_icons = ewmh_probe_wm_icon(shell);
XtRealizeWidget(shell);
uint_least32_t mask;
if (game_check_goal(&state->board)) {
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 */
}
/* Figure out which tiles changed */