File indexing completed on 2024-04-28 04:05:02

0001 /*
0002     SPDX-FileCopyrightText: 2007 Nicolas Roffet <nicolas-kde@roffet.com>
0003     SPDX-FileCopyrightText: 2007 Pino Toscano <toscano.pino@tiscali.it>
0004     SPDX-FileCopyrightText: 2011-2012 Stefan Majewsky <majewsky@gmx.net>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #ifndef KGAMEDIFFICULTY_H
0010 #define KGAMEDIFFICULTY_H
0011 
0012 // own
0013 #include "kdegames_export.h"
0014 // Qt
0015 #include <QMetaType>
0016 #include <QObject>
0017 // Std
0018 #include <memory>
0019 
0020 /**
0021  * @class KGameDifficultyLevel kgamedifficulty.h <KGameDifficultyLevel>
0022  * @see KGameDifficulty
0023  */
0024 class KDEGAMES_EXPORT KGameDifficultyLevel : public QObject
0025 {
0026     Q_OBJECT
0027     Q_DISABLE_COPY(KGameDifficultyLevel)
0028     Q_PROPERTY(bool default READ isDefault)
0029     Q_PROPERTY(int hardness READ hardness)
0030     Q_PROPERTY(QByteArray key READ key)
0031     Q_PROPERTY(QString title READ title)
0032     Q_PROPERTY(StandardLevel standardLevel READ standardLevel)
0033 
0034 public:
0035     enum StandardLevel {
0036         Custom = -1, ///< standardLevel() returns this for custom levels.
0037         RidiculouslyEasy = 10,
0038         VeryEasy = 20,
0039         Easy = 30,
0040         Medium = 40,
0041         Hard = 50,
0042         VeryHard = 60,
0043         ExtremelyHard = 70,
0044         Impossible = 80
0045     };
0046     Q_ENUM(StandardLevel)
0047 
0048     /// Refer to the getters' documentation for details on the params.
0049     KGameDifficultyLevel(int hardness, const QByteArray &key, const QString &title, bool isDefault = false);
0050     explicit KGameDifficultyLevel(StandardLevel level, bool isDefault = false);
0051     ~KGameDifficultyLevel() override;
0052 
0053     /// @return whether this level is the default level when no selection has
0054     ///        been stored (e.g. on first startup)
0055     bool isDefault() const;
0056     /// @return a numeric key which is used to sort the levels by difficulty
0057     ///        (smaller values mean easier levels)
0058     /// @note For standard levels, this equals the numeric value of the level
0059     ///      in the StandardLevel enumeration.
0060     int hardness() const;
0061     /// @return a @b non-localized key for this level
0062     QByteArray key() const;
0063     /// @return a @b localized title for this level
0064     QString title() const;
0065     /// @return the standard level which was used to create this level, or
0066     ///        KGameDifficultyLevel::Custom for custom levels
0067     StandardLevel standardLevel() const;
0068 
0069 private:
0070     std::unique_ptr<class KGameDifficultyLevelPrivate> const d_ptr;
0071     Q_DECLARE_PRIVATE(KGameDifficultyLevel)
0072 };
0073 
0074 /**
0075  * @class KGameDifficulty kgamedifficulty.h <KGameDifficulty>
0076  * @brief KGameDifficulty manages difficulty levels of a game in a standard way.
0077  *
0078  * The difficulty can be a type of game (like in KMines: small or big field) or
0079  * the AI skills (like in Bovo: how deep should the computer search to find the
0080  * best move) or a combination of both of them. On the user point of view, it's
0081  * not really different: either is the game easy or hard to play.
0082  *
0083  * KGameDifficulty contains a list of KGameDifficultyLevel instances. One of
0084  * these levels is selected; this selection will be recorded when the
0085  * application is closed. A set of standard difficulty levels is provided by
0086  * KGameDifficultyLevel, but custom levels can be defined at the same time.
0087  */
0088 class KDEGAMES_EXPORT KGameDifficulty : public QObject
0089 {
0090     Q_OBJECT
0091     Q_DISABLE_COPY(KGameDifficulty)
0092     // Use currentLevel in game logic and selectedLevel in level selection UI.
0093     Q_PROPERTY(const KGameDifficultyLevel *currentLevel READ currentLevel WRITE select NOTIFY currentLevelChanged)
0094     Q_PROPERTY(const KGameDifficultyLevel *selectedLevel READ currentLevel WRITE select NOTIFY selectedLevelChanged)
0095     Q_PROPERTY(bool editable READ isEditable WRITE setEditable NOTIFY editableChanged)
0096     Q_PROPERTY(bool gameRunning READ isGameRunning WRITE setGameRunning NOTIFY gameRunningChanged)
0097 
0098 public:
0099     /// @return a singleton instance of KGameDifficulty
0100     static KGameDifficulty *global();
0101     /// A shortcut for KGameDifficulty::global()->currentLevel()->standardLevel().
0102     static KGameDifficultyLevel::StandardLevel globalLevel();
0103 
0104 public:
0105     explicit KGameDifficulty(QObject *parent = nullptr);
0106     /// Destroys this instance and all DifficultyLevel instances in it.
0107     ~KGameDifficulty() override;
0108 
0109     /// Adds a difficulty level to this instance. This will not affect the
0110     /// currentLevel() if there is one.
0111     void addLevel(KGameDifficultyLevel *level);
0112     /// A shortcut for addLevel(new KGameDifficultyLevel(@a level)).
0113     void addStandardLevel(KGameDifficultyLevel::StandardLevel level, bool isDefault = false);
0114     /// This convenience method adds a range of standard levels to this
0115     /// instance (including the boundaries). For example:
0116     /// @code
0117     /// difficulty.addStandardLevelRange(
0118     ///     KGameDifficultyLevel::Easy,
0119     ///     KGameDifficultyLevel::VeryHard
0120     ///);
0121     /// @endcode
0122     /// This adds the levels "Easy", "Medium", "Hard" and "Very hard".
0123     void addStandardLevelRange(KGameDifficultyLevel::StandardLevel from, KGameDifficultyLevel::StandardLevel to);
0124     /// @overload
0125     /// This overload allows to specify a @a defaultLevel.
0126     void
0127     addStandardLevelRange(KGameDifficultyLevel::StandardLevel from, KGameDifficultyLevel::StandardLevel to, KGameDifficultyLevel::StandardLevel defaultLevel);
0128 
0129     /// @return a list of all difficulty levels, sorted by hardness
0130     QList<const KGameDifficultyLevel *> levels() const;
0131     /// @return the current difficulty level
0132     ///
0133     /// After the KGameDifficulty object has been created, the current
0134     /// difficulty level will not be determined until this method is called
0135     /// for the first time. This allows the application developer to set up
0136     /// the difficulty levels before KGameDifficulty retrieves the last
0137     /// selected level from the configuration file.
0138     const KGameDifficultyLevel *currentLevel() const;
0139 
0140     /// @return whether the difficulty level selection may be edited
0141     bool isEditable() const;
0142     /// @return whether a running game has been marked @see setGameRunning
0143     bool isGameRunning() const;
0144     /// Set whether the difficulty level selection may be edited. The
0145     /// default value is true.
0146     void setEditable(bool editable);
0147     /// KGameDifficulty has optional protection against changing the
0148     /// difficulty level while a game is running. If setGameRunning(true) has
0149     /// been called, and select() is called to select a new difficulty level,
0150     /// the user will be asked for confirmation.
0151     void setGameRunning(bool running);
0152 Q_SIGNALS:
0153     /// Emitted when the editability changes. @see setEditable
0154     void editableChanged(bool editable);
0155     /// Emitted when a running game has been marked or unmarked. @see setGameRunning
0156     void gameRunningChanged(bool gameRunning);
0157     /// Emitted when a new difficulty level has been selected.
0158     void currentLevelChanged(const KGameDifficultyLevel *level);
0159     /// Emitted after every call to select(), even when the user has rejected
0160     /// the change. This is useful to reset a difficulty level selection UI
0161     /// after a rejected change.
0162     void selectedLevelChanged(const KGameDifficultyLevel *level);
0163 public Q_SLOTS:
0164     /// Select a new difficulty level. The given level must already have been
0165     /// added to this instance.
0166     /// @note This does nothing if isEditable() is false. If a game is
0167     /// running (according to setGameRunning()), the user will be asked for
0168     /// confirmation before the new difficulty level is selected.
0169     void select(const KGameDifficultyLevel *level);
0170 
0171 private:
0172     std::unique_ptr<class KGameDifficultyPrivate> const d_ptr;
0173     Q_DECLARE_PRIVATE(KGameDifficulty)
0174 };
0175 
0176 Q_DECLARE_METATYPE(const KGameDifficultyLevel *)
0177 
0178 class KXmlGuiWindow;
0179 
0180 /**
0181  * @namespace KGameDifficultyGUI
0182  *
0183  * The namespace for methods to integrate KGameDifficulty into the UI.
0184  *
0185  * @see KGameDifficulty
0186  */
0187 // TODO KDE5: move this into a separate QtWidgets support library
0188 namespace KGameDifficultyGUI
0189 {
0190 /// Install standard GUI components for the manipulation of the given
0191 /// KGameDifficulty instance in the given @a window.
0192 ///
0193 /// Without a second parameter, the KGameDifficulty::global() singleton is used.
0194 KDEGAMES_EXPORT void init(KXmlGuiWindow *window, KGameDifficulty *difficulty = nullptr);
0195 }
0196 
0197 #endif // KGAMEDIFFICULTY_H