File indexing completed on 2024-09-15 06:39:03
0001 /*************************************************************************** 0002 * Copyright 2007 Francesco Rossi <redsh@email.it> * 0003 * Copyright 2006-2007 Mick Kappenburg <ksudoku@kappendburg.net> * 0004 * Copyright 2006-2007 Johannes Bergmeier <johannes.bergmeier@gmx.net> * 0005 * Copyright 2015 Ian Wadham <iandw.au@gmail.com> * 0006 * * 0007 * This program is free software; you can redistribute it and/or modify * 0008 * it under the terms of the GNU General Public License as published by * 0009 * the Free Software Foundation; either version 2 of the License, or * 0010 * (at your option) any later version. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0015 * GNU General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU General Public License * 0018 * along with this program; if not, write to the * 0019 * Free Software Foundation, Inc., * 0020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 0021 ***************************************************************************/ 0022 0023 #ifndef _KSUDOKUGAME_H_ 0024 #define _KSUDOKUGAME_H_ 0025 0026 #include <QObject> 0027 #include <QUrl> 0028 #include "history.h" 0029 0030 class SKGraph; 0031 0032 class QWidget; 0033 0034 namespace ksudoku { 0035 0036 class Puzzle ; 0037 0038 /** 0039 * The interface of a game. Since the game itself is a shared class you cannot connect to 0040 * the game. Use game->interface() to get a interface instance which you can use to connect 0041 * to. 0042 */ 0043 class GameIFace : public QObject { 0044 Q_OBJECT 0045 0046 public Q_SLOTS: 0047 virtual void undo() = 0; 0048 virtual void redo() = 0; 0049 virtual void addCheckpoint() = 0; 0050 virtual void undo2Checkpoint() = 0; 0051 0052 Q_SIGNALS: 0053 void modified(bool isModified); 0054 void completed(bool isCorrect, const QTime& required, bool withHelp); 0055 void cellChange(int index); 0056 void fullChange(); 0057 void cageChange(int cageNum, bool showLabel); 0058 }; 0059 0060 /** 0061 * @author Johannes Bergmeier 0062 * 0063 * A Game instance represents a interactive game. 0064 * 0065 * For simple puzzles use @c ksudoku::Puzzle. 0066 * 0067 * @see ksudoku::Puzzle 0068 */ 0069 class Game { 0070 public: 0071 /** 0072 * Creates an invalid game 0073 */ 0074 Game(); 0075 0076 /** 0077 * @param[in] puzzle The puzzle for this game 0078 * @note The Game takes ownership on @p puzzle 0079 */ 0080 explicit Game(Puzzle* puzzle); 0081 0082 /** 0083 * Copy constructor 0084 */ 0085 Game(const Game& game); 0086 ~Game(); 0087 0088 public: 0089 // TODO improve this 0090 inline bool isValid() const { return static_cast<bool>(m_private); } 0091 0092 /** 0093 * The nubmer of cells of the puzzle 0094 */ 0095 int size() const; 0096 0097 /** 0098 * Checks whether a set contains obvious errors 0099 * 0100 * @returns True when no error against the rules of the graph exists. This doesn't mean, 0101 * that the values are suitable to solve the puzzle. 0102 */ 0103 bool simpleCheck() const; 0104 0105 ///@return pointer to current puzzle 0106 Puzzle* puzzle() const; 0107 0108 /** 0109 * Gets the interface of the game. Use this if for connecting to signals or 0110 * slots of the game 0111 */ 0112 GameIFace* interface() const; 0113 0114 Game& operator=(const Game& game); 0115 0116 public: 0117 /** 0118 * Restarts the game and marks it as unfinished 0119 */ 0120 void restart(); 0121 0122 int order() const; 0123 0124 int value(int index) const; 0125 int solution(int index) const; 0126 bool given(int index) const; 0127 bool marker(int index, int value) const; 0128 0129 /** 0130 * Returns the state of a cell 0131 * @param[in] index The index of the cell 0132 */ 0133 ksudoku::ButtonState buttonState(int index) const; 0134 CellInfo cellInfo(int index) const; 0135 0136 /** 0137 * Sets one marker in a cell 0138 * @param[in] index The index of the cell 0139 * @param[in] val The value of the marker 0140 * @param[in] state Whether the marker should be set or unset 0141 * @return Whether this function was executed successfully 0142 */ 0143 bool setMarker(int index, int val, bool state); 0144 inline bool flipMarker(int index, int val); 0145 0146 /** 0147 * @brief Sets the value of a cell 0148 * @param[in] index The index of the cell 0149 * @param[in] val The new value of the cell 0150 */ 0151 void setValue(int index, int val); 0152 0153 /** 0154 * Sets whether cell @p index is @p given (A given cell is not changeable by the player). 0155 */ 0156 void setGiven(int index, bool given); 0157 0158 /** 0159 * Constructs a cage for a Mathdoku or Killer Sudoku puzzle which is 0160 * being entered in. Proceeds in steps of one keystroke at a time. 0161 * 0162 * @param[in] index The position of a cell. 0163 * @param[in] val A digit for the value, an operator for the cage or 0164 * a code, e.g. add a cell to the cage or finish it. 0165 * 0166 * @return True if the value was handled by addToCage(), false 0167 * if it should be processed by setValue(), as for a 0168 * Sudoku or Roxdoku puzzle. 0169 */ 0170 bool addToCage (int pos, int val); 0171 0172 /** 0173 * Gets the all current values of the game 0174 */ 0175 const BoardContents allValues() const; 0176 0177 /** 0178 * Gives one value in a randomly chosen cell. 0179 */ 0180 bool giveHint(); 0181 0182 /** 0183 * Makes the whole puzzle given. 0184 */ 0185 bool autoSolve(); 0186 0187 /** 0188 * Returns the time since game start, as a QTime object. 0189 */ 0190 QTime time() const; 0191 0192 /** 0193 * Returns the time since game start, as milliseconds. Used when saving 0194 * the elapsed time during a break in play. 0195 */ 0196 int msecsElapsed() const; 0197 0198 /** 0199 * Sets the time since game start and restarts the clock. Used after a 0200 * break in play, e.g. when loading a saved game. 0201 */ 0202 void setTime(int msecs) const; 0203 0204 /** 0205 * Sets the URL. Game itself doesn't use the URL, but remembers it for other users. 0206 */ 0207 void setUrl(const QUrl& url); 0208 0209 /** 0210 * Gets the URL. Game itself doesn't use the URL, but remembers it for other users. 0211 */ 0212 QUrl getUrl() const; 0213 0214 /** 0215 * Returns whether the user requested some hint. 0216 * @see giveHint(), autoSolve() 0217 */ 0218 bool userHadHelp() const; 0219 0220 /** 0221 * Returns whether the game was already solved. 0222 */ 0223 bool wasFinished() const; 0224 0225 /** 0226 * Sets whether the user had requested some hint. 0227 * @note This method is for loading/saving only 0228 * @see userHadHelp(), giveHint(), autoSolve() 0229 */ 0230 void setUserHadHelp(bool hadHelp); 0231 0232 // History 0233 0234 bool canUndo() const; 0235 bool canRedo() const; 0236 0237 /** 0238 * Adds an event to the history and performs it 0239 */ 0240 void doEvent(const HistoryEvent& event); 0241 0242 /** 0243 * Returns count of history events 0244 */ 0245 int historyLength() const; 0246 0247 /** 0248 * Returns the history event at position @p i 0249 */ 0250 HistoryEvent historyEvent(int i) const; 0251 0252 /** 0253 * Set the parent of message-box dialogs (used in data-entry of cages). 0254 */ 0255 void setMessageParent (QWidget * messageParent); 0256 QWidget * messageParent(); 0257 0258 /* 0259 * Returns true if all values are filled in (not empty) 0260 * and in usable areas (as in Samurai); false otherwise 0261 */ 0262 bool allValuesSetAndUsable() const; 0263 0264 private: 0265 /** 0266 * When the game was finished this function emits a @c completed() 0267 */ 0268 void checkCompleted(); 0269 0270 void finishCurrentCage (SKGraph * graph); 0271 void deleteCageAt (int pos, SKGraph * graph); 0272 bool validCell (int pos, SKGraph * graph); 0273 0274 private: 0275 class Private; 0276 0277 Private* m_private; 0278 }; 0279 0280 inline bool Game::flipMarker(int index, int val) { 0281 return setMarker(index, val, !marker(index, val)); 0282 } 0283 0284 } 0285 0286 #endif