File indexing completed on 2024-05-12 08:00:32

0001 /*
0002  * Copyright (C) 1995 Paul Olav Tvete <paul@troll.no>
0003  * Copyright (C) 2000-2009 Stephan Kulow <coolo@kde.org>
0004  * Copyright (C) 2009-2010 Parker Coates <coates@kde.org>
0005  *
0006  * License of original code:
0007  * -------------------------------------------------------------------------
0008  *   Permission to use, copy, modify, and distribute this software and its
0009  *   documentation for any purpose and without fee is hereby granted,
0010  *   provided that the above copyright notice appear in all copies and that
0011  *   both that copyright notice and this permission notice appear in
0012  *   supporting documentation.
0013  *
0014  *   This file is provided AS IS with no warranties of any kind.  The author
0015  *   shall have no liability with respect to the infringement of copyrights,
0016  *   trade secrets or any patents by this file or any part thereof.  In no
0017  *   event will the author be liable for any lost revenue or profits or
0018  *   other special, indirect and consequential damages.
0019  * -------------------------------------------------------------------------
0020  *
0021  * License of modifications/additions made after 2009-01-01:
0022  * -------------------------------------------------------------------------
0023  *   This program is free software; you can redistribute it and/or
0024  *   modify it under the terms of the GNU General Public License as
0025  *   published by the Free Software Foundation; either version 2 of
0026  *   the License, or (at your option) any later version.
0027  *
0028  *   This program is distributed in the hope that it will be useful,
0029  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
0030  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0031  *   GNU General Public License for more details.
0032  *
0033  *   You should have received a copy of the GNU General Public License
0034  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
0035  * -------------------------------------------------------------------------
0036  */
0037 
0038 #ifndef DEALER_H
0039 #define DEALER_H
0040 
0041 // own
0042 #include "gamestate.h"
0043 #include "patpile.h"
0044 #include "speeds.h"
0045 #include "view.h"
0046 // KCardGame
0047 #include <KCardDeck>
0048 #include <KCardScene>
0049 // Qt
0050 #include <QMap>
0051 #include <QSet>
0052 #include <QStack>
0053 #include <QTimer>
0054 
0055 class DealerInfo;
0056 class MessageBox;
0057 class MoveHint;
0058 class SolverInterface;
0059 class SolverThread;
0060 
0061 class QAction;
0062 
0063 #define scores_group QStringLiteral("Scores")
0064 
0065 class DealerScene : public KCardScene
0066 {
0067     Q_OBJECT
0068 
0069 public:
0070     enum { None = 0, Hint = 1, Demo = 2, Draw = 4, Deal = 8, Redeal = 16 } Actions;
0071 
0072     explicit DealerScene(const DealerInfo *di);
0073     ~DealerScene();
0074 
0075     virtual void initialize() = 0;
0076 
0077     void relayoutScene() override;
0078     void updateWonItem();
0079 
0080     void addPatPile(PatPile *pile);
0081     void removePatPile(PatPile *pile);
0082     void clearPatPiles();
0083     QList<PatPile *> patPiles() const;
0084 
0085     void setAutoDropEnabled(bool enabled);
0086     bool autoDropEnabled() const;
0087 
0088     int gameNumber() const;
0089 
0090     int gameId() const;
0091 
0092     void setActions(int actions);
0093     int actions() const;
0094 
0095     virtual QList<QAction *> configActions() const;
0096 
0097     void startHint();
0098     void stopHint();
0099     bool isHintActive() const;
0100 
0101     void startDrop();
0102     void stopDrop();
0103     bool isDropActive() const;
0104 
0105     void startDemo();
0106     void stopDemo();
0107     bool isDemoActive() const;
0108 
0109     void setSolverEnabled(bool enabled);
0110     SolverInterface *solver() const;
0111     void startSolver();
0112 
0113     virtual bool isGameLost() const;
0114     virtual bool isGameWon() const;
0115 
0116     bool allowedToStartNewGame();
0117     int moveCount() const;
0118 
0119     void saveFile(QIODevice *io);
0120     bool loadFile(QIODevice *io, bool takestate = true);
0121     void saveLegacyFile(QIODevice *io);
0122     bool loadLegacyFile(QIODevice *io);
0123 
0124     virtual void mapOldId(int id);
0125     virtual int oldId() const;
0126     void recordGameStatistics();
0127 
0128     QImage createDump() const;
0129 
0130 Q_SIGNALS:
0131     void undoPossible(bool poss);
0132     void redoPossible(bool poss);
0133     void newCardsPossible(bool poss);
0134     void gameInProgress(bool inProgress);
0135 
0136     void demoActive(bool active);
0137     void hintActive(bool active);
0138     void dropActive(bool active);
0139     void updateMoves(int moves);
0140 
0141     void solverStateChanged(const QString &text);
0142     void newDeal();
0143 
0144     void cardsPickedUp();
0145     void cardsPutDown();
0146 
0147 public Q_SLOTS:
0148     void startNew(int dealNumber = -1);
0149 
0150     void undo();
0151     void redo();
0152 
0153     void stop();
0154 
0155     void drawDealRowOrRedeal();
0156     virtual bool tryAutomaticMove(KCard *card);
0157 
0158 protected:
0159     bool allowedToAdd(const KCardPile *pile, const QList<KCard *> &cards) const override;
0160     bool allowedToRemove(const KCardPile *pile, const KCard *card) const override;
0161 
0162     virtual bool checkAdd(const PatPile *pile, const QList<KCard *> &oldCards, const QList<KCard *> &newCards) const;
0163     virtual bool checkRemove(const PatPile *pile, const QList<KCard *> &cards) const;
0164     virtual bool checkPrefering(const PatPile *pile, const QList<KCard *> &oldCards, const QList<KCard *> &newCards) const;
0165 
0166     void cardsMoved(const QList<KCard *> &cards, KCardPile *oldPile, KCardPile *newPile) override;
0167 
0168     void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
0169     void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
0170     void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
0171 
0172     virtual void restart(const QList<KCard *> &cards) = 0;
0173 
0174     void setSolver(SolverInterface *solver);
0175 
0176     virtual QList<MoveHint> getHints();
0177 
0178     // reimplement these to store and load game-specific information in the state structure
0179     virtual QString getGameState() const;
0180     virtual void setGameState(const QString &state);
0181 
0182     // reimplement these to store and load game-specific options in the saved game file
0183     virtual QString getGameOptions() const;
0184     virtual void setGameOptions(const QString &options);
0185 
0186     void addCardForDeal(KCardPile *pile, KCard *card, bool faceUp, QPointF startPos);
0187     void startDealAnimation();
0188 
0189     void setNeededFutureMoves(int moves);
0190     int neededFutureMoves() const;
0191 
0192     void setDeckContents(int copies = 1, const QList<KCardDeck::Suit> &suits = KCardDeck::standardSuits());
0193 
0194     void multiStepMove(const QList<KCard *> &cards, KCardPile *pile, const QList<KCardPile *> &freePiles, const QList<KCardPile *> &freeCells, int duration);
0195 
0196     QList<MoveHint> getSolverHints();
0197 
0198 protected Q_SLOTS:
0199     void takeState();
0200     virtual void animationDone();
0201     virtual bool newCards();
0202     virtual bool drop();
0203 
0204 private Q_SLOTS:
0205     void stopAndRestartSolver();
0206     void slotSolverEnded();
0207     void slotSolverFinished(int result);
0208 
0209     void demo();
0210 
0211     void showWonMessage();
0212 
0213 private:
0214     void undoOrRedo(bool undo);
0215 
0216     void resetInternals();
0217 
0218     MoveHint chooseHint();
0219 
0220     void won();
0221 
0222     int speedUpTime(int delay) const;
0223 
0224     void multiStepSubMove(QList<KCard *> cards, KCardPile *pile, QList<KCardPile *> freePiles, const QList<KCardPile *> &freeCells);
0225     void continueMultiStepMove();
0226     QList<MoveHint> bruteForceHints();
0227 
0228     const DealerInfo *const m_di;
0229 
0230     SolverInterface *m_solver;
0231     SolverThread *m_solverThread;
0232     QList<MOVE> m_winningMoves;
0233 
0234     KCard *m_peekedCard;
0235     MessageBox *m_wonItem;
0236 
0237     QTimer m_solverUpdateTimer;
0238     QTimer m_demoTimer;
0239     QTimer m_dropTimer;
0240 
0241     int m_dealNumber;
0242     int m_loadedMoveCount;
0243     int m_neededFutureMoves;
0244     int m_supportedActions;
0245 
0246     bool m_autoDropEnabled;
0247     bool m_solverEnabled;
0248 
0249     bool m_dealStarted;
0250     bool m_dealWasEverWinnable;
0251     bool m_dealHasBeenWon;
0252     bool m_dealWasJustSaved;
0253     bool m_statisticsRecorded;
0254     bool m_playerReceivedHelp;
0255 
0256     // We need a flag to avoid telling someone the game is lost
0257     // just because the winning animation moved the cards away
0258     bool m_toldAboutWonGame;
0259     bool m_toldAboutLostGame;
0260 
0261     QSet<KCard *> m_cardsRemovedFromFoundations;
0262     qreal m_dropSpeedFactor;
0263     bool m_interruptAutoDrop;
0264 
0265     bool m_dealInProgress;
0266     bool m_hintInProgress;
0267     bool m_demoInProgress;
0268     bool m_dropInProgress;
0269 
0270     bool m_hintQueued;
0271     bool m_demoQueued;
0272     bool m_dropQueued;
0273     bool m_newCardsQueued;
0274     bool m_takeStateQueued;
0275 
0276     QStack<GameState *> m_undoStack;
0277     GameState *m_currentState;
0278     QStack<GameState *> m_redoStack;
0279     QHash<KCard *, CardState> m_lastKnownCardStates;
0280 
0281     QList<QPair<KCard *, KCardPile *>> m_multiStepMoves;
0282     int m_multiStepDuration;
0283 
0284     QList<PatPile *> m_patPiles;
0285 
0286     QMap<KCard *, QPointF> m_initDealPositions;
0287 };
0288 
0289 #endif