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 */
33class 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 */
96class 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
175Q_DECLARE_METATYPE(const KgDifficultyLevel*)
176
177//TODO: Where to put documentation for this namespace?
178namespace 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
186class KXmlGuiWindow;
187
188//TODO KDE5: move this into a separate QtWidgets support library
189namespace 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