#include "puzzle_options.h" // this macro just does the validation that is always the same #define TILE_TO_IX(bail) \ if (tile.value < '1' || tile.value > '9') { bail; } \ uint8_t ix = tile.value - '1' // all of these are set operations for a bitfield with 9 bits! // (done in the most obvious way possible) void puzzle_options_init(puzzle_options_t* puzzle_options) { puzzle_options->bitfield = 0x1FF; // 9 set bits } void puzzle_options_add(puzzle_options_t* puzzle_options, tile_t tile) { TILE_TO_IX(return); puzzle_options->bitfield |= 1 << ix; } bool puzzle_options_remove(puzzle_options_t* puzzle_options, tile_t tile) { TILE_TO_IX(return false); uint16_t old = puzzle_options->bitfield; puzzle_options->bitfield &= ~(1 << ix); uint16_t new = puzzle_options->bitfield; return old != new; } bool puzzle_options_contains(puzzle_options_t* puzzle_options, tile_t tile) { TILE_TO_IX(return false); return (puzzle_options->bitfield & (1 << ix)) != 0; } uint8_t puzzle_options_count(puzzle_options_t* puzzle_options) { uint8_t count = 0; for (uint8_t ix = 0; ix < 9; ix++) { if ((puzzle_options->bitfield & (1 << ix)) != 0) { count++; } } return count; } bool puzzle_options_is_empty(puzzle_options_t* puzzle_options) { return puzzle_options->bitfield == 0; }