1 | /* **************************************************************************** |
2 | This file is part of the game 'KJumpingCube' |
3 | |
4 | Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de> |
5 | Copyright (C) 2012-2013 by Ian Wadham <iandw.au@gmail.com> |
6 | |
7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. |
11 | |
12 | This program is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | GNU General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with this program; if not, write to the Free Software Foundation, Inc., |
19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
20 | **************************************************************************** */ |
21 | #ifndef GAME_H |
22 | #define GAME_H |
23 | |
24 | #include "ai_globals.h" |
25 | |
26 | #include <QTime> // IDW test. |
27 | |
28 | #include <KUrl> |
29 | #include <QList> |
30 | |
31 | class KConfigGroup; |
32 | class KCubeBoxWidget; |
33 | class SettingsWidget; |
34 | class AI_Main; |
35 | class AI_Box; |
36 | class QTimer; |
37 | |
38 | /** |
39 | * Codes for actions available to users of the Game class. |
40 | */ |
41 | enum Action {NEW, HINT, BUTTON, UNDO, REDO, SAVE, SAVE_AS, LOAD}; |
42 | |
43 | class Game : public QObject |
44 | { |
45 | Q_OBJECT |
46 | public: |
47 | explicit Game (const int dim, KCubeBoxWidget * view, QWidget * parent = 0); |
48 | |
49 | virtual ~Game(); |
50 | |
51 | /** |
52 | * Make sure all animation and AI activity is over before closing a game. |
53 | * */ |
54 | void shutdown(); |
55 | |
56 | public slots: |
57 | |
58 | /** |
59 | * Perform one of the game-actions listed in enum type Action. |
60 | * |
61 | * @param action The action to be performed, taken from enum Action. |
62 | * This parameter must be of type int because KJumpingCube |
63 | * invokes gameActions() via a QSignalMapper of int type. |
64 | */ |
65 | void gameActions (const int action); |
66 | |
67 | private: |
68 | /** |
69 | * Show the winner when the game ends, either after a move or a redo. |
70 | */ |
71 | void showWinner(); |
72 | |
73 | private slots: |
74 | /** |
75 | * Pop up the settings/preferences/configuration dialog window. |
76 | */ |
77 | void showSettingsDialog (bool show = true); |
78 | |
79 | /** |
80 | * Check changes in the user's preferences or settings. Some settings can |
81 | * be used immediately, some must wait until the start of the next turn and |
82 | * a change in box size may require the user's OK (or not) to abandon a game |
83 | * in progress and start a new game. |
84 | */ |
85 | void newSettings(); |
86 | |
87 | /** |
88 | * Check if cube at [x, y] is available to the current (human) player. |
89 | * If it is, make a move using doMove() and the cube at [x, y], animating |
90 | * the move, if required. |
91 | */ |
92 | void startHumanMove (int x, int y); |
93 | |
94 | private: |
95 | /** |
96 | * Check if the current player is a computer player and, if so, start the |
97 | * next move or perhaps wait for the user to click the button to show that |
98 | * he or she is ready. Otherwise, wait for a human player to move. |
99 | */ |
100 | void setUpNextTurn(); |
101 | |
102 | /** |
103 | * Starts calculating a computer move or hint (using asynchronous AI thread). |
104 | */ |
105 | void computeMove(); |
106 | |
107 | private slots: |
108 | /** |
109 | * Deliver a computer-move or hint calculated by the AI thread and start an |
110 | * animation to show which cube is to move. |
111 | * |
112 | * @param index The position of the move in the array of cubes. If the box |
113 | * has n x n cubes, index = x * n + y for co-ordinates [x, y]. |
114 | */ |
115 | void moveCalculationDone (int index); |
116 | |
117 | private: |
118 | /** |
119 | * Finish showing a computer move or hint. If it is a computer move, use |
120 | * doMove() to make the actual move and animate it, if required. |
121 | */ |
122 | void showingDone (int index); |
123 | |
124 | /** |
125 | * Increase the cube at 'index' and start the animation loop, if required. |
126 | */ |
127 | void doMove (int index); |
128 | |
129 | /** |
130 | * Perform and display one or more steps of a move, with breaks for animation |
131 | * if required, finishing when all steps have been done or the current player |
132 | * has won the game. If there is no animation or if the user clicks the |
133 | * action button to interrupt the animation, perform all steps at full speed. |
134 | */ |
135 | void doStep(); |
136 | |
137 | /** |
138 | * Finish one step of a move, if animating, and use doStep() to continue. |
139 | */ |
140 | void stepAnimationDone (int index); |
141 | |
142 | /** |
143 | * Finish an entire move. |
144 | */ |
145 | void moveDone(); |
146 | |
147 | /** |
148 | * Switch to the other player, human or computer, after a non-winning move. |
149 | */ |
150 | Player changePlayer(); |
151 | |
152 | /** |
153 | * Initiate or interrupt computer-move or animation activities. This is used |
154 | * when the computer is first to move or when the user wishes to interrupt |
155 | * or step through moves, as in a computer v. computer game or a complex |
156 | * series of cascade moves. |
157 | */ |
158 | void buttonClick(); |
159 | |
160 | /** |
161 | * Set the action-button to be red, enabled and with text relevant to |
162 | * stopping the current activity (AI v AI game OR computing, showing or |
163 | * animating a move). |
164 | */ |
165 | void setStopAction(); |
166 | |
167 | /** |
168 | * Act on changes in settings that can be used immediately. Color changes |
169 | * can take effect when control returns to the event loop, the other settings |
170 | * next time they are used. They include animation settings, AI players and |
171 | * their skill levels. |
172 | */ |
173 | void loadImmediateSettings(); |
174 | |
175 | /** |
176 | * Act on changes in the user's choice of players and computer-player pause. |
177 | * These can take effect only at the start of a turn. |
178 | */ |
179 | void loadPlayerSettings(); |
180 | |
181 | private slots: |
182 | /** |
183 | * Indicate that showing a move or animating a move-step has finished. |
184 | * |
185 | * @param index The position of the move in the array of cubes. If the box |
186 | * has n x n cubes, index = x * n + y for co-ordinates [x, y]. |
187 | */ |
188 | void animationDone (int index); |
189 | |
190 | signals: |
191 | /** |
192 | * Request that the current player be shown in the KJumpingCube main window. |
193 | * |
194 | * @param player The ID of the player (= 1 or 2). |
195 | */ |
196 | void playerChanged (int newPlayer); |
197 | |
198 | /** |
199 | * Request a change of appearance or text of the general-purpose action |
200 | * button in the KJumpingCube main window. |
201 | * |
202 | * @param enabled True = button is active, false = button is inactive. |
203 | * @param stop If active, true = use STOP style, false = use GO style. |
204 | * @param caption Translated text to appear on the button. |
205 | */ |
206 | void buttonChange (bool enabled, bool stop = false, |
207 | const QString & caption = QString("" )); |
208 | |
209 | /** |
210 | * Request enabling or disabling of an action by KJumpingCube main window. |
211 | * |
212 | * @param a The game-action to be enabled or disabled. |
213 | * @param onOff True = enable the action, false = disable it. |
214 | */ |
215 | void setAction (const Action a, const bool onOff); |
216 | |
217 | /** |
218 | * Request display of a status message. |
219 | * |
220 | * @param message The message to be displayed (translated). |
221 | * @param timed If true, display the message for a limited time. |
222 | */ |
223 | void statusMessage (const QString & message, bool timed); |
224 | |
225 | protected: |
226 | void saveProperties(KConfigGroup&); |
227 | void readProperties(const KConfigGroup&); |
228 | |
229 | private: |
230 | void loadSavedSettings (const KConfigGroup& config); |
231 | |
232 | private: |
233 | QTime t; // IDW test. |
234 | |
235 | enum Activity {Idle, Computing, Stopping, Aborting, |
236 | ShowingMove, AnimatingMove}; |
237 | enum WaitingState {Nil, WaitingToStep, ComputerToMove}; |
238 | |
239 | Activity m_activity; // Current computer activity. |
240 | WaitingState m_waitingState; // Current pause state. |
241 | bool m_waitingToMove; // If true, AI paused or human to move. |
242 | int m_moveNo; // Current move number, 0 = not started. |
243 | int m_endMoveNo; // Winning move number, if game is over. |
244 | bool m_interrupting; // If user has interrupted AI v. AI. |
245 | bool m_newSettings; // If new player settings during a move. |
246 | |
247 | QWidget * m_parent; // Game object's parent (main window). |
248 | KCubeBoxWidget * m_view; // Displayed cubes. |
249 | |
250 | // A pointer to the Settings widget defined in Qt Designer, when the |
251 | // Preferences dialog is first created by Game::showSettingsDialog(). |
252 | SettingsWidget * m_settingsPage; // Displayed settings, 0 = not yet used. |
253 | |
254 | AI_Box * m_box; // Game engine's cubes. |
255 | int m_side; // Cube box size, from Prefs::cubeDim(). |
256 | Player m_currentPlayer; // Current player: One or Two. |
257 | QList<int> * m_steps; // Steps in a move to be displayed. |
258 | |
259 | AI_Main * m_ai; // Current computer player. |
260 | |
261 | int m_index; // Location of move. |
262 | bool m_fullSpeed; // If true, no animation of moves. |
263 | |
264 | bool computerPlOne; // If true, Player 1 is an AI. |
265 | bool computerPlTwo; // If true, Player 2 is an AI. |
266 | |
267 | bool m_pauseForComputer; // If true, pause before each AI move. |
268 | bool m_pauseForStep; // If true, pause before animation step. |
269 | |
270 | KUrl m_gameURL; // Location of load/save file. |
271 | |
272 | private slots: |
273 | void newGame(); // Slot needed for queued invocation. |
274 | |
275 | private: |
276 | void saveGame (bool saveAs); // Standard save-game action. |
277 | void loadGame(); // Standard load-game action. |
278 | void undo(); // Standard undo-move action. |
279 | void redo(); // Standard redo-move action. |
280 | |
281 | /** |
282 | * Check if it is OK to start a new game, maybe ending a current game. |
283 | */ |
284 | bool newGameOK(); |
285 | |
286 | /** |
287 | * Reset cubebox for a new game. |
288 | */ |
289 | void reset(); |
290 | |
291 | /** |
292 | * Undo or redo a move. |
293 | * |
294 | * @param change -1 = undo, +1 = redo |
295 | * |
296 | * @return true = More moves to undo/redo, false = No more to undo/redo. |
297 | */ |
298 | bool undoRedo (int change); |
299 | |
300 | /** |
301 | * Set the number of cubes in a row or column. If the number has changed, |
302 | * delete the existing set of cubes and create a new one. |
303 | */ |
304 | virtual void setDim (int dim); |
305 | |
306 | /** |
307 | * Returns true if the player is a computer player. |
308 | */ |
309 | bool isComputer (Player player) const; |
310 | |
311 | inline void restoreGame(const KConfigGroup&c) { readProperties(c); } |
312 | }; |
313 | |
314 | #endif // GAME_H |
315 | |