From b398e8422be581a80ac23767d97d661f666e0972 Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Mon, 12 Dec 2005 04:23:05 +0000 Subject: [PATCH] Fix "restart game" - we aren't saving the seed, and even so we don't get the same sequence on Linux anyways. Also, multiple clicks in a cell sets/increments the value. Finally, use alternate background color to produce checkerboard-like pattern. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@4695 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- test/sudoku.cxx | 196 +++++++++++++++++++++++++++++++----------------- 1 file changed, 126 insertions(+), 70 deletions(-) diff --git a/test/sudoku.cxx b/test/sudoku.cxx index 6502190b6..6cb271f56 100644 --- a/test/sudoku.cxx +++ b/test/sudoku.cxx @@ -137,6 +137,69 @@ class SudokuSound { }; +// Sudoku cell class... +class SudokuCell : public Fl_Widget { + bool readonly_; + int value_; + int test_value_[8]; + + public: + + SudokuCell(int X, int Y, int W, int H); + void draw(); + int handle(int event); + void readonly(bool r) { readonly_ = r; redraw(); } + bool readonly() const { return readonly_; } + void test_value(int v, int n) { test_value_[n] = v; redraw(); } + int test_value(int n) const { return test_value_[n]; } + void value(int v) { + value_ = v; + for (int i = 0; i < 8; i ++) test_value_[i] = 0; + redraw(); + } + int value() const { return value_; } +}; + + +// Sudoku window class... +class Sudoku : public Fl_Window { + Fl_Sys_Menu_Bar *menubar_; + Fl_Group *grid_; + time_t seed_; + char grid_values_[9][9]; + SudokuCell *grid_cells_[9][9]; + Fl_Group *grid_groups_[3][3]; + int difficulty_; + SudokuSound *sound_; + + static void check_cb(Fl_Widget *widget, void *); + static void close_cb(Fl_Widget *widget, void *); + static void diff_cb(Fl_Widget *widget, void *d); + static void help_cb(Fl_Widget *, void *); + static void new_cb(Fl_Widget *widget, void *); + static void reset_cb(Fl_Widget *widget, void *); + static void restart_cb(Fl_Widget *widget, void *); + void set_title(); + static void solve_cb(Fl_Widget *widget, void *); + + static Fl_Help_Dialog *help_dialog_; + static Fl_Preferences prefs_; + public: + + Sudoku(); + ~Sudoku(); + + void check_game(bool highlight = true); + void load_game(); + void new_game(time_t seed); + int next_value(SudokuCell *c); + void resize(int X, int Y, int W, int H); + void save_game(); + void solve_game(); +}; + + +// Sound class globals... int SudokuSound::frequencies[9] = { 880, // A(5) 988, // B(5) @@ -412,29 +475,6 @@ void SudokuSound::play(char note) { } -// Sudoku cell class... -class SudokuCell : public Fl_Widget { - bool readonly_; - int value_; - int test_value_[8]; - - public: - - SudokuCell(int X, int Y, int W, int H); - void draw(); - int handle(int event); - void readonly(bool r) { readonly_ = r; redraw(); } - bool readonly() const { return readonly_; } - void test_value(int v, int n) { test_value_[n] = v; redraw(); } - int test_value(int n) const { return test_value_[n]; } - void value(int v) { - value_ = v; - for (int i = 0; i < 8; i ++) test_value_[i] = 0; - redraw(); - } - int value() const { return value_; } -}; - // Create a cell widget SudokuCell::SudokuCell(int X, int Y, int W, int H) : Fl_Widget(X, Y, W, H, 0) { @@ -508,6 +548,14 @@ SudokuCell::handle(int event) { case FL_PUSH : if (Fl::event_inside(this)) { + if (Fl::event_clicks()) { + // 2+ clicks increments/sets value + if (value()) { + if (value() < 9) value(value() + 1); + else value(1); + } else value(((Sudoku *)window())->next_value(this)); + } + Fl::focus(this); redraw(); return 1; @@ -570,43 +618,6 @@ SudokuCell::handle(int event) { } -// Sudoku window class... -class Sudoku : public Fl_Window { - Fl_Sys_Menu_Bar *menubar_; - Fl_Group *grid_; - time_t seed_; - char grid_values_[9][9]; - SudokuCell *grid_cells_[9][9]; - Fl_Group *grid_groups_[3][3]; - int difficulty_; - SudokuSound *sound_; - - static void check_cb(Fl_Widget *widget, void *); - static void close_cb(Fl_Widget *widget, void *); - static void diff_cb(Fl_Widget *widget, void *d); - static void help_cb(Fl_Widget *, void *); - static void new_cb(Fl_Widget *widget, void *); - static void reset_cb(Fl_Widget *widget, void *); - static void restart_cb(Fl_Widget *widget, void *); - void set_title(); - static void solve_cb(Fl_Widget *widget, void *); - - static Fl_Help_Dialog *help_dialog_; - static Fl_Preferences prefs_; - public: - - Sudoku(); - ~Sudoku(); - - void check_game(bool highlight = true); - void load_game(); - void new_game(time_t seed); - void resize(int X, int Y, int W, int H); - void save_game(); - void solve_game(); -}; - - // Sudoku class globals... Fl_Help_Dialog *Sudoku::help_dialog_ = (Fl_Help_Dialog *)0; Fl_Preferences Sudoku::prefs_(Fl_Preferences::USER, "fltk.org", "sudoku"); @@ -660,7 +671,8 @@ Sudoku::Sudoku() g = new Fl_Group(j * GROUP_SIZE, i * GROUP_SIZE + MENU_OFFSET, GROUP_SIZE, GROUP_SIZE); g->box(FL_BORDER_BOX); - g->color(FL_DARK3); + if ((i == 1) ^ (j == 1)) g->color(FL_DARK3); + else g->color(FL_DARK2); g->end(); grid_groups_[i][j] = g; @@ -1013,6 +1025,41 @@ Sudoku::new_game(time_t seed) { } +// Return the next available value for a cell... +int +Sudoku::next_value(SudokuCell *c) { + int i, j, k, m; + + + for (i = 0; i < 9; i ++) { + for (j = 0; j < 9; j ++) + if (grid_cells_[i][j] == c) break; + + if (j < 9) break; + } + + if (i == 9) return 1; + + i -= i % 3; + j -= j % 3; + + int numbers[9]; + + memset(numbers, 0, sizeof(numbers)); + + for (k = 0; k < 3; k ++) + for (m = 0; m < 3; m ++) { + c = grid_cells_[i + k][j + m]; + if (c->value()) numbers[c->value() - 1] = 1; + } + + for (i = 0; i < 9; i ++) + if (!numbers[i]) return i + 1; + + return 1; +} + + // Reset widget color to gray... void Sudoku::reset_cb(Fl_Widget *widget, void *) { @@ -1037,6 +1084,24 @@ Sudoku::resize(int X, int Y, int W, int H) { } +// Restart game from beginning... +void +Sudoku::restart_cb(Fl_Widget *widget, void *) { + Sudoku *s = (Sudoku *)(widget->window()); + + for (int i = 0; i < 9; i ++) + for (int j = 0; j < 9; j ++) { + SudokuCell *cell = s->grid_cells_[i][j]; + + if (!cell->readonly()) { + int v = cell->value(); + cell->value(0); + if (v) s->sound_->play('A' + v - 1); + } + } +} + + // Save the current game state... void Sudoku::save_game() { @@ -1063,15 +1128,6 @@ Sudoku::save_game() { } -// Restart game from beginning... -void -Sudoku::restart_cb(Fl_Widget *widget, void *) { - Sudoku *s = (Sudoku *)(widget->window()); - - s->new_game(s->seed_); -} - - // Set title of window... void Sudoku::set_title() {