mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-11 00:44:27 -05:00
694 lines
18 KiB
C++
694 lines
18 KiB
C++
|
/*
|
||
|
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 <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include "FreeCellBoard.h"
|
||
|
#include "CardPixmaps.h"
|
||
|
#include "CardDeck.h"
|
||
|
#include "CardAnimationLock.h"
|
||
|
|
||
|
#include <iostream>
|
||
|
|
||
|
#include <QtGui/QMessageBox>
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
FreeCellBoard::FreeCellBoard()
|
||
|
:GameBoard(NULL,QString(tr("Freecell")).trimmed(),QString("Freecell")),
|
||
|
m_pDeck(NULL),
|
||
|
m_freeVector(),
|
||
|
m_stackVector(),
|
||
|
m_homeVector(),
|
||
|
m_cheat(false)
|
||
|
{
|
||
|
this->setHelpFile(":/help/FreeCellHelp.html");
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
FreeCellBoard::~FreeCellBoard()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::undoMove()
|
||
|
{
|
||
|
GameBoard::undoMove();
|
||
|
|
||
|
this->setNumStackMoveCards();
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::redoMove()
|
||
|
{
|
||
|
GameBoard::redoMove();
|
||
|
|
||
|
this->setNumStackMoveCards();
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
bool FreeCellBoard::getHint(CardStack * & pSrc,
|
||
|
unsigned int & srcIndex,
|
||
|
CardStack * & pDst)
|
||
|
{
|
||
|
bool rc=false;
|
||
|
unsigned int i;
|
||
|
unsigned int j;
|
||
|
|
||
|
|
||
|
// first see if we have any cards from the free cells to move
|
||
|
// home
|
||
|
for (i=0;i<this->m_freeVector.size() && !rc;i++)
|
||
|
{
|
||
|
if (!this->m_freeVector[i]->isEmpty())
|
||
|
{
|
||
|
const PlayingCardVector & cardVector=this->m_freeVector[i]->getCardVector();
|
||
|
PlayingCardVector moveCards;
|
||
|
|
||
|
srcIndex=cardVector.size()-1;
|
||
|
|
||
|
moveCards.push_back(cardVector[srcIndex]);
|
||
|
|
||
|
for (j=0;j<this->m_homeVector.size();j++)
|
||
|
{
|
||
|
if (this->m_homeVector[j]->canAddCards(moveCards))
|
||
|
{
|
||
|
pSrc=this->m_freeVector[i];
|
||
|
pDst=this->m_homeVector[j];
|
||
|
rc=true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// now see if there are any cards in the stacks to move home
|
||
|
if (!rc)
|
||
|
{
|
||
|
for (i=0;i<this->m_stackVector.size() && !rc;i++)
|
||
|
{
|
||
|
if (!this->m_stackVector[i]->isEmpty())
|
||
|
{
|
||
|
const PlayingCardVector & cardVector=this->m_stackVector[i]->getCardVector();
|
||
|
PlayingCardVector moveCards;
|
||
|
|
||
|
srcIndex=cardVector.size()-1;
|
||
|
|
||
|
moveCards.push_back(cardVector[srcIndex]);
|
||
|
|
||
|
for (j=0;j<this->m_homeVector.size();j++)
|
||
|
{
|
||
|
if (this->m_homeVector[j]->canAddCards(moveCards))
|
||
|
{
|
||
|
pSrc=this->m_stackVector[i];
|
||
|
pDst=this->m_homeVector[j];
|
||
|
rc=true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// now see if we can move cards from the free cells to the stacks
|
||
|
if (!rc)
|
||
|
{
|
||
|
for (i=0;i<this->m_freeVector.size() && !rc;i++)
|
||
|
{
|
||
|
if (!this->m_freeVector[i]->isEmpty())
|
||
|
{
|
||
|
PlayingCardVector moveCards;
|
||
|
|
||
|
if (this->m_freeVector[i]->getMovableCards(moveCards,srcIndex))
|
||
|
{
|
||
|
for (j=0;j<this->m_stackVector.size();j++)
|
||
|
{
|
||
|
if (this->m_stackVector[j]->canAddCards(moveCards))
|
||
|
{
|
||
|
pSrc=this->m_freeVector[i];
|
||
|
pDst=this->m_stackVector[j];
|
||
|
rc=true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// now look for stack to stack moves
|
||
|
if (!rc)
|
||
|
{
|
||
|
for (i=0;i<this->m_stackVector.size() && !rc;i++)
|
||
|
{
|
||
|
if (!this->m_stackVector[i]->isEmpty())
|
||
|
{
|
||
|
PlayingCardVector moveCards;
|
||
|
|
||
|
if (this->m_stackVector[i]->getMovableCards(moveCards,srcIndex))
|
||
|
{
|
||
|
// look through the stacks if we couldn't move the card home
|
||
|
for (j=0;j<this->m_stackVector.size();j++)
|
||
|
{
|
||
|
// make sure not the same stackVector and that we are not moving
|
||
|
// the last card in a stack to an empty stack. Moving the last
|
||
|
// card in a stack to an empty stack doesn't do anything. And lastly
|
||
|
// if the cards can be added we have a match.
|
||
|
if (i!=j &&
|
||
|
!(0==srcIndex && this->m_stackVector[j]->isEmpty()) &&
|
||
|
this->m_stackVector[j]->canAddCards(moveCards))
|
||
|
{
|
||
|
pSrc=this->m_stackVector[i];
|
||
|
pDst=this->m_stackVector[j];
|
||
|
rc=true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// now look to move something to a free cell if all else has failed
|
||
|
// for now just going to be a basic move an available card from the first
|
||
|
// stack with cards in it to the free cell.
|
||
|
if (!rc)
|
||
|
{
|
||
|
// first find an open free cell. If we don't have one no need to continue.
|
||
|
pDst=NULL;
|
||
|
|
||
|
for (i=0;i<this->m_freeVector.size();i++)
|
||
|
{
|
||
|
if (this->m_freeVector[i]->isEmpty())
|
||
|
{
|
||
|
pDst=this->m_freeVector[i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (NULL!=pDst)
|
||
|
{
|
||
|
for (i=0;i<this->m_stackVector.size();i++)
|
||
|
{
|
||
|
if (!this->m_stackVector[i]->isEmpty())
|
||
|
{
|
||
|
PlayingCardVector moveCards;
|
||
|
|
||
|
|
||
|
if (this->m_stackVector[i]->getMovableCards(moveCards,srcIndex) &&
|
||
|
pDst->canAddCards(moveCards))
|
||
|
{
|
||
|
pSrc=this->m_stackVector[i];
|
||
|
rc=true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::newGame()
|
||
|
{
|
||
|
// call the base class to clean up
|
||
|
GameBoard::newGame();
|
||
|
|
||
|
CardDeck deck;
|
||
|
unsigned int i;
|
||
|
|
||
|
|
||
|
// add all the cards to the deck
|
||
|
while(!deck.isEmpty())
|
||
|
{
|
||
|
this->m_pDeck->addCard(deck.next());
|
||
|
}
|
||
|
|
||
|
// setup the deal of cards
|
||
|
DealItemVector dealItemVector;
|
||
|
|
||
|
// Create the dealItemVector to direct the DealAnimation object on
|
||
|
// how to deal the cards.
|
||
|
for (i=0;i<this->m_stackVector.size();i++)
|
||
|
{
|
||
|
unsigned int j;
|
||
|
unsigned int cardsInStack=((i<4)?7:6);
|
||
|
|
||
|
dealItemVector.push_back(DealItem(this->m_stackVector[i],m_pDeck));
|
||
|
|
||
|
for (j=0;j<cardsInStack;j++)
|
||
|
{
|
||
|
dealItemVector[i].addCard(true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ok now start the deal. We don't need a move record for this item.
|
||
|
m_dealAni.dealCards(dealItemVector,false);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::addGameMenuItems(QMenu & menu)
|
||
|
{
|
||
|
Q_UNUSED(menu);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::loadSettings(const QSettings & settings)
|
||
|
{
|
||
|
Q_UNUSED(settings);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::saveSettings(QSettings & settings)
|
||
|
{
|
||
|
Q_UNUSED(settings);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::setCheat(bool cheat)
|
||
|
{
|
||
|
unsigned int i;
|
||
|
|
||
|
for (i=0;i<m_stackVector.size();i++)
|
||
|
{
|
||
|
m_stackVector[i]->setCheat(cheat);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::slotCardsMoved(const CardMoveRecord & moveRecord)
|
||
|
{
|
||
|
GameBoard::slotCardsMoved(moveRecord);
|
||
|
|
||
|
this->setNumStackMoveCards();
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::slotFreeCardsClicked(CardStack * pCardStack,
|
||
|
const PlayingCardVector & cardVector,
|
||
|
const CardMoveRecord & startMoveRecord)
|
||
|
{
|
||
|
Q_UNUSED(pCardStack);
|
||
|
|
||
|
CardStack * pEmptyStack=NULL;
|
||
|
CardStack * pMoveStack=NULL;
|
||
|
unsigned int i;
|
||
|
|
||
|
// ok look for where we would move the cards to. We will look first at the home stacks.
|
||
|
// After the home stacks the next priority will be a non-empty stack and then lastly
|
||
|
// an empty stack.
|
||
|
|
||
|
for (i=0;i<this->m_homeVector.size();i++)
|
||
|
{
|
||
|
if (this->m_homeVector[i]->canAddCards(cardVector))
|
||
|
{
|
||
|
pMoveStack=this->m_homeVector[i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// if we did not find a match continue to look
|
||
|
if (NULL==pMoveStack)
|
||
|
{
|
||
|
for (i=0;i<this->m_stackVector.size();i++)
|
||
|
{
|
||
|
if (this->m_stackVector[i]->canAddCards(cardVector))
|
||
|
{
|
||
|
if (this->m_stackVector[i]->isEmpty())
|
||
|
{
|
||
|
pEmptyStack=this->m_stackVector[i];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pMoveStack=this->m_stackVector[i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (NULL!=pMoveStack || NULL!=pEmptyStack)
|
||
|
{
|
||
|
if (NULL==pMoveStack)
|
||
|
{
|
||
|
pMoveStack=pEmptyStack;
|
||
|
}
|
||
|
|
||
|
CardMoveRecord moveRecord(startMoveRecord);
|
||
|
pMoveStack->addCards(cardVector,moveRecord,true);
|
||
|
|
||
|
// perform the move of the cards and animate it if animations
|
||
|
// are enabled
|
||
|
m_sToSAniMove.moveCards(moveRecord);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::slotStackCardsClicked(CardStack * pCardStack,
|
||
|
const PlayingCardVector & cardVector,
|
||
|
const CardMoveRecord & startMoveRecord)
|
||
|
{
|
||
|
CardStack * pEmptyStack=NULL;
|
||
|
CardStack * pMoveStack=NULL;
|
||
|
unsigned int i;
|
||
|
|
||
|
// ok look for where we would move the cards to. We will look first at the home stacks.
|
||
|
// After the home stacks the next priority will be a non-empty stack then an empty stack.
|
||
|
// And lastly a free cell.
|
||
|
|
||
|
for (i=0;i<this->m_homeVector.size();i++)
|
||
|
{
|
||
|
if (this->m_homeVector[i]->canAddCards(cardVector))
|
||
|
{
|
||
|
pMoveStack=this->m_homeVector[i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// if we did not find a match continue to look
|
||
|
if (NULL==pMoveStack)
|
||
|
{
|
||
|
for (i=0;i<this->m_stackVector.size();i++)
|
||
|
{
|
||
|
if (this->m_stackVector[i]!=pCardStack)
|
||
|
{
|
||
|
if (this->m_stackVector[i]->canAddCards(cardVector))
|
||
|
{
|
||
|
if (this->m_stackVector[i]->isEmpty())
|
||
|
{
|
||
|
pEmptyStack=this->m_stackVector[i];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pMoveStack=this->m_stackVector[i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// now look in the free cells
|
||
|
if (NULL==pMoveStack)
|
||
|
{
|
||
|
for (i=0;i<this->m_freeVector.size();i++)
|
||
|
{
|
||
|
if (this->m_freeVector[i]->canAddCards(cardVector))
|
||
|
{
|
||
|
pMoveStack=this->m_freeVector[i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (NULL!=pMoveStack || NULL!=pEmptyStack)
|
||
|
{
|
||
|
if (NULL==pMoveStack)
|
||
|
{
|
||
|
pMoveStack=pEmptyStack;
|
||
|
}
|
||
|
|
||
|
CardMoveRecord moveRecord(startMoveRecord);
|
||
|
pMoveStack->addCards(cardVector,moveRecord,true);
|
||
|
|
||
|
// perform the move of the cards and animate it if animations
|
||
|
// are enabled
|
||
|
m_sToSAniMove.moveCards(moveRecord);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::calcScore()
|
||
|
{
|
||
|
int score=0;
|
||
|
|
||
|
for(unsigned int i=0;i<this->m_homeVector.size();i++)
|
||
|
{
|
||
|
score+=this->m_homeVector[i]->score();
|
||
|
}
|
||
|
|
||
|
emit scoreChanged(score,"");
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::resizeEvent (QResizeEvent * event)
|
||
|
{
|
||
|
unsigned int i;
|
||
|
|
||
|
GameBoard::resizeEvent(event);
|
||
|
|
||
|
|
||
|
QSize cardSize(CardPixmaps::getInst().getCardSize());
|
||
|
|
||
|
QPointF currPos(GameBoard::LayoutSpacing,GameBoard::LayoutSpacing);
|
||
|
|
||
|
for (i=0;i<m_freeVector.size();i++)
|
||
|
{
|
||
|
m_freeVector[i]->setPos(currPos);
|
||
|
currPos.rx()+=cardSize.width()+GameBoard::LayoutSpacing;
|
||
|
}
|
||
|
|
||
|
currPos.rx()+=(cardSize.width() + GameBoard::LayoutSpacing)/2;
|
||
|
|
||
|
m_pDeck->setPos(currPos);
|
||
|
|
||
|
currPos.setX(GameBoard::LayoutSpacing*7 + cardSize.width()*6);
|
||
|
|
||
|
|
||
|
for (i=0;i<m_homeVector.size();i++)
|
||
|
{
|
||
|
m_homeVector[i]->setPos(currPos);
|
||
|
currPos.rx()+=cardSize.width()+GameBoard::LayoutSpacing;
|
||
|
}
|
||
|
|
||
|
currPos.setY(GameBoard::LayoutSpacing*2+cardSize.height());
|
||
|
currPos.setX(GameBoard::LayoutSpacing*2+cardSize.width());
|
||
|
for (i=0;i<m_stackVector.size();i++)
|
||
|
{
|
||
|
m_stackVector[i]->setPos(currPos);
|
||
|
currPos.rx()+=cardSize.width()+GameBoard::LayoutSpacing;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
bool FreeCellBoard::runDemo(bool stopWhenNoMore)
|
||
|
{
|
||
|
bool rc=true;
|
||
|
|
||
|
if (!GameBoard::runDemo(false))
|
||
|
{
|
||
|
// if we didn't find a move. Try to just move a card to a freecell.
|
||
|
CardStack * pDst=NULL;
|
||
|
bool foundMove=false;
|
||
|
CardStack * pSrc=NULL;
|
||
|
unsigned int srcIndex=0;
|
||
|
PlayingCardVector moveCards;
|
||
|
unsigned int i;
|
||
|
|
||
|
for (i=0;i<this->m_freeVector.size();i++)
|
||
|
{
|
||
|
if (this->m_freeVector[i]->isEmpty())
|
||
|
{
|
||
|
pDst=this->m_freeVector[i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (NULL!=pDst)
|
||
|
{
|
||
|
for (i=0;i<this->m_stackVector.size();i++)
|
||
|
{
|
||
|
if (!this->m_stackVector[i]->isEmpty())
|
||
|
{
|
||
|
if (this->m_stackVector[i]->getMovableCards(moveCards,srcIndex) &&
|
||
|
pDst->canAddCards(moveCards))
|
||
|
{
|
||
|
pSrc=this->m_stackVector[i];
|
||
|
foundMove=true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// if we found a move create the move record. And call the stack to stack
|
||
|
// animation to move it.
|
||
|
if (foundMove)
|
||
|
{
|
||
|
CardMoveRecord moveRecord;
|
||
|
|
||
|
pSrc->removeCardsStartingAt(srcIndex,moveCards,moveRecord,true);
|
||
|
pDst->addCards(moveCards,moveRecord,true);
|
||
|
|
||
|
m_sToSAniMove.moveCards(moveRecord,this->getDemoCardAniTime());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (stopWhenNoMore)
|
||
|
{
|
||
|
stopDemo();
|
||
|
rc=false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc=false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::createStacks()
|
||
|
{
|
||
|
this->setCardResizeAlg(10,ResizeByWidth);
|
||
|
|
||
|
unsigned int i;
|
||
|
|
||
|
// first create the home widgets where the cards need to be eventually stacked to
|
||
|
// win the game.
|
||
|
for(i=0;i<4;i++)
|
||
|
{
|
||
|
this->m_homeVector.push_back(new FreeCellHome);
|
||
|
this->m_scene.addItem(m_homeVector[i]);
|
||
|
}
|
||
|
|
||
|
// now create the free cells
|
||
|
for(i=0;i<4;i++)
|
||
|
{
|
||
|
this->m_freeVector.push_back(new FreeCellFree);
|
||
|
this->m_scene.addItem(m_freeVector[i]);
|
||
|
this->connect(this->m_freeVector[i],SIGNAL(cardsMovedByDragDrop(CardMoveRecord)),
|
||
|
this,SLOT(slotCardsMoved(CardMoveRecord)));
|
||
|
this->connect(this->m_freeVector[i],SIGNAL(movableCardsClicked(CardStack*,PlayingCardVector,CardMoveRecord)),
|
||
|
this,SLOT(slotFreeCardsClicked(CardStack*,PlayingCardVector,CardMoveRecord)));
|
||
|
}
|
||
|
|
||
|
// now create the 8 rows for the stacks.
|
||
|
for (i=0;i<8;i++)
|
||
|
{
|
||
|
this->m_stackVector.push_back(new FreeCellStack);
|
||
|
this->m_scene.addItem(m_stackVector[i]);
|
||
|
this->connect(this->m_stackVector[i],SIGNAL(cardsMovedByDragDrop(CardMoveRecord)),
|
||
|
this,SLOT(slotCardsMoved(CardMoveRecord)));
|
||
|
this->connect(this->m_stackVector[i],SIGNAL(movableCardsClicked(CardStack*,PlayingCardVector,CardMoveRecord)),
|
||
|
this,SLOT(slotStackCardsClicked(CardStack*,PlayingCardVector,CardMoveRecord)));
|
||
|
}
|
||
|
|
||
|
this->m_pDeck=new FreeCellDeck;
|
||
|
this->m_scene.addItem(this->m_pDeck);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
bool FreeCellBoard::isGameWon()const
|
||
|
{
|
||
|
bool rc=true;
|
||
|
|
||
|
for (unsigned int i=0;i<this->m_homeVector.size();i++)
|
||
|
{
|
||
|
if (!this->m_homeVector[i]->isStackComplete())
|
||
|
{
|
||
|
rc=false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
bool FreeCellBoard::isGameWonNotComplete()const
|
||
|
{
|
||
|
bool rc=true;
|
||
|
|
||
|
for (unsigned int i=0;i<this->m_stackVector.size();i++)
|
||
|
{
|
||
|
if (!this->m_stackVector[i]->cardsAscendingTopToBottom())
|
||
|
{
|
||
|
rc=false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void FreeCellBoard::setNumStackMoveCards()
|
||
|
{
|
||
|
// as a convience allow dragging of cards if there would be enough
|
||
|
// freecells to move the cards
|
||
|
unsigned int numDragCards=1;
|
||
|
unsigned int i;
|
||
|
|
||
|
for (i=0;i<m_stackVector.size();i++)
|
||
|
{
|
||
|
if (m_stackVector[i]->isEmpty())
|
||
|
{
|
||
|
numDragCards++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// in the case that we might be dragging the cards to a free
|
||
|
// space, we don't want the free space to count. It would not
|
||
|
// be a free space to dump a card. So, it can't be counted.
|
||
|
if (numDragCards>1)
|
||
|
{
|
||
|
numDragCards--;
|
||
|
}
|
||
|
|
||
|
for (i=0;i<m_freeVector.size();i++)
|
||
|
{
|
||
|
if (m_freeVector[i]->isEmpty())
|
||
|
{
|
||
|
numDragCards++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (i=0;i<m_stackVector.size();i++)
|
||
|
{
|
||
|
m_stackVector[i]->setMaxMoveCards(numDragCards);
|
||
|
}
|
||
|
}
|