1 /*
2  * Copyright (C) 1995 Paul Olav Tvete <paul@troll.no>
3  * Copyright (C) 2000-2009 Stephan Kulow <coolo@kde.org>
4  * Copyright (C) 2009-2010 Parker Coates <coates@kde.org>
5  *
6  * License of original code:
7  * -------------------------------------------------------------------------
8  *   Permission to use, copy, modify, and distribute this software and its
9  *   documentation for any purpose and without fee is hereby granted,
10  *   provided that the above copyright notice appear in all copies and that
11  *   both that copyright notice and this permission notice appear in
12  *   supporting documentation.
13  *
14  *   This file is provided AS IS with no warranties of any kind.  The author
15  *   shall have no liability with respect to the infringement of copyrights,
16  *   trade secrets or any patents by this file or any part thereof.  In no
17  *   event will the author be liable for any lost revenue or profits or
18  *   other special, indirect and consequential damages.
19  * -------------------------------------------------------------------------
20  *
21  * License of modifications/additions made after 2009-01-01:
22  * -------------------------------------------------------------------------
23  *   This program is free software; you can redistribute it and/or
24  *   modify it under the terms of the GNU General Public License as
25  *   published by the Free Software Foundation; either version 2 of
26  *   the License, or (at your option) any later version.
27  *
28  *   This program is distributed in the hope that it will be useful,
29  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
30  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31  *   GNU General Public License for more details.
32  *
33  *   You should have received a copy of the GNU General Public License
34  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
35  * -------------------------------------------------------------------------
36  */
37 
38 #ifndef DEALER_H
39 #define DEALER_H
40 
41 // own
42 #include "gamestate.h"
43 #include "patpile.h"
44 #include "speeds.h"
45 #include "view.h"
46 // KCardGame
47 #include <KCardDeck>
48 #include <KCardScene>
49 // Qt
50 #include <QMap>
51 #include <QStack>
52 #include <QTimer>
53 #include <QSet>
54 
55 class DealerInfo;
56 class MessageBox;
57 class MoveHint;
58 class SolverInterface;
59 class SolverThread;
60 
61 class QAction;
62 
63 #define scores_group "Scores"
64 
65 class DealerScene : public KCardScene
66 {
67     Q_OBJECT
68 
69 public:
70     enum { None = 0, Hint = 1, Demo = 2, Draw = 4, Deal = 8, Redeal = 16 } Actions;
71 
72     explicit DealerScene( const DealerInfo * di );
73     ~DealerScene();
74 
75     virtual void initialize() = 0;
76 
77     void relayoutScene() override;
78     void updateWonItem();
79 
80     void addPatPile( PatPile * pile );
81     void removePatPile( PatPile * pile );
82     void clearPatPiles();
83     QList<PatPile*> patPiles() const;
84 
85     void setAutoDropEnabled( bool enabled );
86     bool autoDropEnabled() const;
87 
88     int gameNumber() const;
89 
90     int gameId() const;
91 
92     void setActions( int actions );
93     int actions() const;
94 
95     virtual QList<QAction*> configActions() const;
96 
97     void startHint();
98     void stopHint();
99     bool isHintActive() const;
100 
101     void startDrop();
102     void stopDrop();
103     bool isDropActive() const;
104 
105     void startDemo();
106     void stopDemo();
107     bool isDemoActive() const;
108 
109     void setSolverEnabled( bool enabled );
110     SolverInterface * solver() const;
111     void startSolver();
112 
113     virtual bool isGameLost() const;
114     virtual bool isGameWon() const;
115 
116     bool allowedToStartNewGame();
117     int moveCount() const;
118 
119     void saveFile( QIODevice * io );
120     bool loadFile( QIODevice * io );
121     void saveLegacyFile( QIODevice * io );
122     bool loadLegacyFile( QIODevice * io );
123 
124     virtual void mapOldId(int id);
125     virtual int oldId() const;
126     void recordGameStatistics();
127 
128     QImage createDump() const;
129 
130 Q_SIGNALS:
131     void undoPossible(bool poss);
132     void redoPossible(bool poss);
133     void newCardsPossible(bool poss);
134     void gameInProgress(bool inProgress);
135 
136     void demoActive(bool active);
137     void hintActive(bool active);
138     void dropActive(bool active);
139     void updateMoves(int moves);
140 
141     void solverStateChanged(const QString &text);
142     void newDeal();
143 
144     void cardsPickedUp();
145     void cardsPutDown();
146 
147 public Q_SLOTS:
148     void startNew( int dealNumber = -1 );
149 
150     void undo();
151     void redo();
152 
153     void stop();
154 
155     void drawDealRowOrRedeal();
156     virtual bool tryAutomaticMove( KCard * card );
157 
158 protected:
159     bool allowedToAdd(const KCardPile * pile, const QList<KCard*> & cards) const override;
160     bool allowedToRemove(const KCardPile * pile, const KCard * card) const override;
161 
162     virtual bool checkAdd( const PatPile * pile, const QList<KCard*> & oldCards, const QList<KCard*> & newCards ) const;
163     virtual bool checkRemove( const PatPile * pile, const QList<KCard*> & cards ) const;
164     virtual bool checkPrefering( const PatPile * pile, const QList<KCard*> & oldCards, const QList<KCard*> & newCards ) const;
165 
166     void cardsMoved( const QList<KCard*> & cards, KCardPile * oldPile, KCardPile * newPile ) override;
167 
168     void mouseDoubleClickEvent( QGraphicsSceneMouseEvent * mouseEvent ) override;
169     void mousePressEvent( QGraphicsSceneMouseEvent * mouseEvent ) override;
170     void mouseReleaseEvent( QGraphicsSceneMouseEvent * mouseEvent ) override;
171 
172     virtual void restart( const QList<KCard*> & cards ) = 0;
173 
174     void setSolver( SolverInterface * solver );
175 
176     virtual QList<MoveHint> getHints();
177 
178     // reimplement these to store and load game-specific information in the state structure
179     virtual QString getGameState() const;
180     virtual void setGameState( const QString & state );
181 
182     // reimplement these to store and load game-specific options in the saved game file
183     virtual QString getGameOptions() const;
184     virtual void setGameOptions( const QString & options );
185 
186     void addCardForDeal( KCardPile * pile, KCard * card, bool faceUp, QPointF startPos );
187     void startDealAnimation();
188 
189     void setNeededFutureMoves( int moves );
190     int neededFutureMoves() const;
191 
192     void setDeckContents( int copies = 1,
193                           const QList<KCardDeck::Suit> & suits = KCardDeck::standardSuits() );
194 
195     void multiStepMove( const QList<KCard*> & cards,
196                         KCardPile * pile,
197                         const QList<KCardPile*> & freePiles,
198                         const QList<KCardPile*> & freeCells,
199                         int duration  );
200 
201     QList<MoveHint> getSolverHints();
202 
203 protected Q_SLOTS:
204     void takeState();
205     virtual void animationDone();
206     virtual bool newCards();
207     virtual bool drop();
208 
209 private Q_SLOTS:
210     void stopAndRestartSolver();
211     void slotSolverEnded();
212     void slotSolverFinished( int result );
213 
214     void demo();
215 
216     void showWonMessage();
217 
218 private:
219     void undoOrRedo( bool undo );
220 
221     void resetInternals();
222 
223     MoveHint chooseHint();
224 
225     void won();
226 
227     int speedUpTime( int delay ) const;
228 
229     void multiStepSubMove( QList<KCard*> cards,
230                            KCardPile * pile,
231                            QList<KCardPile*> freePiles,
232                            const QList<KCardPile*> & freeCells );
233     void continueMultiStepMove();
234 
235     const DealerInfo * const m_di;
236 
237     SolverInterface * m_solver;
238     SolverThread * m_solverThread;
239     QList<MOVE> m_winningMoves;
240 
241     KCard * m_peekedCard;
242     MessageBox * m_wonItem;
243 
244     QTimer m_solverUpdateTimer;
245     QTimer m_demoTimer;
246     QTimer m_dropTimer;
247 
248     int m_dealNumber;
249     int m_loadedMoveCount;
250     int m_neededFutureMoves;
251     int m_supportedActions;
252 
253     bool m_autoDropEnabled;
254     bool m_solverEnabled;
255 
256     bool m_dealStarted;
257     bool m_dealWasEverWinnable;
258     bool m_dealHasBeenWon;
259     bool m_dealWasJustSaved;
260     bool m_statisticsRecorded;
261     bool m_playerReceivedHelp;
262 
263     // We need a flag to avoid telling someone the game is lost
264     // just because the winning animation moved the cards away
265     bool m_toldAboutWonGame;
266     bool m_toldAboutLostGame;
267 
268     QSet<KCard*> m_cardsRemovedFromFoundations;
269     qreal m_dropSpeedFactor;
270     bool m_interruptAutoDrop;
271 
272     bool m_dealInProgress;
273     bool m_hintInProgress;
274     bool m_demoInProgress;
275     bool m_dropInProgress;
276 
277     bool m_hintQueued;
278     bool m_demoQueued;
279     bool m_dropQueued;
280     bool m_newCardsQueued;
281     bool m_takeStateQueued;
282 
283     QStack<GameState*> m_undoStack;
284     GameState * m_currentState;
285     QStack<GameState*> m_redoStack;
286     QHash<KCard*,CardState> m_lastKnownCardStates;
287 
288     QList<QPair<KCard*,KCardPile*> > m_multiStepMoves;
289     int m_multiStepDuration;
290 
291     QList<PatPile*> m_patPiles;
292 
293     QMap<KCard*,QPointF> m_initDealPositions;
294 };
295 
296 #endif
297