diff options
Diffstat (limited to 'puzzle.h')
-rw-r--r-- | puzzle.h | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/puzzle.h b/puzzle.h new file mode 100644 index 0000000..4083350 --- /dev/null +++ b/puzzle.h @@ -0,0 +1,163 @@ +/* + * Sudoku: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id: puzzle.h 11 2005-10-28 01:00:01Z tom $ + */ + +#ifndef VDR_SUDOKU_PUZZLE_H +#define VDR_SUDOKU_PUZZLE_H + +#include "sudoku.h" + + +/** Sudoku puzzle + * + * A Sudoku puzzle consists of 9 x 9 cells subdivided into 9 regions with 3 x 3 + * cells. The rules are simple. There have to be the numbers from 1 to 9 in + * every row, column and region. + */ +namespace Sudoku +{ + + /** Regions, rows/columns and square dimension of the puzzle */ + enum + { + /** Regions dimension. Width and height of a region */ + RDIM = 3, + + /** Dimension. Number of cells in a row, column or region */ + DIM = RDIM * RDIM, + + /** Square dimension. Number of cells in the whole puzzle */ + SDIM = DIM * DIM + }; + + + //--- class Sudoku::Pos ------------------------------------------------------ + + /** Position in a Sudoku */ + class Pos + { + unsigned int pos; + public: + Pos(unsigned int col, unsigned int row) : pos(col + row * DIM) {} + Pos(unsigned int pos = 0) : pos(pos) {} + operator unsigned int() const { return pos; } + static Pos first() { return 0; } + static Pos last() { return SDIM-1; } + Pos next() const { return pos + 1; } + unsigned int col() const { return pos % DIM; } + unsigned int row() const { return pos / DIM; } + unsigned int reg() const { return (col() / RDIM) + RDIM * (row() / RDIM); } + static Pos center() { return SDIM / 2; } + Pos symmetric() const { return SDIM - 1 - pos; } + Pos prev_col() const { return col() > 0 ? pos - 1 : pos; } + Pos next_col() const { return col() < DIM-1 ? pos + 1 : pos; } + Pos prev_row() const { return row() > 0 ? pos - DIM : pos; } + Pos next_row() const { return row() < DIM-1 ? pos + DIM : pos; } + }; + + + //--- class Sudoku::Numbers -------------------------------------------------- + + /** Numbers of a Sudoku */ + class Numbers + { + unsigned int content[SDIM]; + + public: + + /** Constructor */ + Numbers(); + + /** Destructor */ + virtual ~Numbers(); + + /** Remove all numbers. */ + virtual void reset(); + + /** Set numbers from contents of sudoku if marked in marks. */ + virtual void set_contents(const Numbers& sudoku, const bool marks[SDIM]); + + /** Set the number into this cell. */ + virtual void set(Pos pos, unsigned int number); + + /** Get the number from this cell. */ + virtual unsigned int get(Pos pos) const; + }; + + + //--- class Sudoku::Puzzle --------------------------------------------------- + + /** Sudoku puzzle */ + class Puzzle : public Numbers + { + Numbers givens; + bool marks[SDIM]; + bool numbers[SDIM][DIM+1]; + unsigned int count[SDIM]; + + public: + + /** Constructor */ + Puzzle(unsigned int givens_count = 0, bool symmetric = true); + + /** Reset the puzzle. */ + virtual void reset(); + + /** Set the number into this cell. */ + virtual void set(Pos pos, unsigned int number); + + /** Generate a new puzzle. */ + void generate(unsigned int givens_count, bool symmetric = true); + + /** Set givens from contents of sudoku if marked in given_marks. */ + void set_givens(const Numbers& sudoku, const bool given_marks[SDIM]); + + /** Remove all givens. */ + void clear_givens(); + + /** No cells set? */ + bool untouched() const; + + /** Is the number in this cell given? */ + bool given(Pos pos) const; + + /** Is there an error on this position? */ + bool error(Pos pos) const; + + /** Is the number in this cell ambiguous? */ + bool ambiguous(Pos pos) const; + + /** All cells set and no errors? */ + bool solved() const; + + /** Is this cell marked? */ + bool marked(Pos pos) const; + + /** Toggle the mark for this cell. */ + void toggle_mark(Pos pos); + + /** Get the next free cell with minimal possible numbers. */ + Pos next_free(Pos pos = Pos::last()) const; + + /** Get the next possible number for this cell. */ + unsigned int next_number(Pos pos); + + /** Get the count of possible numbers for this cell. */ + unsigned int numbers_count(Pos pos); + +private: + + /** Compute all possible numbers for this cell. */ + void compute_numbers(Pos pos); + + /** Is the number in this cell a possible number? */ + bool correct(Pos pos) const; + }; + +} // namespace Sudoku + +#endif // VDR_SUDOKU_PUZZLE_H |