1 | /******************************************************************* |
2 | * |
3 | * Copyright 2006 Dmitry Suzdalev <dimsuz@gmail.com> |
4 | * Copyright 2013 Denis Kuplaykov <dener.kup@gmail.com> |
5 | * |
6 | * This file is part of the KDE project "KReversi" |
7 | * |
8 | * KReversi is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2, or (at your option) |
11 | * any later version. |
12 | * |
13 | * KReversi is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU General Public License |
19 | * along with KReversi; see the file COPYING. If not, write to |
20 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
21 | * Boston, MA 02110-1301, USA. |
22 | * |
23 | ********************************************************************/ |
24 | #ifndef KREVERSI_GAME_H |
25 | #define KREVERSI_GAME_H |
26 | |
27 | #include <QObject> |
28 | #include <QStack> |
29 | #include <QTimer> |
30 | |
31 | #include <Engine.h> |
32 | class Engine; |
33 | #include <commondefs.h> |
34 | #include <kreversiplayer.h> |
35 | class KReversiPlayer; |
36 | |
37 | /** |
38 | * KReversiGame incapsulates all of the game logic. |
39 | * Whenever the board state changes it emits corresponding signals. |
40 | * The idea is also to abstract from any graphic representation of the game |
41 | * process |
42 | * |
43 | * KReversiGame receives signals from KReversiPlayer classes. |
44 | * I.e. it receives commands and emits events when it's internal state changes |
45 | * due to this commands dispatching. |
46 | * |
47 | * See KReversiView, KReversiPlayer, KReversiHumanPlayer |
48 | * and KReversiComputerPlayer for example of working with KReversiGame |
49 | * |
50 | * @see KReversiView, KReversiPlayer, KReversiHumanPlayer |
51 | */ |
52 | class KReversiGame : public QObject |
53 | { |
54 | Q_OBJECT |
55 | public: |
56 | /** |
57 | * Constructs game with two specified players. |
58 | */ |
59 | KReversiGame(KReversiPlayer *blackPlayer, KReversiPlayer *whitePlayer); |
60 | ~KReversiGame(); |
61 | /** |
62 | * @return if undo is possible |
63 | */ |
64 | bool canUndo() const; |
65 | /** |
66 | * Undoes all the opponent of current player moves and one his move |
67 | * (so after calling this function it will be still current player turn) |
68 | * @return number of undone moves |
69 | */ |
70 | int undo(); |
71 | /** |
72 | * @return score (number of chips) of the @p player |
73 | */ |
74 | int playerScore(ChipColor player) const; |
75 | /** |
76 | * @return color of the chip at position @p pos |
77 | */ |
78 | ChipColor chipColorAt(KReversiPos pos) const; |
79 | /** |
80 | * @return a hint to current player |
81 | */ |
82 | KReversiMove getHint() const; |
83 | /** |
84 | * @return last move made |
85 | */ |
86 | KReversiMove getLastMove() const; |
87 | /** |
88 | * @return a list of chips which were changed during last move. |
89 | * First of them will be the move itself, and the rest - chips which |
90 | * were turned by that move |
91 | */ |
92 | MoveList changedChips() const { |
93 | return m_changedChips; |
94 | } |
95 | /** |
96 | * @return a list of possible moves for current player |
97 | */ |
98 | MoveList possibleMoves() const; |
99 | /** |
100 | * @return whether the game is already over |
101 | */ |
102 | bool isGameOver() const; |
103 | /** |
104 | * @return whether any player move is at all possible |
105 | */ |
106 | bool isAnyPlayerMovePossible(ChipColor player) const; |
107 | /** |
108 | * @return a color of the current player |
109 | */ |
110 | ChipColor currentPlayer() const { |
111 | return m_curPlayer; |
112 | } |
113 | /** |
114 | * Sets animation times from players to @p delay milliseconds |
115 | */ |
116 | void setDelay(int delay); |
117 | /** |
118 | * Get wait time for given cell before animating. Used for sequental turning of chips |
119 | */ |
120 | int getPreAnimationDelay(KReversiPos pos) const; |
121 | /** |
122 | * @return History of moves as MoveList |
123 | */ |
124 | MoveList getHistory() const; |
125 | |
126 | /** |
127 | * @return Is hint allowed for current player |
128 | */ |
129 | bool isHintAllowed() const; |
130 | private slots: |
131 | /** |
132 | * Starts next player's turn. |
133 | */ |
134 | void startNextTurn(); |
135 | /** |
136 | * Slot used to handle moves from black player |
137 | * @param move Move of black player |
138 | */ |
139 | void blackPlayerMove(KReversiMove move); |
140 | /** |
141 | * Slot used to handle moves from white player |
142 | * @param move Move of white player |
143 | */ |
144 | void whitePlayerMove(KReversiMove move); |
145 | /** |
146 | * Slot to handle end of animations with m_delayTimer |
147 | */ |
148 | void onDelayTimer(); |
149 | /** |
150 | * Slot to handle ready-status of black player |
151 | */ |
152 | void blackReady(); |
153 | /** |
154 | * Slot to handle ready-status of white player |
155 | */ |
156 | void whiteReady(); |
157 | |
158 | signals: |
159 | void gameOver(); |
160 | void boardChanged(); |
161 | void moveFinished(); |
162 | void whitePlayerCantMove(); |
163 | void blackPlayerCantMove(); |
164 | void whitePlayerTurn(); |
165 | void blackPlayerTurn(); |
166 | private: |
167 | // predefined direction arrays for easy implementation |
168 | static const int DIRECTIONS_COUNT = 8; |
169 | static const int DX[]; |
170 | static const int DY[]; |
171 | /** |
172 | * Used to make player think about his move again after unpossible move |
173 | */ |
174 | void kickCurrentPlayer(); |
175 | /** |
176 | * This will make the player @p move |
177 | * If that is possible, of course |
178 | */ |
179 | void makeMove(const KReversiMove &move); |
180 | /** |
181 | * This function will tell you if the move is possible. |
182 | */ |
183 | bool isMovePossible(const KReversiMove &move) const; |
184 | /** |
185 | * Searches for "chunk" in direction @p dirNum for @p move. |
186 | * As my English-skills are somewhat limited, let me introduce |
187 | * new terminology ;). |
188 | * I'll define a "chunk" of chips for color "C" as follows: |
189 | * (let "O" be the color of the opponent for color "C") |
190 | * CO[O]C <-- this is a chunk |
191 | * where [O] is one or more opponent's pieces |
192 | */ |
193 | bool hasChunk(int dirNum, const KReversiMove &move) const; |
194 | /** |
195 | * Performs @p move, i.e. marks all the chips that player wins with |
196 | * this move with current player color |
197 | */ |
198 | void turnChips(const KReversiMove &move); |
199 | /** |
200 | * Sets the type of chip according to @p move |
201 | */ |
202 | void setChipColor(const KReversiMove &move); |
203 | /** |
204 | * Delay time |
205 | */ |
206 | int m_delay; |
207 | /** |
208 | * Status flags used to know when both players are ready |
209 | */ |
210 | bool m_isReady[2]; |
211 | /** |
212 | * Last player who has made a move. Cannot be NoColor after the first move |
213 | */ |
214 | ChipColor m_lastPlayer; |
215 | /** |
216 | * The board itself |
217 | */ |
218 | ChipColor m_cells[8][8]; |
219 | /** |
220 | * Score of each player |
221 | */ |
222 | int m_score[2]; |
223 | /** |
224 | * AI to give hints |
225 | */ |
226 | Engine *m_engine; |
227 | /** |
228 | * Color of the current player. |
229 | * @c NoColor if it is interchange for animations |
230 | */ |
231 | ChipColor m_curPlayer; |
232 | /** |
233 | * This list holds chips that were changed/added during last move |
234 | * First of them will be the chip added to the board by the player |
235 | * during last move. The rest of them - chips that were turned by that |
236 | * move. |
237 | */ |
238 | MoveList m_changedChips; |
239 | /** |
240 | * This is an undo stack. |
241 | * It contains a lists of chips changed with each turn. |
242 | * @see m_changedChips |
243 | */ |
244 | QStack<MoveList> m_undoStack; |
245 | /** |
246 | * Used to handle end of player's animations or other stuff |
247 | */ |
248 | QTimer m_delayTimer; |
249 | |
250 | /** |
251 | * Actual players, who play the game |
252 | */ |
253 | KReversiPlayer *m_player[2]; |
254 | }; |
255 | #endif |
256 | |