1/*
2 * Copyright (c) 2010 Ni Hui <shuizhuyuanluo@126.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19#ifndef GAMESCENE_H
20#define GAMESCENE_H
21
22#include <QGraphicsScene>
23#include <QUndoStack>
24#include <QVector>
25#include <KGameRenderer>
26
27class QSequentialAnimationGroup;
28class KConfigGroup;
29class KGamePopupItem;
30class Piece;
31/**
32 * This class represents the game field scene.
33 * It handles the most important game logic and rendering.
34 */
35class GameScene : public QGraphicsScene
36{
37 Q_OBJECT
38 public:
39 /** Constructor */
40 explicit GameScene( QObject* parent = 0 );
41 /** Destructor */
42 ~GameScene();
43 /** Start a new game with custom size, color count and game id */
44 void startNewGame( int pwc = 10, int phc = 16, int colorCount = 5, int gameId = qrand() );
45 /** Load a game from config */
46 void loadGame( const KConfigGroup& config );
47 /** Save the current game to config */
48 void saveGame( KConfigGroup& config ) const;
49 /** Restart the current game, all the undo/redo history will be lost */
50 void restartGame();
51 /** Pause/Unpause the current game */
52 void setPaused( bool isPaused );
53 /** @return whether the current game has been finished */
54 bool isGameFinished() const;
55 /** Change the background type */
56 void setBackgroundType( int type );
57 /** Determine whether to show the bound lines between different colors */
58 void setShowBoundLines( bool isShowing );
59 /** Determine whether to enable the animation when removing pieces */
60 void setEnableAnimation( bool isEnabled );
61 /** Determine whether the pieces should be highlighted when hovered */
62 void setEnableHighlight( bool isEnabled );
63 /** The MainWindow needs a ref. to this for KgThemeSelector */
64 KgThemeProvider* themeProvider() const;
65 Q_SIGNALS:
66 /** Emitted when undo action enable or disable */
67 void canUndoChanged( bool canUndo );
68 /** Emitted when redo action enable or disable */
69 void canRedoChanged( bool canRedo );
70 /** Emitted when the marked piece count changes */
71 void markedCountChanged( int markedCount );
72 /** Emitted when the remaining piece count changes */
73 void remainCountChanged( int remainCount );
74 /** Emitted when the game has been finished */
75 void gameFinished( int remainCount );
76 public Q_SLOTS:
77 /** Undo the last move */
78 void undoMove();
79 /** Redo the last undo */
80 void redoMove();
81 /** Undo all */
82 void undoAllMove();
83 /** Redo all */
84 void redoAllMove();
85 protected:
86 /** Reimplemented for drawing the background depending on the settings */
87 virtual void drawBackground( QPainter* painter, const QRectF& rect );
88 private Q_SLOTS:
89 /** Check whether the player has no way to remove any pieces, emit signals if finished */
90 void checkGameFinished();
91 /** Try to highlight the pieces of the same color at ( x y ) */
92 void highlightPieces( int x, int y );
93 /** Try to unhighlight the pieces of the same color at ( x y ) */
94 void unhighlightPieces( int x, int y );
95 /** Try to remove the pieces of the same color at ( x y ) */
96 void removePieces( int x, int y );
97 /** Resize the game scene, layout all the pieces and bound lines */
98 void resize( const QRectF& size );
99 /** Update all the pieces and bound lines */
100 void updateScene();
101 /** Update all the bound lines */
102 void updateBoundLines();
103 private:
104 /** Internal function used to help perform piece function recursively */
105 void traverseNeighbors( int x, int y, int color, bool (GameScene::*func)(Piece*) );
106 /** Internal function used to help highlight pieces recursively */
107 bool highlightPiece( Piece* p );
108 /** Internal function used to help unhighlight pieces recursively */
109 bool unhighlightPiece( Piece* p );
110 /** Internal function used to help remove pieces recursively */
111 bool removePiece( Piece* p );
112 /** Internal function used to check whether the piece can be removed */
113 bool canRemovePiece( int x, int y );
114 /** Internal function used to caluculate the marked piece count */
115 int currentMarkedCount() const;
116 /** Internal function used to caluculate the remaining piece count */
117 int currentRemainCount() const;
118 /** The game graphics item renderer */
119 KGameRenderer m_renderer;
120 /** The popup messenger used when game paused or finished */
121 KGamePopupItem* m_messenger;
122 /** The container of all the pieces */
123 QVector<Piece*> m_pieces;
124 /** The undo stack recording moves */
125 QUndoStack m_undoStack;
126 /** True if the bound lines should be showed */
127 bool m_showBoundLines;
128 /** True if the animation of removing pieces should be used */
129 bool m_enableAnimation;
130 /** True if the pieces should be highlighted when hovered */
131 bool m_enableHighlight;
132 /** The background type */
133 int m_backgroundType;
134 /** The x-position of the currently hovered piece */
135 int m_currentlyHoveredPieceX;
136 /** The y-position of the currently hovered piece */
137 int m_currentlyHoveredPieceY;
138 /** The count of pieces in a row */
139 int PWC;
140 /** The count of pieces in a column */
141 int PHC;
142 /** The count of colors used */
143 int m_colorCount;
144 /** The game id */
145 int m_gameId;
146 /** True if the game has been paused */
147 bool m_isPaused;
148 /** True if the game has been finished */
149 bool m_isFinished;
150 /** The animation group holding the animations of removing pieces */
151 QSequentialAnimationGroup* const m_animation;
152};
153
154#endif // GAMESCENE_H
155