1 | /*************************************************************************** |
2 | * Copyright 2007 Nicolas Roffet <nicolas-kde@roffet.com> * |
3 | * Copyright 2007 Pino Toscano <toscano.pino@tiscali.it> * |
4 | * Copyright 2011-2012 Stefan Majewsky <majewsky@gmx.net> * |
5 | * * |
6 | * This program is free software; you can redistribute it and/or modify * |
7 | * it under the terms of the GNU Library General Public License * |
8 | * version 2 as published by the Free Software Foundation * |
9 | * * |
10 | * This program is distributed in the hope that it will be useful, * |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
13 | * GNU Library General Public License for more details. * |
14 | * * |
15 | * You should have received a copy of the GNU Library General Public * |
16 | * License along with this program; if not, write to the * |
17 | * Free Software Foundation, Inc., * |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * |
19 | ***************************************************************************/ |
20 | |
21 | #ifndef KGDIFFICULTY_H |
22 | #define KGDIFFICULTY_H |
23 | |
24 | #include <QtCore/QMetaType> |
25 | #include <QtCore/QObject> |
26 | |
27 | #include <libkdegames_export.h> |
28 | |
29 | /** |
30 | * @class KgDifficultyLevel kgdifficulty.h <KgDifficultyLevel> |
31 | * @see KgDifficulty |
32 | */ |
33 | class KDEGAMES_EXPORT KgDifficultyLevel : public QObject |
34 | { |
35 | Q_OBJECT |
36 | Q_DISABLE_COPY(KgDifficultyLevel) |
37 | Q_PROPERTY(bool default READ isDefault) |
38 | Q_PROPERTY(int hardness READ hardness) |
39 | Q_PROPERTY(QByteArray key READ key) |
40 | Q_PROPERTY(QString title READ title) |
41 | Q_ENUMS(StandardLevel) |
42 | Q_PROPERTY(StandardLevel standardLevel READ standardLevel) |
43 | public: |
44 | enum StandardLevel |
45 | { |
46 | Custom = -1, ///< standardLevel() returns this for custom levels. |
47 | RidiculouslyEasy = 10, |
48 | VeryEasy = 20, |
49 | Easy = 30, |
50 | Medium = 40, |
51 | Hard = 50, |
52 | VeryHard = 60, |
53 | ExtremelyHard = 70, |
54 | Impossible = 80 |
55 | }; |
56 | |
57 | ///Refer to the getters' documentation for details on the params. |
58 | KgDifficultyLevel(int hardness, const QByteArray& key, const QString& title, bool isDefault = false); |
59 | explicit KgDifficultyLevel(StandardLevel level, bool isDefault = false); |
60 | virtual ~KgDifficultyLevel(); |
61 | |
62 | ///@return whether this level is the default level when no selection has |
63 | /// been stored (e.g. on first startup) |
64 | bool isDefault() const; |
65 | ///@return a numeric key which is used to sort the levels by difficulty |
66 | /// (smaller values mean easier levels) |
67 | ///@note For standard levels, this equals the numeric value of the level |
68 | /// in the StandardLevel enumeration. |
69 | int hardness() const; |
70 | ///@return a @b non-localized key for this level |
71 | QByteArray key() const; |
72 | ///@return a @b localized title for this level |
73 | QString title() const; |
74 | ///@return the standard level which was used to create this level, or |
75 | /// KgDifficultyLevel::Custom for custom levels |
76 | StandardLevel standardLevel() const; |
77 | private: |
78 | class Private; |
79 | Private* const d; |
80 | }; |
81 | |
82 | /** |
83 | * @class KgDifficulty kgdifficulty.h <KgDifficulty> |
84 | * @brief KgDifficulty manages difficulty levels of a game in a standard way. |
85 | * |
86 | * The difficulty can be a type of game (like in KMines: small or big field) or |
87 | * the AI skills (like in Bovo: how deep should the computer search to find the |
88 | * best move) or a combination of both of them. On the user point of view, it's |
89 | * not really different: either is the game easy or hard to play. |
90 | * |
91 | * KgDifficulty contains a list of KgDifficultyLevel instances. One of |
92 | * these levels is selected; this selection will be recorded when the |
93 | * application is closed. A set of standard difficulty levels is provided by |
94 | * KgDifficultyLevel, but custom levels can be defined at the same time. |
95 | */ |
96 | class KDEGAMES_EXPORT KgDifficulty : public QObject |
97 | { |
98 | Q_OBJECT |
99 | Q_DISABLE_COPY(KgDifficulty) |
100 | //Use currentLevel in game logic and selectedLevel in level selection UI. |
101 | Q_PROPERTY(const KgDifficultyLevel* currentLevel READ currentLevel WRITE select NOTIFY currentLevelChanged) |
102 | Q_PROPERTY(const KgDifficultyLevel* selectedLevel READ currentLevel WRITE select NOTIFY selectedLevelChanged) |
103 | Q_PROPERTY(bool editable READ isEditable WRITE setEditable NOTIFY editableChanged) |
104 | Q_PROPERTY(bool gameRunning READ isGameRunning WRITE setGameRunning NOTIFY gameRunningChanged) |
105 | public: |
106 | explicit KgDifficulty(QObject* parent = 0); |
107 | ///Destroys this instance and all DifficultyLevel instances in it. |
108 | virtual ~KgDifficulty(); |
109 | |
110 | ///Adds a difficulty level to this instance. This will not affect the |
111 | ///currentLevel() if there is one. |
112 | void addLevel(KgDifficultyLevel* level); |
113 | ///A shortcut for addLevel(new KgDifficultyLevel(@a level)). |
114 | void addStandardLevel(KgDifficultyLevel::StandardLevel level, bool isDefault = false); |
115 | ///This convenience method adds a range of standard levels to this |
116 | ///instance (including the boundaries). For example: |
117 | ///@code |
118 | ///difficulty.addStandardLevelRange( |
119 | /// KgDifficultyLevel::Easy, |
120 | /// KgDifficultyLevel::VeryHard |
121 | ///); |
122 | ///@endcode |
123 | ///This adds the levels "Easy", "Medium", "Hard" and "Very hard". |
124 | void addStandardLevelRange(KgDifficultyLevel::StandardLevel from, KgDifficultyLevel::StandardLevel to); |
125 | ///@overload |
126 | ///This overload allows to specify a @a defaultLevel. |
127 | void addStandardLevelRange(KgDifficultyLevel::StandardLevel from, KgDifficultyLevel::StandardLevel to, KgDifficultyLevel::StandardLevel defaultLevel); |
128 | |
129 | ///@return a list of all difficulty levels, sorted by hardness |
130 | QList<const KgDifficultyLevel*> levels() const; |
131 | ///@return the current difficulty level |
132 | /// |
133 | ///After the KgDifficulty object has been created, the current |
134 | ///difficulty level will not be determined until this method is called |
135 | ///for the first time. This allows the application developer to set up |
136 | ///the difficulty levels before KgDifficulty retrieves the last |
137 | ///selected level from the configuration file. |
138 | const KgDifficultyLevel* currentLevel() const; |
139 | |
140 | ///@return whether the difficulty level selection may be edited |
141 | bool isEditable() const; |
142 | ///@return whether a running game has been marked @see setGameRunning |
143 | bool isGameRunning() const; |
144 | ///Set whether the difficulty level selection may be edited. The |
145 | ///default value is true. |
146 | void setEditable(bool editable); |
147 | ///KgDifficulty has optional protection against changing the |
148 | ///difficulty level while a game is running. If setGameRunning(true) has |
149 | ///been called, and select() is called to select a new difficulty level, |
150 | ///the user will be asked for confirmation. |
151 | void setGameRunning(bool running); |
152 | Q_SIGNALS: |
153 | ///Emitted when the editability changes. @see setEditable |
154 | void editableChanged(bool editable); |
155 | ///Emitted when a running game has been marked or unmarked. @see setGameRunning |
156 | void gameRunningChanged(bool gameRunning); |
157 | ///Emitted when a new difficulty level has been selected. |
158 | void currentLevelChanged(const KgDifficultyLevel* level); |
159 | ///Emitted after every call to select(), even when the user has rejected |
160 | ///the change. This is useful to reset a difficulty level selection UI |
161 | ///after a rejected change. |
162 | void selectedLevelChanged(const KgDifficultyLevel* level); |
163 | public Q_SLOTS: |
164 | ///Select a new difficulty level. The given level must already have been |
165 | ///added to this instance. |
166 | ///@note This does nothing if isEditable() is false. If a game is |
167 | ///running (according to setGameRunning()), the user will be asked for |
168 | ///confirmation before the new difficulty level is selected. |
169 | void select(const KgDifficultyLevel* level); |
170 | private: |
171 | class Private; |
172 | Private* const d; |
173 | }; |
174 | |
175 | Q_DECLARE_METATYPE(const KgDifficultyLevel*) |
176 | |
177 | //TODO: Where to put documentation for this namespace? |
178 | namespace Kg |
179 | { |
180 | ///@return a singleton instance of KgDifficulty |
181 | KDEGAMES_EXPORT KgDifficulty* difficulty(); |
182 | ///A shortcut for Kg::difficulty()->currentLevel()->standardLevel(). |
183 | KDEGAMES_EXPORT KgDifficultyLevel::StandardLevel difficultyLevel(); |
184 | } |
185 | |
186 | class KXmlGuiWindow; |
187 | |
188 | //TODO KDE5: move this into a separate QtWidgets support library |
189 | namespace KgDifficultyGUI |
190 | { |
191 | ///Install standard GUI components for the manipulation of the given |
192 | ///KgDifficulty instance in the given @a window. |
193 | /// |
194 | ///Without a second parameter, the Kg::difficulty() singleton is used. |
195 | KDEGAMES_EXPORT void init(KXmlGuiWindow* window, KgDifficulty* difficulty = 0); |
196 | } |
197 | |
198 | #endif // KGDIFFICULTY_H |
199 | |