File indexing completed on 2024-05-12 05:46:46

0001 /*
0002 Copyright (c) 2007, Nicolas Roffet, <nicolas-kde@roffet.com>
0003 Copyright (c) 2007, Pino Toscano, <toscano.pino@tiscali.it>
0004 
0005 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
0006 
0007 This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for more details.
0008 
0009 You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
0010 */
0011 
0012 #ifndef KGAMEDIFFICULTY_H
0013 #define KGAMEDIFFICULTY_H
0014 
0015 
0016 
0017 class QObject;
0018 
0019 
0020 class KGameDifficultyPrivate;
0021 class KXmlGuiWindow;
0022 #include <QMap>
0023 #include <QPair>
0024 #include "libkdegamesprivate_export.h"
0025 
0026 
0027 
0028 /**
0029  * \class KGameDifficulty kgamedifficulty.h <KGameDifficulty>
0030  *
0031  * @brief KGameDifficuty manages the game difficulty levels in a standard way
0032  *
0033  * KGameDifficulty manages the difficulty levels of a game. The
0034  * difficulty can be a type of game (like in KMines: small field / big
0035  * field) or the AI skills (like in Bovo: how deep should the computer
0036  * search to find the best move) or a combination of both of them. On
0037  * the user point of view, it's not really different: either is the
0038  * game easy or hard to play.
0039  *
0040  * KGameDifficulty provides standard actions on the main menu and a
0041  * standard combo box in the status bar with the list of the
0042  * difficulty levels. They both use the standard icon for
0043  * "difficulty". Using KGameDifficulty instead of a custom
0044  * implementation is better to provide a uniform user experience over
0045  * all KDE games.
0046  *
0047  * It is possible to use standard difficulty levels (like "Easy",
0048  * "Hard", ...) or define custom ones ("My level!"...). Using standard
0049  * levels reduces the work of the translator teams and assures that
0050  * the translation (for instance of "Medium") will not be different in
0051  * different games (and it is better because it is uniform).  In some
0052  * games, it is no problem if the player changes the difficulty level
0053  * during a running game. In others, it is: the current game should be
0054  * given up and a new game should be started. In this case,
0055  * KGameDifficulty provides a confirmation dialog so the game
0056  * programmer does not have to manage this himself: he just has to
0057  * tell KGameDifficulty when the game is running and when not.
0058  *
0059  * Code example: definition of the difficulty levels in the main window class.
0060  * @code
0061  * KGameDifficulty::init(this, this, SLOT(levelChanged(KGameDifficulty::standardLevel)));
0062  * KGameDifficulty::addStandardLevel(KGameDifficulty::Easy);
0063  * KGameDifficulty::addStandardLevel(KGameDifficulty::Medium);
0064  * KGameDifficulty::addStandardLevel(KGameDifficulty::Hard);
0065  * KGameDifficulty::setRestartOnChange(KGameDifficulty::NoRestartOnChange);
0066  *
0067  * // The default level (it should be read from the config file).
0068  * KGameDifficulty::setLevel(KGameDifficulty::Medium);
0069  *
0070  * // And you also need to define the slot "levelChanged" to manage changes.
0071  * // ...
0072  * @endcode
0073  *
0074  * Note that this class is a singleton. So you can have only one current difficulty level per application.
0075  *
0076  * @author Nicolas Roffet, <nicolas-kde@roffet.com>
0077  */
0078 class KDEGAMESPRIVATE_EXPORT KGameDifficulty
0079 {
0080     public:
0081         /**
0082          * @brief Behavior on change
0083          *
0084          * Does the game have to be restarted, when the player changes the difficulty level? In this case and if the game is running, a confirmation dialog is displayed and the player can cancel the change.
0085          */
0086         enum onChange {
0087             RestartOnChange, /**< The current game has to be canceled and a new game will be started on change. */
0088             NoRestartOnChange /**< The current game can continue on change. */
0089         };
0090 
0091         /**
0092          * @brief Standard difficulty levels
0093          *
0094          * If they fit the needs of the game, the standard appellations of the difficulty levels should be used.
0095          */
0096         enum standardLevel {
0097             RidiculouslyEasy = 10, /**< Level "Ridiculously easy" */
0098             VeryEasy = 20, /**< Level "Very easy" */
0099             Easy = 30, /**< Level "Easy" */
0100             Medium = 40, /**< Level "Medium" */
0101             Hard = 50, /**< Level "Hard" */
0102             VeryHard = 60, /**< Level "Very hard" */
0103             ExtremelyHard = 70, /**< Level "Extremely hard" */
0104             Impossible = 80, /**< Level "Impossible"  */
0105             Configurable = 90, /**< Level "Custom". This is a special item to let the player configure the difficulty level. The configuration of the user level has to be implemented in each game using it with an adapted dialog. Example: In a minesweeper game like KMines, the player wants to define the number of rows, columns and mines. */
0106             Custom = 100, /**< Any custom appellations for levels */
0107             NoLevel = 110 /**< No level */
0108         };
0109 
0110 
0111         /**
0112          * @brief Destructor
0113          */
0114         virtual ~KGameDifficulty();
0115 
0116         /**
0117          * @brief Initialize the difficulty class
0118          *
0119          * You must call this class before using the singleton.
0120          *
0121          * @param window The window where to add menu items.
0122          * @param recvr Object that receives the signals and have the following slots.
0123          * @param slotStandard Slot to call when the player changed the difficulty level to a standard one. Slot should have the signature like: SLOT(levelChanged(KGameDifficulty::standardLevel))
0124          * @param slotCustom Slot to call when the player changed the difficulty level to a custom one. (Optional). Slot should have the signature like: SLOT(customLevelChanged(int))
0125          */
0126         static void init(KXmlGuiWindow* window, const QObject *recvr, const char* slotStandard, const char* slotCustom = nullptr);
0127 
0128         /**
0129          * @brief Set if a new game has to be started by change
0130          *
0131          * Default is RestartOnChange.
0132          * @param restart Behavior on change
0133          */
0134         static void setRestartOnChange(onChange restart);
0135 
0136         /**
0137          * @brief Add a standard difficulty level
0138          *
0139          * You should add all the standard difficulty levels you need after the initialization of the class.
0140          * Standard difficulty levels are displayed before custom levels (if available).
0141          * @param level Standard difficulty level to add
0142          */
0143         static void addStandardLevel(standardLevel level);
0144 
0145         /**
0146          * @brief Remove a standard difficulty level
0147          *
0148          * @param level Standard difficulty level to remove
0149          */
0150         static void removeStandardLevel(standardLevel level);
0151 
0152         /**
0153          * @brief Add a custom difficulty level
0154          *
0155          * If you need custom appellations like "8x8", "Coward", "Courageous", "Tired of life" or whatever, you can define them with this method.
0156          * Custom difficulty levels are displayed after standard levels (if available).
0157          * @param key Custom level identifier. (It must be distinct for every different level. Trying to add a new level with an allocated key replace the previous level.).
0158          * @param appellation Custom level appellation.
0159          */
0160         static void addCustomLevel(int key, const QString& appellation);
0161 
0162         /**
0163          * @brief Remove a custom difficulty level
0164          *
0165          * @param key Custom level identifier.
0166          */
0167         static void removeCustomLevel(int key);
0168 
0169         /**
0170          * @brief Set if the difficulty level may be changed.
0171          *
0172          * If not, all the actions are disabled.
0173          * Default is "true".
0174          * @param enabled State.
0175          */
0176         static void setEnabled(bool enabled);
0177 
0178         /**
0179          * @brief Set the new current difficulty level as a standard one
0180          *
0181          * @param level Standard level.
0182          */
0183         static void setLevel(standardLevel level);
0184 
0185         /**
0186          * @brief Get the current standard difficulty level
0187          *
0188          * @return The current standard level, or customLevel if a custom level is selected, or noLevel if no difficulty level is selected.
0189          */
0190         static standardLevel level();
0191                 /**
0192                  * @return current standard level string name
0193                  */
0194                 static QString levelString();
0195                 /**
0196                  * @return current standard level name translated string
0197                  */
0198                 static QPair<QByteArray, QString> localizedLevelString();
0199                 /**
0200                  * @return list of translated standard level string names
0201                  */
0202                 static QMap<QByteArray, QString> localizedLevelStrings();
0203                 /**
0204                  * @return map with the weight order of untranslated standard level names matches value of standardLevel enum
0205                  * @since KDE 4.2
0206                  */
0207                 static QMap<int, QByteArray> levelWeights();
0208         /**
0209          * @brief Set the new current difficulty level as a custom one
0210          *
0211          * This sets also the value of the standard level to "custom".
0212          * @param key Custom level identifier.
0213          */
0214         static void setLevelCustom(int key);
0215 
0216         /**
0217          * @brief Get the current custom difficulty level
0218          *
0219          * It does only make sense to get the current custom difficulty level, if the value of the level is "custom".
0220          * @return The current custom level identifier.
0221          */
0222         static int levelCustom();
0223 
0224         /**
0225          * @brief Set the game state: Running or not
0226          *
0227          * The game state should be defined if the current onChange value is restartByChange.
0228          * Default: false.
0229          * @param running Running state.
0230          */
0231         static void setRunning(bool running);
0232 
0233 
0234     private:
0235         /**
0236          * Private constructor: we are a singleton
0237          */
0238         KGameDifficulty();
0239         /**
0240          * @brief Access to the unique instance of the class
0241          *
0242          * Be aware to call init first.
0243          * @see init
0244          */
0245         static KGameDifficulty* self();
0246 
0247         static KGameDifficulty* instance;
0248         friend class KGameDifficultyPrivate;
0249         KGameDifficultyPrivate* const d;
0250 
0251         Q_DISABLE_COPY(KGameDifficulty)
0252 };
0253 
0254 #endif //KGAMEDIFFICULTY_H