Ajout de sudoSolver.cpp - Simplification de la gestion des menus
This commit is contained in:
parent
72170f0e96
commit
b0d79c4184
1
TODO.md
1
TODO.md
|
@ -13,6 +13,7 @@
|
|||
- [ ] pour FX9680G ... ?
|
||||
- [ ] getItem / setItem
|
||||
- [x] _homeScreen()
|
||||
- [ ] "Fermeture" après x sec.
|
||||
- [x] icones
|
||||
- [x] grids
|
||||
- [x] Copie d'écran - *fxlink*
|
||||
|
|
|
@ -51,12 +51,12 @@ extern "C" {
|
|||
// "Solve" sub-menu bar
|
||||
//
|
||||
#define IDS_SOLVE_OBVIOUS "Obvious"
|
||||
#define IDS_SOLVE_FIND "Resolve"
|
||||
#define IDS_SOLVE_RESOLVE "Resolve"
|
||||
#define IDS_SOLVE_REVERT "Revert"
|
||||
|
||||
#define IDM_SOLVE_SUBMENU 300
|
||||
#define IDM_SOLVE_OBVIOUS 301
|
||||
#define IDM_SOLVE_FIND 302
|
||||
#define IDM_SOLVE_RESOLVE 302
|
||||
#define IDM_SOLVE_REVERT 303
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1,373 +1,373 @@
|
|||
//----------------------------------------------------------------------
|
||||
//--
|
||||
//-- sudoSolver.cpp
|
||||
//--
|
||||
//-- Implementation of sudoSolver object
|
||||
//--
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#include "sudoSolver.h"
|
||||
#include "sudoku.h"
|
||||
|
||||
extern bopti_image_t g_homeScreen; // Background image
|
||||
|
||||
// Construction
|
||||
//
|
||||
sudoSolver::sudoSolver(){
|
||||
// Initialize members
|
||||
_initStats();
|
||||
}
|
||||
|
||||
// Destruction
|
||||
//
|
||||
sudoSolver::~sudoSolver(){
|
||||
#ifndef NO_CAPTURE
|
||||
if (_capture.isSet()){
|
||||
_capture.remove(); // stop "capture" on exit
|
||||
}
|
||||
#endif // #ifndef NO_CAPTURE
|
||||
}
|
||||
|
||||
// Create app. menu bar
|
||||
//
|
||||
void sudoSolver::createMenu(){
|
||||
// "File" sub menu
|
||||
menuBar fileMenu;
|
||||
fileMenu.appendItem(IDM_FILE_NEW, IDS_FILE_NEW);
|
||||
fileMenu.appendItem(IDM_FILE_PREV, IDS_FILE_PREV, ITEM_STATE_INACTIVE);
|
||||
fileMenu.appendItem(IDM_FILE_NEXT, IDS_FILE_NEXT, ITEM_STATE_INACTIVE);
|
||||
fileMenu.appendItem(IDM_FILE_SAVE, IDS_FILE_SAVE, ITEM_STATE_INACTIVE);
|
||||
fileMenu.appendItem(IDM_FILE_DELETE, IDS_FILE_DELETE, ITEM_STATE_INACTIVE);
|
||||
menu_.appendSubMenu(&fileMenu, IDM_FILE_SUBMENU, IDS_FILE_SUBMENU);
|
||||
|
||||
menu_.appendItem(IDM_EDIT, IDS_EDIT);
|
||||
|
||||
// "Solve" sub menu
|
||||
menuBar sMenu;
|
||||
sMenu.appendItem(IDM_SOLVE_OBVIOUS, IDS_SOLVE_OBVIOUS);
|
||||
sMenu.appendItem(IDM_SOLVE_FIND, IDS_SOLVE_FIND);
|
||||
sMenu.addItem(MENU_POS_RIGHT - 1, IDM_SOLVE_REVERT, IDS_SOLVE_REVERT);
|
||||
menu_.appendSubMenu(&sMenu, IDM_SOLVE_SUBMENU, IDS_SOLVE_SUBMENU);
|
||||
|
||||
menu_.addItem(MENU_POS_RIGHT, IDM_QUIT, IDS_QUIT);
|
||||
|
||||
menu_.update();
|
||||
}
|
||||
|
||||
// showHomeScreen() : Display home screen
|
||||
//
|
||||
void sudoSolver::showHomeScreen(){
|
||||
drect(0, 0, CASIO_WIDTH, CASIO_HEIGHT - menu_.getHeight(), C_WHITE);
|
||||
dimage(0, 0, &g_homeScreen);
|
||||
|
||||
char copyright[255];
|
||||
strcpy(copyright, APP_NAME);
|
||||
strcat(copyright, " par ");
|
||||
strcat(copyright, APP_AUTHOR);
|
||||
strcat(copyright, " v");
|
||||
strcat(copyright, APP_VERSION);
|
||||
|
||||
int w, h;
|
||||
dsize(copyright, NULL, &w, &h);
|
||||
dtext(CASIO_WIDTH - w - 5,
|
||||
CASIO_HEIGHT - menu_.getHeight() - h - 10, C_BLACK,
|
||||
copyright);
|
||||
|
||||
dupdate();
|
||||
}
|
||||
|
||||
// browseGridFolder() : Browse the folder containing grid files
|
||||
//
|
||||
void sudoSolver::browseGridFolder(){
|
||||
// List of grid files
|
||||
if (files_.browse() > 0){
|
||||
_updateFileItemsState();
|
||||
}
|
||||
}
|
||||
|
||||
// run() : Edit / solve sudoku(s)
|
||||
//
|
||||
void sudoSolver::run(void)
|
||||
{
|
||||
// Start sudoku solver object
|
||||
RECT mainRect;
|
||||
menu_.getRect(mainRect);
|
||||
mainRect = {0, 0, mainRect.w, CASIO_HEIGHT - mainRect.h};
|
||||
|
||||
sudoku game(&mainRect);
|
||||
|
||||
// Handle user's choices
|
||||
bool end(false);
|
||||
int error(FILE_NO_ERROR);
|
||||
MENUACTION action;
|
||||
while (!end){
|
||||
// A menu action ?
|
||||
action = menu_.handleKeyboard();
|
||||
|
||||
// push a menu key ?
|
||||
if (ACTION_MENU == action.type){
|
||||
switch (action.value){
|
||||
// (re)start with a new empty grid
|
||||
case IDM_FILE_NEW:
|
||||
game.empty();
|
||||
game.display();
|
||||
_initStats();
|
||||
break;
|
||||
|
||||
// Load previous file
|
||||
case IDM_FILE_PREV:
|
||||
if (files.prevFile(fileName)){
|
||||
_updateFileItemsState();
|
||||
|
||||
// Update grid on screen
|
||||
if (FILE_NO_ERROR == (error = game.load(fileName))){
|
||||
game.display(false);
|
||||
_getShortFileName();
|
||||
_displayStats(sFileName, -1, -1);
|
||||
}
|
||||
else{
|
||||
dprint(TEXT_X, TEXT_V_OFFSET, C_RED, "Error loading file : %d", (int)error);
|
||||
dupdate();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Load next file
|
||||
case IDM_FILE_NEXT:
|
||||
if (files.nextFile(fileName)){
|
||||
_updateFileItemsState();
|
||||
|
||||
// Update grid on screen
|
||||
if (FILE_NO_ERROR == (error = game.load(fileName))){
|
||||
game.display(false);
|
||||
_getShortFileName();
|
||||
_displayStats(sFileName, -1, -1);
|
||||
}
|
||||
else{
|
||||
dprint(TEXT_X, TEXT_V_OFFSET, C_RED, "Error loading file : %d", (int)error);
|
||||
dupdate();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Save the grid
|
||||
case IDM_FILE_SAVE:
|
||||
{
|
||||
bool fileExists(sFileName[0]);
|
||||
int uid;
|
||||
|
||||
// Use current name or new name if none
|
||||
if (fileExists || (!fileExists && files.getNewFileName(fileName, &uid))){
|
||||
if (FILE_NO_ERROR == (error = game.save(fileName))){
|
||||
if (!fileExists){
|
||||
_setFileName(fileName, sFileName);
|
||||
_displayStats(sFileName, -1, -1);
|
||||
|
||||
// Update internal list
|
||||
files.browse();
|
||||
files.setPos(files.findPos(uid)); // select the file
|
||||
|
||||
menu.activate(IDM_FILE_NEXT, SEARCH_BY_ID, false);
|
||||
menu.activate(IDM_FILE_PREV, SEARCH_BY_ID, files.size()>1);
|
||||
|
||||
}
|
||||
|
||||
menu.activate(IDM_FILE_SAVE, SEARCH_BY_ID, false);
|
||||
menu.activate(IDM_FILE_DELETE, SEARCH_BY_ID, true);
|
||||
menu.update();
|
||||
} // save
|
||||
else{
|
||||
dprint(TEXT_X, TEXT_V_OFFSET, C_RED, "Error saving : %d", error);
|
||||
dupdate();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Remove current file
|
||||
case IDM_FILE_DELETE:
|
||||
if (files.deleteFile()){
|
||||
bool file(true);
|
||||
if (!files.prevFile(fileName)){
|
||||
menu.activate(IDM_FILE_PREV, SEARCH_BY_ID, false);
|
||||
if (!files.nextFile(fileName)){
|
||||
menu.activate(IDM_FILE_NEXT, SEARCH_BY_ID, false);
|
||||
menu.activate(IDM_FILE_DELETE, SEARCH_BY_ID, false);
|
||||
game.empty();
|
||||
file = false; // No filename
|
||||
}
|
||||
menu.update();
|
||||
}
|
||||
|
||||
_setFileName(file?fileName:NULL, sFileName);
|
||||
_displayStats(sFileName, -1, -1);
|
||||
}
|
||||
break;
|
||||
|
||||
// Modify current grid
|
||||
case IDM_EDIT:{
|
||||
game.display();
|
||||
if (game.edit()){
|
||||
menu.activate(IDM_FILE_SAVE, SEARCH_BY_ID, true);
|
||||
_displayStats(sFileName, -1, -1);
|
||||
}
|
||||
|
||||
menu.selectByIndex(-1);
|
||||
menu.update(); // redraw the whole menu bar
|
||||
break;
|
||||
}
|
||||
|
||||
// Search for obvious values
|
||||
case IDM_SOLVE_OBVIOUS:{
|
||||
obviousVals = game.findObviousValues();
|
||||
game.display(false);
|
||||
|
||||
_displayStats(sFileName, obviousVals, -1);
|
||||
break;
|
||||
}
|
||||
|
||||
// Try to find a solution
|
||||
case IDM_SOLVE_FIND:
|
||||
game.display();
|
||||
if (!game.resolve(&duration)){
|
||||
// No soluce found ...
|
||||
// ... return to original grid
|
||||
game.revert();
|
||||
}
|
||||
|
||||
game.display(false);
|
||||
_displayStats(sFileName, obviousVals, duration);
|
||||
|
||||
break;
|
||||
|
||||
// Return to "original" grid
|
||||
case IDM_SOLVE_REVERT:
|
||||
game.revert();
|
||||
game.display(false);
|
||||
obviousVals = -1;
|
||||
_displayStats(sFileName, -1, -1);
|
||||
break;
|
||||
|
||||
// Quit the application
|
||||
case IDM_QUIT:
|
||||
end = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break; // ???
|
||||
} // switch
|
||||
}else{
|
||||
// From keyboard (and not handled by the menu)
|
||||
if (ACTION_KEYBOARD == action.type){
|
||||
switch (action.value){
|
||||
// Return to main menu
|
||||
case KEY_MENU:
|
||||
end = true;
|
||||
break;
|
||||
|
||||
// Activate or deactivate screen capture
|
||||
#ifndef NO_CAPTURE
|
||||
case KEY_CODE_CAPTURE:
|
||||
if (action.modifier == MOD_SHIFT){
|
||||
if (!_capture.isSet()){
|
||||
_capture.install();
|
||||
}
|
||||
else{
|
||||
_capture.remove();
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif // #ifndef NO_CAPTURE
|
||||
|
||||
default:
|
||||
break;
|
||||
} // switch (action.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Internal methods
|
||||
//
|
||||
|
||||
// _initStats() : initialize grid stats
|
||||
//
|
||||
void sudoSolver::_initStats(){
|
||||
fileName_[0] = 0x0000;
|
||||
sFileName_[0] = '\0';
|
||||
obviousVals_ = -1;
|
||||
duration_ = -1;
|
||||
}
|
||||
|
||||
// _updateFileItemsState() : Item's state
|
||||
//
|
||||
// @modified : Has the grid been edited (changed) ?
|
||||
//
|
||||
void sudoSolver::_updateFileItemsState(bool modified){
|
||||
int count(files_.size());
|
||||
int pos(files_.pos());
|
||||
bool bPrev, bNext, bSave, bDelete;
|
||||
if (!count){
|
||||
bPrev = bNext = bSave = bDelete = false;
|
||||
}
|
||||
else{
|
||||
bPrev = (pos>0); // Not the first in list ?
|
||||
bNext = (pos < (count - 1)); // Not the last in list
|
||||
bSave = modified;
|
||||
bDelete = (sFileName_[0]);
|
||||
}
|
||||
|
||||
menu_.activate(IDM_FILE_PREV, SEARCH_BY_ID, bPrev);
|
||||
menu_.activate(IDM_FILE_NEXT, SEARCH_BY_ID, bNext);
|
||||
menu_.activate(IDM_FILE_SAVE, SEARCH_BY_ID, bSave);
|
||||
menu_.activate(IDM_FILE_DELETE, SEARCH_BY_ID, bDelete);
|
||||
|
||||
menu_.update();
|
||||
}
|
||||
|
||||
// _getShortFileName() : Get short filename from FQN
|
||||
//
|
||||
void sudoSolver::_getShortFileName(){
|
||||
if (bFile::FC_len(fileName_)){
|
||||
char fName[BFILE_MAX_PATH + 1];
|
||||
bFile::FC_FC2str(fileName_, fName);
|
||||
char* name = strrchr(fName, CHAR_PATH_SEPARATOR);
|
||||
strcpy(sFileName_, (name?++name:fName)); // No path ?
|
||||
}
|
||||
else{
|
||||
sFileName_[0] = '\0'; // No filename
|
||||
}
|
||||
}
|
||||
|
||||
// _displayStats() : Display grid's stats
|
||||
//
|
||||
void sudoSolver::_displayStats(const char* fName, int8_t obvious, int elapse){
|
||||
if (fName && fName[0]){
|
||||
dprint(TEXT_X, TEXT_Y, C_BLACK, "File : %s", fName);
|
||||
}
|
||||
|
||||
if (obvious != -1){
|
||||
if (obvious){
|
||||
dprint(TEXT_X, TEXT_Y + TEXT_V_OFFSET, C_BLACK, "%d obvious values", obvious);
|
||||
|
||||
}
|
||||
else{
|
||||
dtext(TEXT_X, TEXT_Y + TEXT_V_OFFSET, C_BLACK, "No obvious value");
|
||||
}
|
||||
}
|
||||
|
||||
if (elapse != -1){
|
||||
if (elapse){
|
||||
dprint(TEXT_X, TEXT_Y + 2*TEXT_V_OFFSET, C_BLACK, "Solved in %d ms", elapse);
|
||||
|
||||
}
|
||||
else{
|
||||
dprint(TEXT_X, TEXT_Y + 2*TEXT_V_OFFSET, C_BLACK, "No solution found");
|
||||
}
|
||||
}
|
||||
|
||||
dupdate();
|
||||
}
|
||||
|
||||
// EOF
|
||||
//----------------------------------------------------------------------
|
||||
//--
|
||||
//-- sudoSolver.cpp
|
||||
//--
|
||||
//-- Implementation of sudoSolver object
|
||||
//--
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#include "sudoSolver.h"
|
||||
#include "sudoku.h"
|
||||
|
||||
extern bopti_image_t g_homeScreen; // Background image
|
||||
|
||||
// Construction
|
||||
//
|
||||
sudoSolver::sudoSolver(){
|
||||
// Initialize members
|
||||
_initStats();
|
||||
}
|
||||
|
||||
// Destruction
|
||||
//
|
||||
sudoSolver::~sudoSolver(){
|
||||
#ifndef NO_CAPTURE
|
||||
if (_capture.isSet()){
|
||||
_capture.remove(); // stop "capture" on exit
|
||||
}
|
||||
#endif // #ifndef NO_CAPTURE
|
||||
}
|
||||
|
||||
// Create app. menu bar
|
||||
//
|
||||
void sudoSolver::createMenu(){
|
||||
// "File" sub menu
|
||||
menuBar fileMenu;
|
||||
fileMenu.appendItem(IDM_FILE_NEW, IDS_FILE_NEW);
|
||||
fileMenu.appendItem(IDM_FILE_PREV, IDS_FILE_PREV, ITEM_STATE_INACTIVE);
|
||||
fileMenu.appendItem(IDM_FILE_NEXT, IDS_FILE_NEXT, ITEM_STATE_INACTIVE);
|
||||
fileMenu.appendItem(IDM_FILE_SAVE, IDS_FILE_SAVE, ITEM_STATE_INACTIVE);
|
||||
fileMenu.appendItem(IDM_FILE_DELETE, IDS_FILE_DELETE, ITEM_STATE_INACTIVE);
|
||||
menu_.appendSubMenu(&fileMenu, IDM_FILE_SUBMENU, IDS_FILE_SUBMENU);
|
||||
|
||||
menu_.appendItem(IDM_EDIT, IDS_EDIT);
|
||||
|
||||
// "Solve" sub menu
|
||||
menuBar sMenu;
|
||||
sMenu.appendItem(IDM_SOLVE_OBVIOUS, IDS_SOLVE_OBVIOUS);
|
||||
sMenu.appendItem(IDM_SOLVE_RESOLVE, IDS_SOLVE_RESOLVE);
|
||||
sMenu.addItem(MENU_POS_RIGHT - 1, IDM_SOLVE_REVERT, IDS_SOLVE_REVERT);
|
||||
menu_.appendSubMenu(&sMenu, IDM_SOLVE_SUBMENU, IDS_SOLVE_SUBMENU);
|
||||
|
||||
menu_.addItem(MENU_POS_RIGHT, IDM_QUIT, IDS_QUIT);
|
||||
|
||||
menu_.update();
|
||||
}
|
||||
|
||||
// showHomeScreen() : Display home screen
|
||||
//
|
||||
void sudoSolver::showHomeScreen(){
|
||||
drect(0, 0, CASIO_WIDTH, CASIO_HEIGHT - menu_.getHeight(), C_WHITE);
|
||||
dimage(0, 0, &g_homeScreen);
|
||||
|
||||
char copyright[255];
|
||||
strcpy(copyright, APP_NAME);
|
||||
strcat(copyright, " par ");
|
||||
strcat(copyright, APP_AUTHOR);
|
||||
strcat(copyright, " v");
|
||||
strcat(copyright, APP_VERSION);
|
||||
|
||||
int w, h;
|
||||
dsize(copyright, NULL, &w, &h);
|
||||
dtext(CASIO_WIDTH - w - 5,
|
||||
CASIO_HEIGHT - menu_.getHeight() - h - 10, C_BLACK,
|
||||
copyright);
|
||||
|
||||
dupdate();
|
||||
}
|
||||
|
||||
// browseGridFolder() : Browse the folder containing grid files
|
||||
//
|
||||
void sudoSolver::browseGridFolder(){
|
||||
// List of grid files
|
||||
if (files_.browse() > 0){
|
||||
_updateFileItemsState();
|
||||
}
|
||||
}
|
||||
|
||||
// run() : Edit / solve sudoku(s)
|
||||
//
|
||||
void sudoSolver::run(void)
|
||||
{
|
||||
// Start sudoku solver object
|
||||
RECT mainRect;
|
||||
menu_.getRect(mainRect);
|
||||
mainRect = {0, 0, mainRect.w, CASIO_HEIGHT - mainRect.h};
|
||||
|
||||
sudoku game(&mainRect);
|
||||
|
||||
// Handle user's choices
|
||||
bool end(false);
|
||||
int error(FILE_NO_ERROR);
|
||||
MENUACTION action;
|
||||
while (!end){
|
||||
// A menu action ?
|
||||
action = menu_.handleKeyboard();
|
||||
|
||||
// push a menu key ?
|
||||
if (ACTION_MENU == action.type){
|
||||
switch (action.value){
|
||||
// (re)start with a new empty grid
|
||||
case IDM_FILE_NEW:
|
||||
game.empty();
|
||||
game.display();
|
||||
_initStats();
|
||||
break;
|
||||
|
||||
// Load previous file
|
||||
case IDM_FILE_PREV:
|
||||
if (files_.prevFile(fileName_)){
|
||||
_updateFileItemsState();
|
||||
|
||||
// Update grid on screen
|
||||
if (FILE_NO_ERROR == (error = game.load(fileName_))){
|
||||
game.display(false);
|
||||
_newFileName();
|
||||
}
|
||||
else{
|
||||
dprint(TEXT_X, TEXT_V_OFFSET, C_RED, "Error loading file : %d", (int)error);
|
||||
dupdate();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Load next file
|
||||
case IDM_FILE_NEXT:
|
||||
if (files_.nextFile(fileName_)){
|
||||
_updateFileItemsState();
|
||||
|
||||
// Update grid on screen
|
||||
if (FILE_NO_ERROR == (error = game.load(fileName_))){
|
||||
game.display(false);
|
||||
_newFileName();
|
||||
}
|
||||
else{
|
||||
dprint(TEXT_X, TEXT_V_OFFSET, C_RED, "Error loading file : %d", (int)error);
|
||||
dupdate();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Save the grid
|
||||
case IDM_FILE_SAVE:
|
||||
{
|
||||
bool fileExists(sFileName_[0]);
|
||||
int uid;
|
||||
|
||||
// Use current name or new name if none
|
||||
if (fileExists || (!fileExists && files_.getNewFileName(fileName_, &uid))){
|
||||
if (FILE_NO_ERROR == (error = game.save(fileName_))){
|
||||
if (!fileExists){
|
||||
// It's a new file
|
||||
_newFileName();
|
||||
|
||||
// Update internal list
|
||||
files_.browse();
|
||||
files_.setPos(files_.findPos(uid)); // select the file
|
||||
}
|
||||
|
||||
_updateFileItemsState();
|
||||
} // save
|
||||
else{
|
||||
dprint(TEXT_X, TEXT_V_OFFSET, C_RED, "Error saving : %d", error);
|
||||
dupdate();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Remove current file
|
||||
case IDM_FILE_DELETE:
|
||||
if (files_.deleteFile()){
|
||||
bool file(true);
|
||||
if (!files_.prevFile(fileName_)){
|
||||
menu_.activate(IDM_FILE_PREV, SEARCH_BY_ID, false);
|
||||
if (!files_.nextFile(fileName_)){
|
||||
_updateFileItemsState();
|
||||
game.empty();
|
||||
file = false; // No filename
|
||||
}
|
||||
}
|
||||
|
||||
if (!file){
|
||||
fileName_[0] = 0x0000;
|
||||
}
|
||||
|
||||
_newFileName();
|
||||
}
|
||||
break;
|
||||
|
||||
// Modify current grid
|
||||
case IDM_EDIT:{
|
||||
game.display();
|
||||
if (game.edit()){
|
||||
_displayStats();
|
||||
}
|
||||
else{
|
||||
game.revert();
|
||||
}
|
||||
|
||||
menu_.selectByIndex(-1);
|
||||
_updateFileItemsState();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Search for obvious values
|
||||
case IDM_SOLVE_OBVIOUS:{
|
||||
obviousVals_ = game.findObviousValues();
|
||||
duration_ = -1;
|
||||
game.display(false);
|
||||
_displayStats();
|
||||
break;
|
||||
}
|
||||
|
||||
// Try to find a solution
|
||||
case IDM_SOLVE_RESOLVE:
|
||||
game.display();
|
||||
if (!game.resolve(&duration_)){
|
||||
// No soluce found ...
|
||||
// ... return to original grid
|
||||
game.revert();
|
||||
}
|
||||
|
||||
game.display(false);
|
||||
_displayStats();
|
||||
|
||||
break;
|
||||
|
||||
// Return to "original" grid
|
||||
case IDM_SOLVE_REVERT:
|
||||
game.revert();
|
||||
game.display(false);
|
||||
obviousVals_ = -1;
|
||||
duration_ = -1;
|
||||
_displayStats();
|
||||
break;
|
||||
|
||||
// Quit the application
|
||||
case IDM_QUIT:
|
||||
end = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break; // ???
|
||||
} // switch
|
||||
}else{
|
||||
// From keyboard (and not handled by the menu)
|
||||
if (ACTION_KEYBOARD == action.type){
|
||||
switch (action.value){
|
||||
// Return to main menu
|
||||
case KEY_MENU:
|
||||
end = true;
|
||||
break;
|
||||
|
||||
// Activate or deactivate screen capture
|
||||
#ifndef NO_CAPTURE
|
||||
case KEY_CODE_CAPTURE:
|
||||
if (action.modifier == MOD_SHIFT){
|
||||
if (!_capture.isSet()){
|
||||
_capture.install();
|
||||
}
|
||||
else{
|
||||
_capture.remove();
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif // #ifndef NO_CAPTURE
|
||||
|
||||
default:
|
||||
break;
|
||||
} // switch (action.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Internal methods
|
||||
//
|
||||
|
||||
// _initStats() : initialize grid stats
|
||||
//
|
||||
void sudoSolver::_initStats(bool whole){
|
||||
if (whole){
|
||||
fileName_[0] = 0x0000;
|
||||
}
|
||||
|
||||
sFileName_[0] = '\0';
|
||||
obviousVals_ = -1;
|
||||
duration_ = -1;
|
||||
}
|
||||
|
||||
// _updateFileItemsState() : Item's state
|
||||
//
|
||||
// @modified : Has the grid been edited (changed) ?
|
||||
//
|
||||
void sudoSolver::_updateFileItemsState(bool modified){
|
||||
int count(files_.size());
|
||||
int pos(files_.pos());
|
||||
bool bPrev, bNext, bSave, bDelete;
|
||||
if (!count){
|
||||
bPrev = bNext = bSave = bDelete = false;
|
||||
}
|
||||
else{
|
||||
bPrev = (pos>0); // Not the first in list ?
|
||||
bNext = (pos < (count - 1)); // Not the last in list
|
||||
bSave = modified;
|
||||
bDelete = (sFileName_[0]);
|
||||
}
|
||||
|
||||
menu_.activate(IDM_FILE_PREV, SEARCH_BY_ID, bPrev);
|
||||
menu_.activate(IDM_FILE_NEXT, SEARCH_BY_ID, bNext);
|
||||
menu_.activate(IDM_FILE_SAVE, SEARCH_BY_ID, bSave);
|
||||
menu_.activate(IDM_FILE_DELETE, SEARCH_BY_ID, bDelete);
|
||||
|
||||
menu_.update();
|
||||
}
|
||||
|
||||
// _newFileName() : Notifies FQN has changed
|
||||
//
|
||||
void sudoSolver::_newFileName(){
|
||||
_initStats(false);
|
||||
if (bFile::FC_len(fileName_)){
|
||||
char fName[BFILE_MAX_PATH + 1];
|
||||
bFile::FC_FC2str(fileName_, fName);
|
||||
char* name = strrchr(fName, CHAR_PATH_SEPARATOR);
|
||||
strcpy(sFileName_, (name?++name:fName)); // No path ?
|
||||
}
|
||||
|
||||
_displayStats();
|
||||
}
|
||||
|
||||
// _displayStats() : Display grid's stats
|
||||
//
|
||||
void sudoSolver::_displayStats(){
|
||||
if (sFileName_[0]){
|
||||
dprint(TEXT_X, TEXT_Y, C_BLACK, "File : %s", sFileName_);
|
||||
}
|
||||
|
||||
if (obviousVals_ != -1){
|
||||
if (obviousVals_){
|
||||
dprint(TEXT_X, TEXT_Y + TEXT_V_OFFSET, C_BLACK, "%d obvious values", obviousVals_);
|
||||
|
||||
}
|
||||
else{
|
||||
dtext(TEXT_X, TEXT_Y + TEXT_V_OFFSET, C_BLACK, "No obvious value");
|
||||
}
|
||||
}
|
||||
|
||||
if (duration_ != -1){
|
||||
if (duration_){
|
||||
dprint(TEXT_X, TEXT_Y + 2*TEXT_V_OFFSET, C_BLACK, "Solved in %d ms", duration_);
|
||||
|
||||
}
|
||||
else{
|
||||
dprint(TEXT_X, TEXT_Y + 2*TEXT_V_OFFSET, C_BLACK, "No solution found");
|
||||
}
|
||||
}
|
||||
|
||||
dupdate();
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -44,7 +44,7 @@ private:
|
|||
|
||||
// _initStats() : initialize grid stats
|
||||
//
|
||||
void _initStats();
|
||||
void _initStats(bool whole = true);
|
||||
|
||||
// _updateFileItemsState() : Item's state
|
||||
//
|
||||
|
@ -53,11 +53,10 @@ private:
|
|||
void _updateFileItemsState(bool modified = false);
|
||||
|
||||
|
||||
// _updateShortFileName() : Get short filename from FQN
|
||||
// _newFileName() : Notifies FQN has changed
|
||||
//
|
||||
void _updateShortFileName();
|
||||
|
||||
void _displayStats(const char* fName, int8_t obvious, int elapse);
|
||||
void _newFileName();
|
||||
void _displayStats();
|
||||
|
||||
private:
|
||||
menuBar menu_; // Application menu
|
||||
|
|
538
src/sudoku.h
538
src/sudoku.h
|
@ -1,269 +1,269 @@
|
|||
//----------------------------------------------------------------------
|
||||
//--
|
||||
//-- sudoku.h
|
||||
//--
|
||||
//-- Definition of sudoku object - Edition and resolution
|
||||
//-- of a sudoku grid
|
||||
//--
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#ifndef __S_SOLVER_SUDOKU_h__
|
||||
#define __S_SOLVER_SUDOKU_h__ 1
|
||||
|
||||
#include "consts.h"
|
||||
|
||||
#include "element.h"
|
||||
#include "position.h"
|
||||
#include "tinySquare.h"
|
||||
|
||||
#include "shared/bFile.h"
|
||||
|
||||
// Error codes
|
||||
//
|
||||
#define FILE_NO_ERROR BFILE_NO_ERROR
|
||||
#define FILE_INVALID_FILENAME (BFILE_LAST_ERROR_CODE + 1) // File doesn't exist
|
||||
#define FILE_INVALID_FILESIZE (BFILE_LAST_ERROR_CODE + 2)
|
||||
#define FILE_NO_FILENAME (BFILE_LAST_ERROR_CODE + 3)
|
||||
#define FILE_IO_ERROR (BFILE_LAST_ERROR_CODE + 4)
|
||||
#define FILE_INVALID_LINE (BFILE_LAST_ERROR_CODE + 11)
|
||||
#define FILE_INVALID_FORMAT (BFILE_LAST_ERROR_CODE + 12)
|
||||
// The value can't be set at this position
|
||||
#define FILE_VALUE_ERROR (BFILE_LAST_ERROR_CODE + 13)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
// sudoku : Edition and/or resolution of a single sudoku grid
|
||||
//
|
||||
class sudoku{
|
||||
public:
|
||||
|
||||
// Construction & destruction
|
||||
sudoku(RECT* scr = NULL);
|
||||
~sudoku(){}
|
||||
|
||||
// display() : Display the grid and it's content
|
||||
//
|
||||
// @update : update screen ?
|
||||
//
|
||||
void display(bool update = true);
|
||||
|
||||
// empty() : Empties the grid
|
||||
//
|
||||
void empty();
|
||||
|
||||
// revert : Return to the original state
|
||||
//
|
||||
void revert();
|
||||
|
||||
// io
|
||||
//
|
||||
|
||||
// load() : Load a new grid
|
||||
//
|
||||
// @fName : file to load
|
||||
//
|
||||
// @return : 0 on success or an error code
|
||||
//
|
||||
uint8_t load(const FONTCHARACTER fName);
|
||||
|
||||
// save() : Save the grid on a file
|
||||
//
|
||||
// In the given grid, only "original" values
|
||||
// will be saved
|
||||
//
|
||||
// @fName : File name to use
|
||||
//
|
||||
// @return : 0 on success or an error code
|
||||
//
|
||||
int save(const FONTCHARACTER fName);
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
// edit() : Edit / modify the current grid
|
||||
//
|
||||
// @return : true if grid has been modified or false if unchanged
|
||||
//
|
||||
bool edit();
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
// findObviousValues() : Find all the obvious values
|
||||
//
|
||||
// @return : #obvious values found
|
||||
//
|
||||
uint8_t findObviousValues();
|
||||
|
||||
// resolve() : Find a solution for the current grid
|
||||
//
|
||||
// mDuration : points to an int that will receive duration
|
||||
// of solving process in ms. Can be NULL
|
||||
//
|
||||
// @return : true if a solution was found
|
||||
//
|
||||
bool resolve(int* mDuration = NULL);
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
// Checks
|
||||
//
|
||||
|
||||
// _checkValue() : Can we put the value at the current position ?
|
||||
//
|
||||
// @pos : position
|
||||
// @value : Check the given value at this 'position'
|
||||
//
|
||||
// @return : true if the given value is valid at the given position
|
||||
//
|
||||
bool _checkValue(position& pos, uint8_t value);
|
||||
|
||||
// _checkLine() : Can we put the value at the current position ?
|
||||
//
|
||||
// @pos : position
|
||||
// @value : Check this value at this position's line
|
||||
//
|
||||
// @return : true if the given value is valid in the given line
|
||||
//
|
||||
bool _checkLine(position& pos, uint8_t value);
|
||||
|
||||
// _checkRow() : Can we put the value at the current row ?
|
||||
//
|
||||
// @pos : position
|
||||
// @value : Check this value at this position's row
|
||||
//
|
||||
// @return : true if the given value is valid in the given row
|
||||
//
|
||||
bool _checkRow(position& pos, uint8_t value);
|
||||
|
||||
// _checTinySquare() : Can we put the value in this tinySquare ?
|
||||
//
|
||||
// @pos : position
|
||||
// @value : Check this value
|
||||
//
|
||||
// @return : true if the given value is valid in the tinySquare
|
||||
//
|
||||
bool _checkTinySquare(position& pos, uint8_t value){
|
||||
return (false == tSquares_[pos.squareID()].inMe(elements_, value));
|
||||
}
|
||||
|
||||
// _checkAndSet() : Try to put the value at the current position
|
||||
//
|
||||
// @pos : position
|
||||
// @value : value to put
|
||||
//
|
||||
// @return : true if value is set
|
||||
//
|
||||
bool _checkAndSet(position& pos, uint8_t value);
|
||||
|
||||
//
|
||||
// Drawings
|
||||
//
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
// _drawBackground() : Draw background and the grid's borders
|
||||
//
|
||||
void _drawBackground();
|
||||
|
||||
// _drawContent() : : Draw all the elements
|
||||
//
|
||||
void _drawContent();
|
||||
|
||||
// _drawSingleElement : draw a single element of the grid
|
||||
//
|
||||
// @row, @line : coordinate of the element in the grid
|
||||
// @value : value of the element in [1..9]
|
||||
// @bkColour : background colour
|
||||
// @txtColour : text colour
|
||||
//
|
||||
void _drawSingleElement(uint8_t row, uint8_t line, uint8_t value,
|
||||
int bkColour, int txtColour);
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
//
|
||||
// Search for obvious values
|
||||
//
|
||||
|
||||
// _findObviousValues() :
|
||||
// Search and set all the possible obvious values in the grid
|
||||
//
|
||||
// @return the # of values found (and set)
|
||||
//
|
||||
uint8_t _findObviousValues();
|
||||
|
||||
// _checkObviousValue() : Is there an obvious value
|
||||
// for the given position ?
|
||||
//
|
||||
// pos : current position in the grid
|
||||
//
|
||||
// @returns the value or 0
|
||||
//
|
||||
uint8_t _checkObviousValue(position& pos);
|
||||
|
||||
// _setObviousValueInLines() : Try to put the value in another line
|
||||
//
|
||||
// @pos : start position
|
||||
// @value : value to "put"
|
||||
//
|
||||
// @return : count (0 or 1) of value set
|
||||
//
|
||||
uint8_t _setObviousValueInLines(position& pos, uint8_t value);
|
||||
|
||||
// _setObviousValueInRows() : Try to put the value in another row
|
||||
//
|
||||
// @pos : start position
|
||||
// @value : value to "put"
|
||||
//
|
||||
// @return : count (0 or 1) of value set
|
||||
//
|
||||
uint8_t _setObviousValueInRows(position& pos, uint8_t value);
|
||||
|
||||
//
|
||||
// Resolving
|
||||
//
|
||||
|
||||
// _findFirstEmptyPos() : Find the first empty pos.
|
||||
//
|
||||
// @start : position where to start the search
|
||||
//
|
||||
// @return : status of position (POS_VALID or POS_END_OF_LIST)
|
||||
//
|
||||
uint8_t _findFirstEmptyPos(position &start);
|
||||
|
||||
// _previousPos() : Returns to the previous position
|
||||
//
|
||||
// Go backward in the grid to find a valid position.
|
||||
// If position index is -1, the method will return POS_INDEX_ERROR
|
||||
// ie. no solution for this grid
|
||||
//
|
||||
// @current : current position
|
||||
//
|
||||
// @return the status of the position (POS_VALID or POS_INDEX_ERROR)
|
||||
//
|
||||
uint8_t _previousPos(position& current);
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
// __callbackTick() : Call back function for timer
|
||||
// This function is used during edition to make selected item blink
|
||||
//
|
||||
// @pTick : pointer to blinking state indicator
|
||||
//
|
||||
// @return : TIMER_CONTINUE if valid
|
||||
//
|
||||
static int __callbackTick(volatile int *pTick);
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
// Members
|
||||
private:
|
||||
element elements_[LINE_COUNT * ROW_COUNT]; // grid as a one dim. table
|
||||
tinySquare tSquares_[TINY_COUNT]; // Elements IDs in tinySquares
|
||||
|
||||
RECT screen_; // Position & dims of screen : {x Grid, yGrid, "screen" width , "screen" height}
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
#endif // __S_SOLVER_SUDOKU_h__
|
||||
|
||||
// EOF
|
||||
//----------------------------------------------------------------------
|
||||
//--
|
||||
//-- sudoku.h
|
||||
//--
|
||||
//-- Definition of sudoku object - Edition and resolution
|
||||
//-- of a sudoku grid
|
||||
//--
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#ifndef __S_SOLVER_SUDOKU_h__
|
||||
#define __S_SOLVER_SUDOKU_h__ 1
|
||||
|
||||
#include "consts.h"
|
||||
|
||||
#include "element.h"
|
||||
#include "position.h"
|
||||
#include "tinySquare.h"
|
||||
|
||||
#include "shared/bFile.h"
|
||||
|
||||
// Error codes
|
||||
//
|
||||
#define FILE_NO_ERROR BFILE_NO_ERROR
|
||||
#define FILE_INVALID_FILENAME (BFILE_LAST_ERROR_CODE + 1) // File doesn't exist
|
||||
#define FILE_INVALID_FILESIZE (BFILE_LAST_ERROR_CODE + 2)
|
||||
#define FILE_NO_FILENAME (BFILE_LAST_ERROR_CODE + 3)
|
||||
#define FILE_IO_ERROR (BFILE_LAST_ERROR_CODE + 4)
|
||||
#define FILE_INVALID_LINE (BFILE_LAST_ERROR_CODE + 11)
|
||||
#define FILE_INVALID_FORMAT (BFILE_LAST_ERROR_CODE + 12)
|
||||
// The value can't be set at this position
|
||||
#define FILE_VALUE_ERROR (BFILE_LAST_ERROR_CODE + 13)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
// sudoku : Edition and/or resolution of a single sudoku grid
|
||||
//
|
||||
class sudoku{
|
||||
public:
|
||||
|
||||
// Construction & destruction
|
||||
sudoku(RECT* scr = NULL);
|
||||
~sudoku(){}
|
||||
|
||||
// display() : Display the grid and it's content
|
||||
//
|
||||
// @update : update screen ?
|
||||
//
|
||||
void display(bool update = true);
|
||||
|
||||
// empty() : Empties the grid
|
||||
//
|
||||
void empty();
|
||||
|
||||
// revert : Return to the original state
|
||||
//
|
||||
void revert();
|
||||
|
||||
// io
|
||||
//
|
||||
|
||||
// load() : Load a new grid
|
||||
//
|
||||
// @fName : file to load
|
||||
//
|
||||
// @return : 0 on success or an error code
|
||||
//
|
||||
uint8_t load(const FONTCHARACTER fName);
|
||||
|
||||
// save() : Save the grid on a file
|
||||
//
|
||||
// In the given grid, only "original" values
|
||||
// will be saved
|
||||
//
|
||||
// @fName : File name to use
|
||||
//
|
||||
// @return : 0 on success or an error code
|
||||
//
|
||||
int save(const FONTCHARACTER fName);
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
// edit() : Edit / modify the current grid
|
||||
//
|
||||
// @return : true if grid has been modified or false if unchanged
|
||||
//
|
||||
bool edit();
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
// findObviousValues() : Find all the obvious values
|
||||
//
|
||||
// @return : #obvious values found
|
||||
//
|
||||
uint8_t findObviousValues();
|
||||
|
||||
// resolve() : Find a solution for the current grid
|
||||
//
|
||||
// mDuration : points to an int that will receive duration
|
||||
// of solving process in ms. Can be NULL
|
||||
//
|
||||
// @return : true if a solution was found
|
||||
//
|
||||
bool resolve(int* mDuration = NULL);
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
// Checks
|
||||
//
|
||||
|
||||
// _checkValue() : Can we put the value at the current position ?
|
||||
//
|
||||
// @pos : position
|
||||
// @value : Check the given value at this 'position'
|
||||
//
|
||||
// @return : true if the given value is valid at the given position
|
||||
//
|
||||
bool _checkValue(position& pos, uint8_t value);
|
||||
|
||||
// _checkLine() : Can we put the value at the current position ?
|
||||
//
|
||||
// @pos : position
|
||||
// @value : Check this value at this position's line
|
||||
//
|
||||
// @return : true if the given value is valid in the given line
|
||||
//
|
||||
bool _checkLine(position& pos, uint8_t value);
|
||||
|
||||
// _checkRow() : Can we put the value at the current row ?
|
||||
//
|
||||
// @pos : position
|
||||
// @value : Check this value at this position's row
|
||||
//
|
||||
// @return : true if the given value is valid in the given row
|
||||
//
|
||||
bool _checkRow(position& pos, uint8_t value);
|
||||
|
||||
// _checTinySquare() : Can we put the value in this tinySquare ?
|
||||
//
|
||||
// @pos : position
|
||||
// @value : Check this value
|
||||
//
|
||||
// @return : true if the given value is valid in the tinySquare
|
||||
//
|
||||
bool _checkTinySquare(position& pos, uint8_t value){
|
||||
return (false == tSquares_[pos.squareID()].inMe(elements_, value));
|
||||
}
|
||||
|
||||
// _checkAndSet() : Try to put the value at the current position
|
||||
//
|
||||
// @pos : position
|
||||
// @value : value to put
|
||||
//
|
||||
// @return : true if value is set
|
||||
//
|
||||
bool _checkAndSet(position& pos, uint8_t value);
|
||||
|
||||
//
|
||||
// Drawings
|
||||
//
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
// _drawBackground() : Draw background and the grid's borders
|
||||
//
|
||||
void _drawBackground();
|
||||
|
||||
// _drawContent() : : Draw all the elements
|
||||
//
|
||||
void _drawContent();
|
||||
|
||||
// _drawSingleElement : draw a single element of the grid
|
||||
//
|
||||
// @row, @line : coordinate of the element in the grid
|
||||
// @value : value of the element in [1..9]
|
||||
// @bkColour : background colour
|
||||
// @txtColour : text colour
|
||||
//
|
||||
void _drawSingleElement(uint8_t row, uint8_t line, uint8_t value,
|
||||
int bkColour, int txtColour);
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
//
|
||||
// Search for obvious values
|
||||
//
|
||||
|
||||
// _findObviousValues() :
|
||||
// Search and set all the possible obvious values in the grid
|
||||
//
|
||||
// @return the # of values found (and set)
|
||||
//
|
||||
uint8_t _findObviousValues();
|
||||
|
||||
// _checkObviousValue() : Is there an obvious value
|
||||
// for the given position ?
|
||||
//
|
||||
// pos : current position in the grid
|
||||
//
|
||||
// @returns the value or 0
|
||||
//
|
||||
uint8_t _checkObviousValue(position& pos);
|
||||
|
||||
// _setObviousValueInLines() : Try to put the value in another line
|
||||
//
|
||||
// @pos : start position
|
||||
// @value : value to "put"
|
||||
//
|
||||
// @return : count (0 or 1) of value set
|
||||
//
|
||||
uint8_t _setObviousValueInLines(position& pos, uint8_t value);
|
||||
|
||||
// _setObviousValueInRows() : Try to put the value in another row
|
||||
//
|
||||
// @pos : start position
|
||||
// @value : value to "put"
|
||||
//
|
||||
// @return : count (0 or 1) of value set
|
||||
//
|
||||
uint8_t _setObviousValueInRows(position& pos, uint8_t value);
|
||||
|
||||
//
|
||||
// Resolving
|
||||
//
|
||||
|
||||
// _findFirstEmptyPos() : Find the first empty pos.
|
||||
//
|
||||
// @start : position where to start the search
|
||||
//
|
||||
// @return : status of position (POS_VALID or POS_END_OF_LIST)
|
||||
//
|
||||
uint8_t _findFirstEmptyPos(position &start);
|
||||
|
||||
// _previousPos() : Returns to the previous position
|
||||
//
|
||||
// Go backward in the grid to find a valid position.
|
||||
// If position index is -1, the method will return POS_INDEX_ERROR
|
||||
// ie. no solution for this grid
|
||||
//
|
||||
// @current : current position
|
||||
//
|
||||
// @return the status of the position (POS_VALID or POS_INDEX_ERROR)
|
||||
//
|
||||
uint8_t _previousPos(position& current);
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
// __callbackTick() : Call back function for timer
|
||||
// This function is used during edition to make selected item blink
|
||||
//
|
||||
// @pTick : pointer to blinking state indicator
|
||||
//
|
||||
// @return : TIMER_CONTINUE if valid
|
||||
//
|
||||
static int __callbackTick(volatile int *pTick);
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
// Members
|
||||
private:
|
||||
element elements_[LINE_COUNT * ROW_COUNT]; // grid as a one dim. table
|
||||
tinySquare tSquares_[TINY_COUNT]; // Elements IDs in tinySquares
|
||||
|
||||
RECT screen_; // Position & dims of screen : {x Grid, yGrid, "screen" width , "screen" height}
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
#endif // __S_SOLVER_SUDOKU_h__
|
||||
|
||||
// EOF
|
||||
|
|
Loading…
Reference in New Issue