File indexing completed on 2024-05-19 04:04:54
0001 /* 0002 This file is part of the game 'KJumpingCube' 0003 0004 SPDX-FileCopyrightText: 1998-2000 Matthias Kiefer <matthias.kiefer@gmx.de> 0005 SPDX-FileCopyrightText: 2012-2013 Ian Wadham <iandw.au@gmail.com> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #ifndef GAME_H 0011 #define GAME_H 0012 0013 #include "ai_globals.h" 0014 0015 #include <QObject> 0016 #include <QTime> // IDW test. 0017 0018 #include <QUrl> 0019 #include <QList> 0020 0021 class KConfigGroup; 0022 class KCubeBoxWidget; 0023 class SettingsWidget; 0024 class AI_Main; 0025 class AI_Box; 0026 0027 /** 0028 * Codes for actions available to users of the Game class. 0029 */ 0030 enum Action {NEW, HINT, BUTTON, UNDO, REDO, SAVE, SAVE_AS, LOAD}; 0031 0032 class Game : public QObject 0033 { 0034 Q_OBJECT 0035 friend class KJumpingCube; 0036 0037 public: 0038 explicit Game (const int dim, KCubeBoxWidget * view, QWidget * parent = nullptr); 0039 0040 ~Game() override; 0041 0042 /** 0043 * Make sure all animation and AI activity is over before closing a game. 0044 * */ 0045 void shutdown(); 0046 0047 public Q_SLOTS: 0048 0049 /** 0050 * Perform one of the game-actions listed in enum type Action. 0051 * 0052 * @param action The action to be performed, taken from enum Action. 0053 * This parameter must be of type int because KJumpingCube 0054 * invokes gameActions() via a QSignalMapper of int type. 0055 */ 0056 void gameActions (const int action); 0057 0058 private: 0059 /** 0060 * Show the winner when the game ends, either after a move or a redo. 0061 */ 0062 void showWinner(); 0063 0064 private Q_SLOTS: 0065 /** 0066 * Pop up the settings/preferences/configuration dialog window. 0067 */ 0068 void showSettingsDialog (bool show = true); 0069 0070 /** 0071 * Check changes in the user's preferences or settings. Some settings can 0072 * be used immediately, some must wait until the start of the next turn and 0073 * a change in box size may require the user's OK (or not) to abandon a game 0074 * in progress and start a new game. 0075 */ 0076 void newSettings(); 0077 0078 /** 0079 * Check if cube at [x, y] is available to the current (human) player. 0080 * If it is, make a move using doMove() and the cube at [x, y], animating 0081 * the move, if required. 0082 */ 0083 void startHumanMove (int x, int y); 0084 0085 private: 0086 /** 0087 * Check if the current player is a computer player and, if so, start the 0088 * next move or perhaps wait for the user to click the button to show that 0089 * he or she is ready. Otherwise, wait for a human player to move. 0090 */ 0091 void setUpNextTurn(); 0092 0093 /** 0094 * Starts calculating a computer move or hint (using asynchronous AI thread). 0095 */ 0096 void computeMove(); 0097 0098 private Q_SLOTS: 0099 /** 0100 * Deliver a computer-move or hint calculated by the AI thread and start an 0101 * animation to show which cube is to move. 0102 * 0103 * @param index The position of the move in the array of cubes. If the box 0104 * has n x n cubes, index = x * n + y for co-ordinates [x, y]. 0105 */ 0106 void moveCalculationDone (int index); 0107 0108 private: 0109 /** 0110 * Finish showing a computer move or hint. If it is a computer move, use 0111 * doMove() to make the actual move and animate it, if required. 0112 */ 0113 void showingDone (int index); 0114 0115 /** 0116 * Increase the cube at 'index' and start the animation loop, if required. 0117 */ 0118 void doMove (int index); 0119 0120 /** 0121 * Perform and display one or more steps of a move, with breaks for animation 0122 * if required, finishing when all steps have been done or the current player 0123 * has won the game. If there is no animation or if the user clicks the 0124 * action button to interrupt the animation, perform all steps at full speed. 0125 */ 0126 void doStep(); 0127 0128 /** 0129 * Finish one step of a move, if animating, and use doStep() to continue. 0130 */ 0131 void stepAnimationDone (int index); 0132 0133 /** 0134 * Finish an entire move. 0135 */ 0136 void moveDone(); 0137 0138 /** 0139 * Switch to the other player, human or computer, after a non-winning move. 0140 */ 0141 Player changePlayer(); 0142 0143 /** 0144 * Initiate or interrupt computer-move or animation activities. This is used 0145 * when the computer is first to move or when the user wishes to interrupt 0146 * or step through moves, as in a computer v. computer game or a complex 0147 * series of cascade moves. 0148 */ 0149 void buttonClick(); 0150 0151 /** 0152 * Set the action-button to be red, enabled and with text relevant to 0153 * stopping the current activity (AI v AI game OR computing, showing or 0154 * animating a move). 0155 */ 0156 void setStopAction(); 0157 0158 /** 0159 * Act on changes in settings that can be used immediately. Color changes 0160 * can take effect when control returns to the event loop, the other settings 0161 * next time they are used. They include animation settings, AI players and 0162 * their skill levels. 0163 */ 0164 void loadImmediateSettings(); 0165 0166 /** 0167 * Act on changes in the user's choice of players and computer-player pause. 0168 * These can take effect only at the start of a turn. 0169 */ 0170 void loadPlayerSettings(); 0171 0172 private Q_SLOTS: 0173 /** 0174 * Indicate that showing a move or animating a move-step has finished. 0175 * 0176 * @param index The position of the move in the array of cubes. If the box 0177 * has n x n cubes, index = x * n + y for co-ordinates [x, y]. 0178 */ 0179 void animationDone (int index); 0180 0181 Q_SIGNALS: 0182 /** 0183 * Request that the current player be shown in the KJumpingCube main window. 0184 * 0185 * @param player The ID of the player (= 1 or 2). 0186 */ 0187 void playerChanged (int newPlayer); 0188 0189 /** 0190 * Request a change of appearance or text of the general-purpose action 0191 * button in the KJumpingCube main window. 0192 * 0193 * @param enabled True = button is active, false = button is inactive. 0194 * @param stop If active, true = use STOP style, false = use GO style. 0195 * @param caption Translated text to appear on the button. 0196 */ 0197 void buttonChange (bool enabled, bool stop = false, 0198 const QString & caption = QLatin1String("")); 0199 0200 /** 0201 * Request enabling or disabling of an action by KJumpingCube main window. 0202 * 0203 * @param a The game-action to be enabled or disabled. 0204 * @param onOff True = enable the action, false = disable it. 0205 */ 0206 void setAction (const Action a, const bool onOff); 0207 0208 /** 0209 * Request display of a status message. 0210 * 0211 * @param message The message to be displayed (translated). 0212 * @param timed If true, display the message for a limited time. 0213 */ 0214 void statusMessage (const QString & message, bool timed); 0215 0216 protected: 0217 void saveProperties(KConfigGroup&); 0218 void readProperties(const KConfigGroup&); 0219 0220 private: 0221 void loadSavedSettings (const KConfigGroup& config); 0222 0223 private: 0224 QTime t; // IDW test. 0225 0226 enum Activity {Idle, Computing, Stopping, Aborting, 0227 ShowingMove, AnimatingMove}; 0228 enum WaitingState {Nil, WaitingToStep, ComputerToMove}; 0229 0230 Activity m_activity; // Current computer activity. 0231 WaitingState m_waitingState; // Current pause state. 0232 bool m_waitingToMove; // If true, AI paused or human to move. 0233 int m_moveNo; // Current move number, 0 = not started. 0234 int m_endMoveNo; // Winning move number, if game is over. 0235 bool m_interrupting; // If user has interrupted AI v. AI. 0236 bool m_newSettings; // If new player settings during a move. 0237 0238 QWidget * m_parent; // Game object's parent (main window). 0239 KCubeBoxWidget * m_view; // Displayed cubes. 0240 0241 // A pointer to the Settings widget defined in Qt Designer, when the 0242 // Preferences dialog is first created by Game::showSettingsDialog(). 0243 SettingsWidget * m_settingsPage; // Displayed settings, 0 = not yet used. 0244 0245 AI_Box * m_box; // Game engine's cubes. 0246 int m_side; // Cube box size, from Prefs::cubeDim(). 0247 Player m_currentPlayer; // Current player: One or Two. 0248 QList<int> * m_steps; // Steps in a move to be displayed. 0249 0250 AI_Main * m_ai; // Current computer player. 0251 0252 int m_index; // Location of move. 0253 bool m_fullSpeed; // If true, no animation of moves. 0254 0255 bool computerPlOne; // If true, Player 1 is an AI. 0256 bool computerPlTwo; // If true, Player 2 is an AI. 0257 0258 bool m_pauseForComputer; // If true, pause before each AI move. 0259 bool m_pauseForStep; // If true, pause before animation step. 0260 0261 QUrl m_gameURL; // Location of load/save file. 0262 0263 private Q_SLOTS: 0264 void newGame(); // Slot needed for queued invocation. 0265 0266 private: 0267 void saveGame (bool saveAs); // Standard save-game action. 0268 void loadGame(); // Standard load-game action. 0269 void undo(); // Standard undo-move action. 0270 void redo(); // Standard redo-move action. 0271 0272 /** 0273 * Check if it is OK to start a new game, maybe ending a current game. 0274 */ 0275 bool newGameOK(); 0276 0277 /** 0278 * Reset cubebox for a new game. 0279 */ 0280 void reset(); 0281 0282 /** 0283 * Undo or redo a move. 0284 * 0285 * @param change -1 = undo, +1 = redo 0286 * 0287 * @return true = More moves to undo/redo, false = No more to undo/redo. 0288 */ 0289 bool undoRedo (int change); 0290 0291 /** 0292 * Set the number of cubes in a row or column. If the number has changed, 0293 * delete the existing set of cubes and create a new one. 0294 */ 0295 virtual void setDim (int dim); 0296 0297 /** 0298 * Returns true if the player is a computer player. 0299 */ 0300 bool isComputer (Player player) const; 0301 0302 inline void restoreGame(const KConfigGroup&c) { readProperties(c); } 0303 }; 0304 0305 #endif // GAME_H