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
This commit is contained in:
Michael R Sweet 2005-12-12 04:23:05 +00:00
parent 5f83ff12e6
commit b398e8422b
1 changed files with 126 additions and 70 deletions

View File

@ -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() {