/* QSoloCards is a collection of Solitaire card games written using Qt Copyright (C) 2009 Steve Moore This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef GAMEBOARD_H #define GAMEBOARD_H #include #include #include #include #include #include #include #include "CardStack.h" #include "CardMoveRecord.h" #include "StackToStackAniMove.h" #include "DealAnimation.h" // Generic base class for a games board class GameBoard : public QGraphicsView { Q_OBJECT public: enum { LayoutSpacing=10 }; enum CardResizeType { ResizeByWidth=0, ResizeByHeight=1 }; enum DemoCardAniTime { DemoEndGameCardAniTime=100, DemoNormalCardAniTime=400 }; GameBoard(QWidget * pWidget, const QString & gameName, const QString & gameSettingsId); virtual ~GameBoard(); virtual void setGameName(const QString & gameName){m_gameName=gameName;} virtual void setGameId(const QString & gameId){ m_gameSettingsId=gameId;} // this function show be called in the constructor of classes inheriting from this // class to set the way that cards will be resized. virtual void setCardResizeAlg(unsigned int colsOrRows,CardResizeType resizeType); // this function is called when setCardResizeAlg is called or when the GameBoard is resized. virtual void updateCardSize(const QSize & newSize); // undoMove and redoMove pop items off there respective stacks // and process the move. They also call calcScore to update the // score. // signals undoAvail and redoAvail are also emitted if necessary virtual void undoMove(); virtual void redoMove(); virtual bool canUndoMove() const; virtual bool canRedoMove() const; // addUndoMove will add the move to the undo stack. clear the redo stack // and call calcScore. // signals undoAvail and redoAvail are also emitted if necessary virtual void addUndoMove(const CardMoveRecord &); // will clear all contents of both the redo and undo stacks, call calcScore, and // signals undoAvail and redoAvail are also emitted if necessary virtual void clearUndoRedoStacks(); virtual void restartGame(); virtual void showHint(); // this function is split into a separate virtual function // it will allow the function to be used both for showing a // hint and for demo mode. virtual bool getHint(CardStack * & pSrcWidget, unsigned int & srcStackIndex, CardStack * & pDstWidget)=0; virtual void startDemo(DemoCardAniTime demoCardAniTime=DemoNormalCardAniTime); virtual void stopDemo(); inline bool isDemoRunning() const { return m_demoRunning;} inline DemoCardAniTime getDemoCardAniTime()const{return m_demoCardAniTime;} // override this function if the game is implementing demo mode. // The runDemo() function will need to be called after // each move. Bestway would be to add something at the end of the slot // that catches the cardsMoved signal from the move animations. // By default runDemo will call getHint and if a move is returned it will // perform the move. If something else is desired the function can be overridden. // it also returns a bool. So, if it is overridden the base class can be called // first to see if there is a basic move. If not something else can be done. virtual bool hasDemo() const {return false;} virtual void newGame(); virtual bool isCheating() const=0; virtual void setCheat(bool cheat)=0; virtual void addGameMenuItems(QMenu &)=0; virtual void loadSettings(const QSettings & settings)=0; virtual void saveSettings(QSettings & settings)=0; virtual bool supportsScore() const=0; virtual const QString & helpFile() const { return m_helpFile;} const QPixmap & getGamePixmap() const{return m_gamePixmap;} const QString & gameName() const{return m_gameName;} const QString & gameSettingsId() const {return m_gameSettingsId;} public slots: virtual void slotCardsMoved(const CardMoveRecord &); signals: // this signal should be emitted on a state change of undo from available // to unavailable or unavailable to available by sub classes void undoAvail(bool avail); // this signal should be emitted on a state change of redo from available // to unavailable or unavailable to available by sub classes void redoAvail(bool avail); // signal emitted by a game when its score changed. // The string is extra info the game can pass to show // additional info. void scoreChanged(int score,const QString &); void demoStarted(); void demoStopped(); protected: virtual void calcScore()=0; // called when the score is changed by add to rewinding the undo and redo stacks // subclasses should override for customizing score calculations virtual void setHelpFile(const QString & helpFile){m_helpFile=helpFile;} virtual void resizeEvent (QResizeEvent * event); // called to create the CardStacks for the game. virtual void createStacks()=0; // this function can be overloaded for more complex behavior for the demo. By default it // will just peform the hint returned if it found one. virtual bool runDemo(bool stopWhenNoMore=true); // implement in subclasses to determine if the game is won. virtual bool isGameWon()const=0; // implement in subclasses when cards are in position that the // game will be won. When this function returns true the demo // will be started if it is available to move the remaining cards virtual bool isGameWonNotComplete()const=0; QGraphicsScene m_scene; StackToStackAniMove m_sToSAniMove; DealAnimation m_dealAni; private: QString m_gameName; QString m_gameSettingsId; QPixmap m_gamePixmap; std::stack m_undoStack; // stack to keep track of moves std::stack m_redoStack; // stack to keep track of moves QString m_helpFile; unsigned int m_numColsOrRows; CardResizeType m_resizeType; bool m_demoRunning; CardStack * m_pDemoSrcPrev; CardStack * m_pDemoDstPrev; PlayingCardVector m_demoCardsPrev; DemoCardAniTime m_demoCardAniTime; bool m_stacksCreated; // variable to keep track if we have called createStacks }; #endif // GAMEBOARD_H