X-Git-Url: https://git.draconx.ca/gitweb/rrace.git/blobdiff_plain/2529a9651d160ab3a17118d778f5e5584d040765..26fb4b6902a32be6e9f504bee44724a0dd4292f7:/src/game.c?ds=inline
diff --git a/src/game.c b/src/game.c
index bd1fef9..f7cc2bb 100644
--- a/src/game.c
+++ b/src/game.c
@@ -1,8 +1,25 @@
/*
+ * Slide puzzle core game logic
+ * Copyright © 2022 Nick Bowler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
* The RNG implementation is adapted from xoshiro256** and splitmix64
* by David Blackman and Sebastiano Vigna, originally distributed under
* the Creative Commons Zero public domain dedication.
*/
+
#include
#include
#include
@@ -117,36 +134,30 @@ void game_reset(struct board *board)
memset(board->goal, 0, sizeof board->goal);
for (i = 0; i < 9; i++) {
- uint_fast32_t position = board_position(i/3+1, i%3+1);
-
- if (tiles[i] & 1)
- board->goal[0] |= position >> 6;
- if (tiles[i] & 2)
- board->goal[1] |= position >> 6;
- if (tiles[i] & 4)
- board->goal[2] |= position >> 6;
+ uint_fast32_t position = board_position(i/3+1, i%3+1) >> 6;
+
+ if (tiles[i] & 1) board->goal[0] |= position;
+ if (tiles[i] & 2) board->goal[1] |= position;
+ if (tiles[i] & 4) board->goal[2] |= position;
}
tiles[24] = TILE_EMPTY;
shuffle(tiles, 25);
- memset(board->game, 0, sizeof board->game);
+ memset(board->game, 0, sizeof board->game);
for (i = 0; i < 25; i++) {
unsigned x = i/5, y = i%5;
uint_fast32_t position;
position = board_position(x, y);
- if (tiles[i] == TILE_EMPTY) {
- board->game[0] = 0x1ffffff ^ position;
+ if (tiles[i] != TILE_EMPTY) {
+ if (tiles[i] & 1) board->game[0] |= position;
+ if (tiles[i] & 2) board->game[1] |= position;
+ if (tiles[i] & 4) board->game[2] |= position;
+ } else {
+ board->game[3] = ~position;
board->x = x;
board->y = y;
- } else {
- if (tiles[i] & 1)
- board->game[1] |= position;
- if (tiles[i] & 2)
- board->game[2] |= position;
- if (tiles[i] & 4)
- board->game[3] |= position;
}
}
}
@@ -179,3 +190,27 @@ int game_do_move(struct board *board, int x, int y)
board->y = y;
return 0;
}
+
+int game_check_goal(struct board *board)
+{
+ int i, ret = 1;
+
+ for (i = 0; i < 3; i++)
+ ret &= ((board->game[i] & GOAL_MASK) >> 6) == board->goal[i];
+ return ret;
+}
+
+void game_finish(struct board *board)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ board->game[i] &= GOAL_MASK;
+ }
+
+ /*
+ * Setting both x and y hole location to a bogus value will effectively
+ * disable the game since there will be no valid moves.
+ */
+ board->x = board->y = -1;
+}