~ubuntu-branches/ubuntu/precise/kdegames/precise

1.2.14 by Jonathan Riddell
Import upstream version 4.0.80
1
/*******************************************************************
2
 *
3
 * Copyright 2006 Dmitry Suzdalev <dimsuz@gmail.com>
4
 *
5
 * This file is part of the KDE project "KReversi"
6
 *
7
 * KReversi 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, or (at your option)
10
 * any later version.
11
 *
12
 * KReversi 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 KReversi; see the file COPYING.  If not, write to
19
 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20
 * Boston, MA 02110-1301, USA.
21
 *
22
 ********************************************************************/
23
#ifndef KREVERSI_GAME_H
24
#define KREVERSI_GAME_H
25
26
#include <QObject>
27
#include <QStack>
28
29
#include "commondefs.h"
30
31
class Engine;
32
33
namespace KGGZMod
34
{
35
    class Module;
36
}
37
38
class KGGZRaw;
39
40
/**
41
 *  KReversiGame incapsulates all of the game logic.
42
 *  Whenever the board state changes it emits corresponding signals.
43
 *  The idea is also to abstract from any graphic representation of the game process
44
 *
45
 *  KReversiGame is supposed to be driven by someone from outside.
46
 *  I.e. it receives commands and emits events when it's internal state changes
47
 *  due to this commands dispatching.
48
 *  The main commands are:
49
 *  startNextTurn() and  makePlayerMove()
50
 *
51
 *  See KReversiScene for example of working with KReversiGame
52
 */
53
class KReversiGame : public QObject
54
{
55
    Q_OBJECT
56
public:
57
    KReversiGame();
58
    ~KReversiGame();
59
    /**
60
     *  Starts next player turn.
61
     *  If game isn't over yet, then this function does the following:
62
     *  - if it is computer turn and computer can move, it'll make that move.
63
     *  - if it is computer turn and computer can't move it'll emit "computerCantMove"
64
     *  signal and exit
65
     *  - if it is player turn and player can move then this function
66
     *  will do nothing - you can call makePlayerMove(row,col) to make player move (but see last item)
67
     *  - if it is player turn and player can't move it'll make a computer move
68
     *  - in demo mode this function will make computer play player moves,
69
     *  so you don't need to call makePlayerMove.
70
     *
71
     *  If game is over it'll emit gameOver()
72
     *
73
     *  If it's still unclear how to use it please see KReversiScene for working example.
74
     *  In short: KReversiScene calls startNextTurn() at the end of each turn and makePlayerMove()
75
     *  in mouseReleaseEvent()
76
     *
77
     *  @param demoMode if true then computer will decide for player turn
78
     */
79
    void startNextTurn(bool demoMode);
80
    /**
81
     *  This will make the player move at row, col.
82
     *  If that is possible of course
83
     *  If demoMode is true, the computer will decide on what move to take.
84
     *  row and col values do not matter in that case.
85
     */
86
    void makePlayerMove(int row, int col, bool demoMode);
87
    /**
88
     *  This function will make computer decide where he
89
     *  wants to put his chip... and he'll put it there!
90
     */
91
    void makeComputerMove();
92
    /**
93
     *  Undoes all the computer moves and one player move
94
     *  (so after calling this function it will be player turn)
95
     *  @return number of undone moves
96
     */
97
    int undo();
98
    /**
99
     *  Sets the computer skill level. From 1 to 7
100
     */
101
    void setComputerSkill(int skill);
102
    /**
103
     * @return whether the game is currently computing turn
104
     */
105
    bool isThinking() const;
106
    /**
107
     *  @return whether the game is already over
108
     */
109
    bool isGameOver() const; // perhaps this doesn't need to be public
110
    /**
111
     *  @return whether any player move is at all possible
112
     */
113
    bool isAnyPlayerMovePossible() const;// perhaps this doesn't need to be public
114
    /**
115
     *  @return whether any computer move is at all possible
116
     */
117
    bool isAnyComputerMovePossible() const;// perhaps this doesn't need to be public
118
    /**
119
     *  @return a color of the current player
120
     */
121
    ChipColor currentPlayer() const { return m_curPlayer; }
122
123
    /**
124
     *  @return score (number of chips) of the player
125
     */
126
    int playerScore( ChipColor player ) const;
127
    /**
128
     *  @return color of the chip at position [row, col]
129
     */
130
    ChipColor chipColorAt( int row, int col ) const;
131
    /**
132
     *  @return if undo is possible
133
     */
134
    bool canUndo() const { return !m_undoStack.isEmpty(); }
135
    /**
136
     *  @return a hint to current player
137
     */
138
    KReversiPos getHint() const;
139
    /**
140
     *  @return last move made
141
     */
142
    KReversiPos getLastMove() const;
143
    /**
144
     *  @return true, if it's computer's turn now
145
     */
146
    bool isComputersTurn() const { return m_curPlayer == m_computerColor; }
147
    /**
148
     *  @return a list of chips which were changed during last move.
149
     *  First of them will be the move itself, and the rest - chips which
150
     *  were turned by that move
151
     */
152
    PosList changedChips() const { return m_changedChips; }
153
    /**
154
     *  @return a list of possible moves for current player
155
     */
156
    PosList possibleMoves() const;
157
signals:
158
    void gameOver();
159
    void boardChanged();
160
    void moveFinished();
161
    void computerCantMove();
162
    void playerCantMove();
163
    void networkError();
164
private slots:
165
    void networkData(int fd);
166
    void networkErrorHandler();
167
private:
168
    enum Direction { Up, Down, Right, Left, UpLeft, UpRight, DownLeft, DownRight };
169
    /**
170
     * This function will tell you if the move is possible.
171
     * That's why it was given such a name ;)
172
     */
173
    bool isMovePossible( const KReversiPos& move ) const;
174
    /**
175
     *  Searches for "chunk" in direction dir for move.
176
     *  As my English-skills are somewhat limited, let me introduce
177
     *  new terminology ;).
178
     *  I'll define a "chunk" of chips for color "C" as follows:
179
     *  (let "O" be the color of the opponent for color "C")
180
     *  CO[O]C <-- this is a chunk
181
     *  where [O] is one or more opponent's pieces
182
     */
183
    bool hasChunk( Direction dir, const KReversiPos& move) const;
184
    /**
185
     *  Performs move, i.e. marks all the chips that player wins with
186
     *  this move with current player color
187
     */
188
    void makeMove( const KReversiPos& move );
189
    /**
190
     *  Requests a move from the game server
191
     */
192
    void makeNetworkMove( int row, int col );
193
    /**
194
     *  Sets the type of chip at (row,col)
195
     */
196
    void setChipColor(ChipColor type, int row, int col);
197
    /**
198
     *  The board itself
199
     */
200
    ChipColor m_cells[8][8];
201
    /**
202
     *  Score of each player
203
     */
204
    int m_score[2];
205
    /**
206
     *  Color of the current player
207
     */
208
    ChipColor m_curPlayer;
209
    /**
210
     *  The color of the human played chips
211
     */
212
    ChipColor m_playerColor;
213
    /**
214
     *  The color of the computer played chips
215
     */
216
    ChipColor m_computerColor;
217
    /**
218
     *  Our AI
219
     */
220
    Engine *m_engine;
221
     // Well I'm not brief at all :). That's because I think that my
222
     // English is not well shaped sometimes, so I try to describe things
223
     // so that me and others can understand. Even simple things.
224
     // Specially when I think that my description sucks :)
225
    /**
226
     *  This list holds chips that were changed/added during last move
227
     *  First of them will be the chip added to the board by the player
228
     *  during last move. The rest of them - chips that were turned by that
229
     *  move.
230
     */
231
    PosList m_changedChips;
232
    /**
233
     *  This is an undo stack.
234
     *  It contains a lists of chips changed with each turn.
235
     *  @see m_changedChips
236
     */
237
    QStack<PosList> m_undoStack;
238
    /**
239
     *  Network connection to GGZ
240
     */
241
    KGGZMod::Module *m_mod;
242
    KGGZRaw *m_raw;
243
};
244
#endif