File indexing completed on 2024-04-21 07:52:23

0001 /*
0002     SPDX-FileCopyrightText: 2008 Ian Wadham <iandw.au@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef GAME_H
0008 #define GAME_H
0009 
0010 // The Cube object uses the sqrt() function.
0011 #include <cmath>
0012 #include <cstdlib>
0013 
0014 // KDE includes
0015 #include <KGameStandardAction>  // Used only to get internal names of actions.
0016 
0017 // Qt includes
0018 #include <QObject>
0019 #include <QString>
0020 #include <QList>
0021 #include <QElapsedTimer>
0022 #include <QRandomGenerator>
0023 
0024 // Local includes.
0025 #include "kubrick.h"
0026 #include "gameglview.h"
0027 #include "gamedialog.h"
0028 #include "kbkglobal.h"
0029 #include "cube.h"
0030 
0031 class Kubrick;
0032 class GameView;     // Forward declaration of view.
0033 class GameGLView;   // Forward declaration of OpenGL painter and view.
0034 class MoveTracker;
0035 class SceneLabel;
0036 
0037 /** 
0038  * This is the main Kubrick game class.
0039  * All information about the game itself is stored here.
0040  */
0041 class Game : public QObject
0042 {
0043   Q_OBJECT
0044 
0045 public:
0046     /**
0047      * Constructor for the Kubrick game object.
0048      * @param parent    The parent widget, Kubrick, which inherits KMainWindow.
0049      */
0050     explicit Game (Kubrick * parent = nullptr);
0051 
0052     ~Game() override;
0053 
0054     /**
0055      * Further initialisation for the Kubrick game object, which is called back
0056      * by the main window (Kubrick) after the GUI and OpenGL have been set up.
0057      * @param glv   The OpenGL widget, used to draw 3d cubes.
0058      * @param mw    The main window widget (identical to "parent").
0059      */
0060     void initGame (GameGLView * glv, Kubrick * mw);
0061 
0062     /**
0063      * Procedure called back by GameGLView::paintGL() to compose the current
0064      * game scene, which in turn calls various GameGLView methods to build up
0065      * pictures of cubes in whatever states are determined by the game-play.
0066      */
0067     void drawScene ();
0068 
0069     void saveState ();
0070     void restoreState ();
0071 
0072     void loadDemo (const QString & file);
0073 
0074     void setSceneLabels ();
0075 
0076     /**
0077      * Procedure called back by GameGLView to handle mouse-button events, which
0078      * works out the cube-picture and sticker that the mouse is pointing to.
0079      */
0080     void handleMouseEvent (MouseEvent event, int button, int mX, int mY);
0081 
0082 public Q_SLOTS:
0083     void newPuzzle              (); // New puzzle (shuffle a similar cube).
0084     void undoAll                (); // Undo all player moves (restart).
0085 
0086     void load           ();
0087     void save           ();
0088     void saveAs         ();
0089 
0090     void changePuzzle           (const Kubrick::PuzzleItem & puzzle);
0091     void newCubeDialog();       // Run options dialog; build a new cube.
0092 
0093     void undoMove               (); // Undo the last move.
0094     void redoMove               (); // Redo an undone move.
0095     void toggleDemo     (); // Start/stop the demo.
0096     void solveCube              (); // Show solution (reverse all moves).
0097     void setStandardView    (); // Align to show R, F and U (top) faces.
0098 
0099     void redoAll                (); // Redo all undone moves.
0100 
0101     void changeScene    (const int);    // Change the scene (View Menu).
0102     void cycleSceneUp       (); // Cycle up through the scenes.
0103     void cycleSceneDown     (); // Cycle down through the scenes.
0104 
0105     void watchShuffling     (); // Set/clear viewShuffle option.
0106     void watchMoves     (); // Set/clear viewMoves option.
0107     void enableMessages     (); // Re-enable all "don't show" messages.
0108     void optionsDialog      (); // Open the dialog box for game options.
0109 
0110     // IDW - Key K for switching the background (temporary) - FIX IT FOR KDE 4.2
0111     void switchBackground       ();
0112 
0113     // Input for XYZ keyboard moves.
0114     void setMoveAxis        (int i);
0115     void setMoveSlice       (int slice);
0116     void setMoveDirection   (int direction);
0117 
0118     // Input for Singmaster keyboard moves, coded as a finite state machine.
0119     void smInput        (const int smCode);
0120 
0121 private:
0122     // Implementation of states and state changes for Singmaster moves.
0123     QString singmasterString;       // Moves that have been entered.
0124     int     smSelectionStart;       // Highlighting of last move executed.
0125     int     smSelectionLength;
0126     QString smTempString;       // A move that is being entered.
0127 
0128     int     smDotCount;
0129     enum    KeyboardStateCode
0130         {WaitingForInput, SingmasterPrefixSeen, SingmasterFaceIDSeen};
0131     KeyboardStateCode keyboardState;
0132 
0133     // The Singmaster move the player is entering or has just entered.
0134     Axis    smMoveAxis;
0135     int     smMoveSlice;
0136     Rotation smMoveDirection;
0137 
0138     // Display or re-display the Singmaster Moves.
0139     void smShowSingmasterMoves();
0140 
0141     // Check for an incomplete Singmaster move when there is another move to do.
0142     bool smMoveToComplete();
0143 
0144     // Initialise or re-initialise the move-text parsing.
0145     void smInitInput();
0146 
0147     // Processing of states for Singmaster moves.
0148     void smWaitingForInput  (const SingmasterMove smCode);
0149     void smSingmasterPrefixSeen (const SingmasterMove smCode);
0150     void smSingmasterFaceIDSeen (const SingmasterMove smCode);
0151 
0152     // Actions for Singmaster moves.
0153     void saveSingmasterFaceID   (const SingmasterMove smCode);
0154     void executeSingmasterMove  (const SingmasterMove smCode);
0155 
0156     QString convertMoveToSingmaster (const Move * move);
0157 
0158 private Q_SLOTS:
0159     /**
0160     * This slot implements a game tick.  It increases the game tick counter,
0161     * triggers the OpenGL rendering and manages sequences of animated moves.
0162     * It also performs moves that are not animated, all at once, depending
0163     * on the current settings of the "view" options.
0164     **/
0165     void advance                ();
0166 
0167     /**
0168     * This slot adds a player's move to the list.  It is invoked either after
0169     * keyboard input or by a newMove signal from the moveTracker object.
0170     **/
0171     void addPlayersMove         (Move * move);
0172 
0173     /**
0174     * This slot records the fact that the user has rotated the cube manually.
0175     **/
0176     void setCubeNotAligned      ();
0177 
0178 private:
0179     Kubrick *    myParent;  // Game's parent widget.
0180     Kubrick *    mainWindow;    // Main window: used for status, etc.
0181     GameGLView * gameGLView;    // OpenGL view: used to draw 3D cubes.
0182 
0183     QRandomGenerator random;    // Random number generator object.
0184     Cube *   cube;      // The cube that is in play.
0185     float    cubieSize;     // Size of each cubie in OpenGL co-ordinates.
0186     QList<CubeView *> cubeViews; // Parameters for views of 1-3 cubes.
0187 
0188     SceneLabel * demoL;     // Text to say "DEMO - Click anywhere ...".
0189     SceneLabel * frontVL;   // Text to say "Front View".
0190     SceneLabel * backVL;    // Text to say "Back View".
0191 
0192 /******************************************************************************/
0193 /**************** DATA THAT RECORDS THE STATE OF PLAY *************************/
0194 /******************************************************************************/
0195 
0196     QString saveFilename;   // Last filename used for Save or SaveAs.
0197     int     currentSceneID; // The set of CubeViews to be displayed.
0198     bool    tumbling;       // If true, cubes are tumbling around.
0199     bool    cubeAligned;    // If false, the user has rotated the cube.
0200 
0201     int tumblingTicks;      // The cumulative time tumbling has been on.  In
0202                 // effect, it records the cube's rotation state.
0203 
0204     int     cubeSize [nAxes];   // Size of each side of the cube (in cubies).
0205     int     nMax;       // Maximum side of the cube or brick.
0206 
0207     int     option [nOptions];  // Array of options set by GameDialog.
0208     bool    demoPhase;      // True while the demo is running.
0209     bool    viewShuffle;    // If true, animate (show) shuffling moves.
0210     bool    viewMoves;      // If true, animate (show) player's moves.
0211     int     moveSpeed;      // Degrees of turn per animation step.
0212 
0213     QList<Move *> moves;    // The list of moves (if any).
0214     int     shuffleMoves;   // The number of shuffle moves in the list.
0215     int     playerMoves;    // The number of player moves in the list.
0216     int     moveIndex;      // The index of the current move.
0217 
0218     // The move the player is selecting or has just selected.
0219     Axis    currentMoveAxis;
0220     int     currentMoveSlice;
0221     Rotation currentMoveDirection;
0222 
0223 /******************************************************************************/
0224 /************************* DATA TO CONTROL ANIMATION **************************/
0225 /******************************************************************************/
0226 
0227     QString displaySequence;    // Codes for sequences of moves to display.
0228                 // m = move, u = undo, r = redo, U = undo all
0229                 // (restart puzzle), R = redo all, h = shuffle,
0230                 // s = solve, d = demo, w = wait.
0231 
0232     long    nTick;      // Game-tick counter.
0233 
0234     enum    Mover {None, Mouse, Keyboard};
0235     Mover   moveFeedback;   // If != None, player is selecting a move.
0236 
0237     int     movesToDo;      // Number of moves to animate in next sequence.
0238     bool    undoing;        // If true, reverse the direction of each move.
0239     int     pauseTicks;     // Counter for a pause during animation.
0240 
0241     int     moveAngle;      // Degrees turned so far in an animated move.
0242     int     moveAngleStep;  // Degrees to be turned per animation step.
0243     int     moveAngleMax;   // Total degrees to turn in an animated move.
0244 
0245     long    blinkStartTime; // When to start showing feedback of a move.
0246     QElapsedTimer   time;
0247 
0248 /******************************************************************************/
0249 /***************************** MOUSE-CONTROL DATA *****************************/
0250 /******************************************************************************/
0251 
0252     MoveTracker * moveTracker;  // An object to track the pointer during moves.
0253 
0254 /******************************************************************************/
0255 /********************* METHODS TO SUPPORT GAME ACTIONS ************************/
0256 /******************************************************************************/
0257 
0258     // Save the current puzzle to a KDE config file.
0259     void    doSave     (bool getFilename);
0260     void    savePuzzle (KConfig & config);
0261 
0262     // Load a saved puzzle from a KDE config file.
0263     void    loadPuzzle (KConfig & config);
0264 
0265     void    setCubeView (int sceneID, bool rotates, float size,
0266         float relX, float relY,
0267         float turn, float tilt, int labelX, int labelY, LabelID label);
0268 
0269     void    setDefaults();  // Set default cube sizes and options.
0270     int     doOptionsDialog (bool changePuzzle); // Do dialog for game options.
0271     void    newCube     // Construct a new cube and display it.
0272         (int xDim, int yDim, int zDim, int shMoves);
0273     void    shuffleCube (); // Generate shuffling moves.
0274     int     pickANumber     // Pick a number at random,
0275         (int lo, int hi);   //     in the range (lo..hi).
0276 
0277     void    startUndo (const QString &code, const QString &header);
0278     void    startRedo (const QString &code, const QString &header);
0279 
0280 /******************************************************************************/
0281 /********************** METHODS TO SUPPORT ANIMATION  *************************/
0282 /******************************************************************************/
0283 
0284     void    appendMove (Move * move);
0285     void    forceImmediateMove (Axis axis, int slice, Rotation direction);
0286     void    forceImmediateMove (Move * move);
0287     void    truncateUndoneMoves(); // Delete all undone and not-redone moves.
0288 
0289     void    startAnimation (const QString &dSeq, int sID, bool vShuffle, bool vMoves);
0290 
0291     void    startNextDisplay(); // Start executing a step from displaySequence.
0292     void    startDemo();    // Start the demo sequence.
0293     void    randomDemo();   // Generate a random demo.
0294     void    stopDemo();     // Stop the demo sequence.
0295     void    chooseMousePointer(); // Set cross or stopwatch (wait) cursor.
0296     bool    tooBusy();      // Blocks menus, keyboard and mouse during
0297                 // animated displays of moves, etc.
0298 
0299     void    startBlinking ();   // Blink a slice that has been selected to move.
0300 
0301     void    startMoves      // Start showing a sequence of moves.
0302         (int nMoves, int index, bool pUndo, int speed);
0303     void    startAnimatedMove   // Start showing a slice of the cube in motion.
0304             (Move * move, int speed);
0305     void    startNextMove   // Initiate the next move in a sequence.
0306         (int speed);
0307 
0308     void    tumble();       // Tumble the cubes around if tumbling = true.
0309 
0310 /******************************************************************************/
0311 /********************** METHODS TO SUPPORT THE MOUSE  *************************/
0312 /******************************************************************************/
0313 
0314 };
0315 
0316 #endif  // GAME_H