2 * Slide puzzle core game logic
3 * Copyright © 2022 Nick Bowler
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
35 enum { GOAL_SHIFT = 6 };
38 * Bit planes representing the current game area.
40 * The 5x5 game board is represented by these four 25-bit values.
41 * The bits are arranged in row-major order so, for example, bit 0
42 * corresponds to position (0,0), bit 4 is position (4,0) and bit 25
45 * game[0] - least significant bit of the tile's colour.
46 * game[1] - tile colour.
47 * game[2] - most significant bit of the tile's colour.
48 * game[3] - the board mask, all bits set except one indicating the
49 * absense of a tile at this position.
51 uint_least32_t game[4];
54 * Bit planes representing the goal area.
56 * These are encoded identically to the game area, except the values
57 * are shifted right by 6 as only bits 6 through 18 are relevant.
59 * goal[0] - least significant bit of the tile's colour.
60 * goal[2] - tile colour.
61 * goal[3] - most significant bit of the tile's colour.
63 uint_least16_t goal[3];
65 /* (x, y) position of the current empty position. */
69 /* Return the board bitmap with all bits in column x set */
70 static inline uint_fast32_t board_column(int x)
72 return 0x108421ul << x;
75 /* Return the board bitmap with all bits in row y set */
76 static inline uint_fast32_t board_row(int y)
81 /* Return the board bitmap with the bit at position (x, y) set. */
82 static inline uint_fast32_t board_position(int x, int y)
84 return 1ul << x << 5*y;
88 * Return the board bitmap with set bits indicating tile locations
89 * that change with the hole at (x0, y) and the play at (x1, y).
91 static inline uint_fast32_t board_mask_h(int y, int x0, int x1)
93 uint_fast32_t row = board_row(y);
96 return (row << x0) & (row >> (4-x1));
97 return (row << x1) & (row >> (4-x0));
101 * Return the board bitmap with set bits indicating tile locations
102 * that change with the hole at (x, y0) and the play at (x, y1).
104 static inline uint_fast32_t board_mask_v(int x, int y0, int y1)
106 uint_fast32_t col = board_column(x);
109 return (col << 5*y0) & (col >> 5*(4-y1));
110 return (col << 5*y1) & (col >> 5*(4-y0));
114 * Move the bits in the game bitmaps according to a move at position (x, y),
115 * and update the location of the empty position which, if the move was valid
118 * Returns 0 if the move was valid (and board has been updated), -1 otherwise.
120 int game_do_move(struct board *board, int x, int y);
123 * Returns 1 if the game is in a winning position, or 0 otherwise.
125 int game_check_goal(struct board *board);
128 * Initialize the game RNG such that the next call to game_reset will produce a
129 * new board that is entirely dependent on the given seed value.
131 void game_reseed(unsigned long long seed);
134 * Shuffle the game and goal tiles to produce a new game state.
136 void game_reset(struct board *board);
139 * Disable new moves and clear all tile bits other than the 9 goal tiles.
141 void game_finish(struct board *board);