diff options
-rw-r--r-- | HISTORY | 2 | ||||
-rw-r--r-- | README | 19 | ||||
-rw-r--r-- | commands.cpp | 128 | ||||
-rw-r--r-- | commands.h | 41 | ||||
-rw-r--r-- | menu.cpp | 151 | ||||
-rw-r--r-- | menu.h | 13 | ||||
-rw-r--r-- | puzzle.cpp | 4 | ||||
-rw-r--r-- | puzzle.h | 4 | ||||
-rw-r--r-- | setup.cpp | 22 | ||||
-rw-r--r-- | setup.h | 5 | ||||
-rw-r--r-- | solver.cpp | 4 |
11 files changed, 303 insertions, 90 deletions
@@ -53,3 +53,5 @@ VDR plug-in 'Sudoku' Revision History ____-__-__: Version 0.3.0 - Added history function. +- Added setup options to configure red, green and yellow key. +- Change default commands for red, green and yellow key: mark, undo and redo. @@ -101,6 +101,12 @@ Setup: Values: yes/no. Default: no. - Clear marks on reset Unmark all cells when the puzzle is reset. Values: yes/no. Default: no. +- Key Red Choose command for the red key. + Values: see commands menu. Default: Mark/unmark. +- Key Green Choose command for the green key. + Values: see commands menu. Default: Undo last action. +- Key Yellow Choose command for the yellow key. + Values: see commands menu. Default: Redo last action. - Transparency (%) Set the transparency of the menu. Values: 0-100. Default: 50. @@ -111,11 +117,9 @@ Keys: - Left/Right/Up/Down Move the cursor in the puzzle. - 1-9 Set the number in the current cell. - 0 Remove the number from the current cell. -- Green Mark/unmark the current cell. -- Yellow Move the cursor to the next free cell with minimal - possible numbers. -- Red Set the next possible number for the current cell - - reset the number if greater numbers are not possible. +- Red Execute red key command. +- Green Execute green key command. +- Yellow Execute yellow key command. - Blue Open the commands menu. - Back Quit the plug-in. @@ -131,6 +135,11 @@ Commands menu: optional description. - Undo last action Go one step backward in the history. - Redo last action Go one step forward in the history. +- Mark/unmark Mark/unmark the current cell. +- Next cell Move the cursor to the next free cell with minimal + possible numbers. +- Next number Set the next possible number for the current cell - + reset the number if greater numbers are not possible. - Reset the puzzle Reset the numbers in all cells, excluding the givens. - Open setup menu Open the setup menu of the plug-in. - Exit Quit the plug-in. diff --git a/commands.cpp b/commands.cpp index 029978c..e9a9d91 100644 --- a/commands.cpp +++ b/commands.cpp @@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * $Id: commands.cpp 140 2008-06-30 22:10:38Z tom $ + * $Id: commands.cpp 142 2008-07-06 15:50:02Z tom $ */ #include "commands.h" @@ -28,9 +28,125 @@ #include <vdr/osd.h> #include <assert.h> + +namespace SudokuPlugin +{ + /** Command ids */ + enum + { + Cmd_LowerEdge = 100, + CmdGenerate, + CmdReset, + CmdExit, + CmdMark, + CmdNextCell, + CmdNextNumber, + CmdLoad, + CmdSave, + CmdSetup, + CmdUndo, + CmdRedo, + // Add new command ids only here, don't remove commands. + Cmd_UpperEdge, + Cmd_Count = Cmd_UpperEdge-Cmd_LowerEdge-1, + // Default commands + Cmd_KeyRedDefault = CmdMark, + Cmd_KeyGreenDefault = CmdUndo, + Cmd_KeyYellowDefault = CmdRedo + }; +} // namespace SudokuPlugin + + using namespace SudokuPlugin; +//--- class SudokuPlugin::CommandList ------------------------------------------ + +/** List of commands - sorted for the commands menu */ +const struct CommandList::List CommandList::list[] = +{ + { CmdGenerate, trNOOP("Generate a new puzzle"), &Menu::generate }, + { CmdLoad, trNOOP("Load a puzzle"), &Menu::load }, + { CmdSave, trNOOP("Save the puzzle"), &Menu::save }, + { CmdUndo, trNOOP("Undo last action"), &Menu::undo }, + { CmdRedo, trNOOP("Redo last action"), &Menu::redo }, + { CmdMark, trNOOP("Mark/unmark"), &Menu::toggle_mark }, + { CmdNextCell, trNOOP("Next cell"), &Menu::next_cell }, + { CmdNextNumber, trNOOP("Next number"), &Menu::next_number }, + { CmdReset, trNOOP("Reset the puzzle"), &Menu::reset }, + { CmdSetup, trNOOP("Open setup menu"), &Menu::open_setup }, + { CmdExit, trNOOP("Exit"), &Menu::exit } +}; + +/** Command id of a command */ +int CommandList::id(int index) +{ + assert(index >= 0 && index < count()); + return list[index].id; +} + +/** Translated text of a command */ +const char* CommandList::text(int index) +{ + assert(index >= 0 && index < count()); + return tr(list[index].text); +} + +/** Command type of a command */ +CommandType CommandList::command(int index) +{ + assert(index >= 0 && index < count()); + return list[index].cmd; +} + +/** Count of commands */ +int CommandList::count() +{ + assert(Cmd_Count == sizeof(list)/sizeof(*list)); + return Cmd_Count; +} + +/** List with translated texts of all commands */ +const char* const* CommandList::texts() +{ + static const char* text_list[Cmd_Count]; + for (int idx = 0; idx < count(); ++idx) + text_list[idx] = tr(list[idx].text); + return text_list; +} + +/** Search a command id. Return default index if not found. */ +int CommandList::id_to_index(int id, int default_index) +{ + int idx = 0; + for (; idx < count(); ++idx) + if (list[idx].id == id) + break; + if (idx >= count()) + idx = default_index; + assert(idx >= 0 && idx < count()); + return idx; +} + +/** Default index for the red key */ +int CommandList::key_red_default_index() +{ + return id_to_index(Cmd_KeyRedDefault); +} + +/** Default index for the green key */ +int CommandList::key_green_default_index() +{ + return id_to_index(Cmd_KeyGreenDefault); +} + +/** Default index for the yellow key */ +int CommandList::key_yellow_default_index() +{ + return id_to_index(Cmd_KeyYellowDefault); +} + + //--- class SudokuPlugin::CommandMenu ------------------------------------------ /** Constructor */ @@ -38,14 +154,8 @@ CommandMenu::CommandMenu() : cOsdMenu(trVDR("Commands")) { SetHasHotkeys(); - Add(new Command(hk(tr("Generate a new puzzle")), &Menu::generate)); - Add(new Command(hk(tr("Load a puzzle")), &Menu::load)); - Add(new Command(hk(tr("Save the puzzle")), &Menu::save)); - Add(new Command(hk(tr("Undo last action")), &Menu::undo)); - Add(new Command(hk(tr("Redo last action")), &Menu::redo)); - Add(new Command(hk(tr("Reset the puzzle")), &Menu::reset)); - Add(new Command(hk(tr("Open setup menu")), &Menu::open_setup)); - Add(new Command(hk(tr("Exit")), &Menu::exit)); + for (int idx = 0; idx < CommandList::count(); ++idx) + Add(new Command(hk(CommandList::text(idx)), CommandList::command(idx))); command = NULL; } @@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * $Id: commands.h 113 2008-03-16 20:12:52Z tom $ + * $Id: commands.h 142 2008-07-06 15:50:02Z tom $ */ #ifndef VDR_SUDOKU_COMMANDS_H @@ -35,6 +35,45 @@ namespace SudokuPlugin typedef eOSState (Menu::*CommandType)(); + //--- class SudokuPlugin::CommandList ---------------------------------------- + + class CommandList + { + /** List of commands - sorted for the commands menu */ + struct List { int id; const char* text; CommandType cmd; }; + static const struct List list[]; + + public: + + /** Command id of a command */ + static int id(int index); + + /** Translated text of a command */ + static const char* text(int index); + + /** Command type of a command */ + static CommandType command(int index); + + /** Count of commands */ + static int count(); + + /** List with translated texts of all commands */ + static const char* const* texts(); + + /** Search a command id. Return default index if not found. */ + static int id_to_index(int id, int default_index = -1); + + /** Default index for the red key */ + static int key_red_default_index(); + + /** Default index for the green key */ + static int key_green_default_index(); + + /** Default index for the yellow key */ + static int key_yellow_default_index(); + }; + + //--- class SudokuPlugin::CommandMenu ---------------------------------------- /** Commands menu of the plugin */ @@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * $Id: menu.cpp 140 2008-06-30 22:10:38Z tom $ + * $Id: menu.cpp 142 2008-07-06 15:50:02Z tom $ */ #include "menu.h" @@ -172,73 +172,73 @@ eOSState Menu::ProcessKey(eKeys key) eOSState state = cOsdObject::ProcessKey(key); if (state == osUnknown) { - if (key == kBack) - return exit(); - if (key == kBlue) + Pos curr = puzzle->get_pos(); + CommandType command = NULL; + switch (key) { - osd->Flush(); - DELETENULL(osd); - command_menu = new CommandMenu(); - command_menu->Display(); - return osContinue; + case kLeft: + case kLeft|k_Repeat: + puzzle->set_pos(curr.prev_col()); + break; + case kRight: + case kRight|k_Repeat: + puzzle->set_pos(curr.next_col()); + break; + case kUp: + case kUp|k_Repeat: + puzzle->set_pos(curr.prev_row()); + break; + case kDown: + case kDown|k_Repeat: + puzzle->set_pos(curr.next_row()); + break; + case k0: + case k1: + case k2: + case k3: + case k4: + case k5: + case k6: + case k7: + case k8: + case k9: + puzzle->set_with_history(key - k0); + break; + case kRed: + command = CommandList::command(setup.key_red); + break; + case kGreen: + command = CommandList::command(setup.key_green); + break; + case kYellow: + command = CommandList::command(setup.key_yellow); + break; + case kBlue: + osd->Flush(); + DELETENULL(osd); + command_menu = new CommandMenu(); + command_menu->Display(); + return osContinue; + case kOk: + if (new_puzzle_request) + generate(); + break; + case kBack: + return exit(); + default: + return osContinue; } - if (new_puzzle_request) - { - if (key == kOk) - generate(); - } - else + if (command) { - Pos curr = puzzle->get_pos(); - switch (key) - { - case kLeft: - case kLeft|k_Repeat: - puzzle->set_pos(curr.prev_col()); - break; - case kRight: - case kRight|k_Repeat: - puzzle->set_pos(curr.next_col()); - break; - case kUp: - case kUp|k_Repeat: - puzzle->set_pos(curr.prev_row()); - break; - case kDown: - case kDown|k_Repeat: - puzzle->set_pos(curr.next_row()); - break; - case k0: - case k1: - case k2: - case k3: - case k4: - case k5: - case k6: - case k7: - case k8: - case k9: - puzzle->set_with_history(key - k0); - break; - case kRed: - puzzle->set_with_history(puzzle->next_number(curr)); - break; - case kGreen: - puzzle->toggle_mark(curr); - break; - case kYellow: - if (puzzle->next_free(curr) <= Pos::last()) - puzzle->set_pos(puzzle->next_free(curr)); - break; - default: - return osContinue; - } + state = (this->*command)(); + if (state == osUnknown) + return osContinue; + if (state == osEnd) + return osEnd; } - if (puzzle->solved()) - { - new_puzzle_request = true; + new_puzzle_request = !new_puzzle_request && puzzle->solved(); + if (new_puzzle_request) infoText = tr("Congratulations!\nPress OK to start a new puzzle"); - } paint(); state = osContinue; } @@ -288,6 +288,29 @@ eOSState Menu::redo() return osContinue; } +/** Mark/unmark the current cell. */ +eOSState Menu::toggle_mark() +{ + puzzle->toggle_mark(puzzle->get_pos()); + return osContinue; +} + +/** Move the cursor to the next free cell with minimal possible numbers. */ +eOSState Menu::next_cell() +{ + Pos new_pos = puzzle->next_cell(puzzle->get_pos()); + if (new_pos <= Pos::last()) + puzzle->set_pos(new_pos); + return osContinue; +} + +/** Set the next possible number for the current cell. */ +eOSState Menu::next_number() +{ + puzzle->set_with_history(puzzle->next_number(puzzle->get_pos())); + return osContinue; +} + /** Reset the puzzle. */ eOSState Menu::reset() { @@ -403,8 +426,6 @@ void Menu::paint() osd->DrawBitmap(xPos + 10, yPos + 10, *info); infoText = NULL; } - else - new_puzzle_request = false; osd->Flush(); } @@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * $Id: menu.h 140 2008-06-30 22:10:38Z tom $ + * $Id: menu.h 142 2008-07-06 15:50:02Z tom $ */ #ifndef VDR_SUDOKU_MENU_H @@ -88,7 +88,16 @@ namespace SudokuPlugin /** Redo last action. */ eOSState redo(); - + + /** Mark/unmark the current cell. */ + eOSState toggle_mark(); + + /** Move the cursor to the next free cell with minimal possible numbers. */ + eOSState next_cell(); + + /** Set the next possible number for the current cell. */ + eOSState next_number(); + /** Reset the puzzle. */ eOSState reset(); @@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * $Id: puzzle.cpp 141 2008-07-05 14:52:52Z tom $ + * $Id: puzzle.cpp 142 2008-07-06 15:50:02Z tom $ */ #include "puzzle.h" @@ -311,7 +311,7 @@ void Puzzle::toggle_mark(Pos pos) } /** Get the next free cell with minimal possible numbers. */ -Pos Puzzle::next_free(Pos pos) const +Pos Puzzle::next_cell(Pos pos) const { unsigned int min_count = DIM+1, min_index = SDIM, i; @@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * $Id: puzzle.h 140 2008-06-30 22:10:38Z tom $ + * $Id: puzzle.h 142 2008-07-06 15:50:02Z tom $ */ #ifndef VDR_SUDOKU_PUZZLE_H @@ -188,7 +188,7 @@ namespace Sudoku void toggle_mark(Pos pos); /** Get the next free cell with minimal possible numbers. */ - Pos next_free(Pos pos = Pos::last()) const; + Pos next_cell(Pos pos = Pos::last()) const; /** Get the next possible number for this cell. */ unsigned int next_number(Pos pos) const; @@ -17,10 +17,11 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * $Id: setup.cpp 135 2008-04-05 20:23:44Z tom $ + * $Id: setup.cpp 142 2008-07-06 15:50:02Z tom $ */ #include "setup.h" +#include "commands.h" #include "i18n.h" #include <strings.h> @@ -42,6 +43,9 @@ SetupData::SetupData() show_possibles_pattern = 0; show_possibles_digits = 0; clear_marks = 0; + key_red = CommandList::key_red_default_index(); + key_green = CommandList::key_green_default_index(); + key_yellow = CommandList::key_yellow_default_index(); transparency = 50; } @@ -52,6 +56,7 @@ SetupData::SetupData() */ bool SetupData::parse(const char* name, const char* value) { + CommandList cl; if (!strcasecmp(name, "GivensCount")) givens_count = atoi(value); else if (!strcasecmp(name, "Symmetric")) @@ -66,6 +71,12 @@ bool SetupData::parse(const char* name, const char* value) show_possibles_digits = atoi(value); else if (!strcasecmp(name, "ClearMarks")) clear_marks = atoi(value); + else if (!strcasecmp(name, "KeyRed")) + key_red = cl.id_to_index(atoi(value), cl.key_red_default_index()); + else if (!strcasecmp(name, "KeyGreen")) + key_green = cl.id_to_index(atoi(value), cl.key_green_default_index()); + else if (!strcasecmp(name, "KeyYellow")) + key_yellow = cl.id_to_index(atoi(value), cl.key_yellow_default_index()); else if (!strcasecmp(name, "Transparency")) transparency = atoi(value); else @@ -92,6 +103,12 @@ SetupPage::SetupPage(SetupData& setup) : &data.show_possibles_digits)); #endif Add(new cMenuEditBoolItem(tr("Clear marks on reset"), &data.clear_marks)); + Add(new cMenuEditStraItem(tr("Key Red"), &data.key_red, + CommandList::count(), CommandList::texts())); + Add(new cMenuEditStraItem(tr("Key Green"), &data.key_green, + CommandList::count(), CommandList::texts())); + Add(new cMenuEditStraItem(tr("Key Yellow"), &data.key_yellow, + CommandList::count(), CommandList::texts())); Add(new cMenuEditIntItem(tr("Transparency (%)"), &data.transparency, 0, 100)); } @@ -110,5 +127,8 @@ void SetupPage::Store() SetupStore("ShowPossiblesPattern", setup.show_possibles_pattern); SetupStore("ShowPossiblesDigits", setup.show_possibles_digits); SetupStore("ClearMarks", setup.clear_marks); + SetupStore("KeyRed", CommandList::id(setup.key_red)); + SetupStore("KeyGreen", CommandList::id(setup.key_green)); + SetupStore("KeyYellow", CommandList::id(setup.key_yellow)); SetupStore("Transparency", setup.transparency); } @@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * $Id: setup.h 117 2008-03-21 17:57:50Z tom $ + * $Id: setup.h 142 2008-07-06 15:50:02Z tom $ */ #ifndef VDR_SUDOKU_SETUP_H @@ -43,6 +43,9 @@ namespace SudokuPlugin int show_possibles_pattern; int show_possibles_digits; int clear_marks; + int key_red; + int key_green; + int key_yellow; int transparency; /** Constructor */ @@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * $Id: solver.cpp 117 2008-03-21 17:57:50Z tom $ + * $Id: solver.cpp 142 2008-07-06 15:50:02Z tom $ */ #define USE_RAND @@ -46,7 +46,7 @@ Solver::Solver(Puzzle& puzzle, bool random_init, unsigned int max_iter) : void Solver::set_first_at(unsigned int level) { assert(level < free_count); - const Pos p = puzzle.next_free(); + const Pos p = puzzle.next_cell(); assert(p <= Pos::last()); free_list[level] = p; |