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:
parent
5f83ff12e6
commit
b398e8422b
196
test/sudoku.cxx
196
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() {
|
||||
|
Loading…
Reference in New Issue
Block a user