summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/solitaire/canvascardgame.cpp3
-rw-r--r--noncore/games/solitaire/canvascardgame.h1
-rw-r--r--noncore/games/solitaire/freecellcardgame.cpp83
-rw-r--r--noncore/games/solitaire/freecellcardgame.h5
4 files changed, 90 insertions, 2 deletions
diff --git a/noncore/games/solitaire/canvascardgame.cpp b/noncore/games/solitaire/canvascardgame.cpp
index 8e07cc8..8250193 100644
--- a/noncore/games/solitaire/canvascardgame.cpp
+++ b/noncore/games/solitaire/canvascardgame.cpp
@@ -306,54 +306,55 @@ void CanvasCardGame::contentsMouseReleaseEvent(QMouseEvent *e)
Q_UNUSED(p);
if ( moving ) {
CanvasCard *item = moving;
if ( item->animated() )
return;
if ( alphaCardPile )
if ( moved ) {
CardPile *pile = closestPile((int)alphaCardPile->x(), (int)alphaCardPile->y(), 30);
if (pile && pile->isAllowedOnTop(item)) {
CardPile *oldPile = item->getCardPile();
Card *c = NULL;
if ( oldPile != pile) {
while ( item ) {
item->show();
if ( oldPile ) {
c = oldPile->cardInfront(item);
oldPile->removeCard(item);
}
- pile->addCardToTop(item);
item->setCardPile(pile);
//item->move( pile->getCardPos(item) );
+ pile->addCardToTop(item);
QPoint p = pile->getCardPos(item);
item->setPos( p.x(), p.y(), highestZ );
highestZ++;
+ checkUnusable(); // added for freecell to move card to discard pile
if (item->getValue() == king && haveWeWon()) {
alphaCardPile->hide();
gameWon();
moving = NULL;
return;
}
if (oldPile) {
item = (CanvasCard *)c;
} else {
item = NULL;
}
}
alphaCardPile->hide();
moving = NULL;
return;
}
}
alphaCardPile->animatedMove();
}
}
diff --git a/noncore/games/solitaire/canvascardgame.h b/noncore/games/solitaire/canvascardgame.h
index 0dfb85e..d159de6 100644
--- a/noncore/games/solitaire/canvascardgame.h
+++ b/noncore/games/solitaire/canvascardgame.h
@@ -57,40 +57,41 @@ public:
return new CanvasCard( v, s, f, canvas() );
}
virtual void readConfig( Config& cfg ) { Q_UNUSED( cfg ); }
virtual void writeConfig( Config& cfg ) { Q_UNUSED( cfg ); }
virtual void gameWon();
virtual bool haveWeWon() { return FALSE; }
virtual bool mousePressCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); return FALSE; }
virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
void cancelMoving() { moving = NULL; }
void toggleSnap() { snapOn = (snapOn == TRUE) ? FALSE : TRUE; }
void toggleCardsDrawn() { numberToDraw = (numberToDraw == 1) ? 3 : 1; }
int cardsDrawn() { return numberToDraw; }
void setNumberToDraw(int numToDraw) { this->numberToDraw = numToDraw; }
void readPile( Config& cfg, CardPile *pile, QString name, int& highestZ );
protected:
void contentsMousePressEvent(QMouseEvent *e);
void contentsMouseReleaseEvent(QMouseEvent *e);
void contentsMouseMoveEvent(QMouseEvent *e);
+ virtual void checkUnusable() { } //added for freecell
protected:
// Mouse event state variables
bool moved;
CanvasCard *moving;
CanvasCardPile *alphaCardPile;
int cardXOff, cardYOff;
private:
bool snapOn;
int numberToDraw;
};
#endif
diff --git a/noncore/games/solitaire/freecellcardgame.cpp b/noncore/games/solitaire/freecellcardgame.cpp
index 98415aa..aeb32fc 100644
--- a/noncore/games/solitaire/freecellcardgame.cpp
+++ b/noncore/games/solitaire/freecellcardgame.cpp
@@ -48,48 +48,131 @@ FreecellCardGame::FreecellCardGame(QCanvas *c, bool snap, QWidget *parent) : Can
}
}
void FreecellCardGame::deal(void)
{
highestZ = 1;
beginDealing();
for (int i = 0; i < 52; i++) {
Card *card = cards[i];
card->setFace( TRUE );
card->setPos( 0, 0, highestZ );
card->setCardPile( workingPiles[i%8] );
workingPiles[i%8]->addCardToTop( card );
card->move( workingPiles[i%8]->getCardPos( card ) );
card->showCard();
highestZ++;
}
endDealing();
}
+// checks if smaller card with different color, that could be put on top on the
+// card, is present in working or freecell pile
+bool FreecellCardGame::checkNeeded(Card *card)
+{
+ if (card->getValue() > 2){
+ int i;
+ Card *c;
+ for (i=0;i<4;i++){
+ c = freecellPiles[i]->cardOnBottom();
+ if (c != NULL){
+ if (card->isRed()!= c->isRed() && card->getValue()== c->getValue()+1){
+ return (false);
+ }
+ }
+ }
+ for (i=0;i<8;i++){
+ c=workingPiles[i]->cardOnBottom();
+ while (c!=NULL){
+ if (card->isRed() != c->isRed() && card->getValue() == c->getValue()+1) {
+ return (false);
+ }
+ c=workingPiles[i]->cardInfront(c);
+ }
+ }
+ }
+ return(true);
+}
+
+// added to move cards, on which no card can be moved, to discard pile
+void FreecellCardGame::checkUnusable()
+{
+ int i,j;
+// printf("void FreecellCardGame::checkUnusable()\n");
+ Card *top_one;
+ for (i=0;i < 8;i++)
+ {
+ top_one = workingPiles[i]->cardOnTop();
+ if (top_one != NULL)
+ {
+ j = 0;
+ while ((j < 4))
+ {
+ if (discardPiles[j]->isAllowedOnTop(top_one)){
+ if (checkNeeded(top_one)){
+ top_one->setCardPile(discardPiles[j]);
+ workingPiles[i]->removeCard(top_one);
+// printf("k %d f work%d to disk%d on %d\n ",top_one->getValue(),i+1,j+1,highestZ);
+ discardPiles[j]->addCardToTop(top_one);
+ top_one->setPos(discardPiles[j]->getX(),discardPiles[j]->getY(),highestZ);
+ highestZ++;
+ j = 4;
+ checkUnusable();
+ }
+ }
+ j++;
+ }
+ }
+ }
+ for (i=0;i<4;i++){
+ top_one = freecellPiles[i]->cardOnTop();
+ if (top_one != NULL)
+ {
+ j = 0;
+ while ((j < 4))
+ {
+ if (discardPiles[j]->isAllowedOnTop(top_one)){
+ if (checkNeeded(top_one)){
+ top_one->setCardPile(discardPiles[j]);
+ freecellPiles[i]->removeCard(top_one);
+// printf("k %d f work%d to disk%d on %d\n ",top_one->getValue(),i+1,j+1,highestZ);
+ discardPiles[j]->addCardToTop(top_one);
+ top_one->setPos(discardPiles[j]->getX(),discardPiles[j]->getY(),highestZ);
+ highestZ++;
+ j = 4;
+ checkUnusable();
+ }
+ }
+ j++;
+ }
+ }
+ }
+}
+
bool FreecellCardGame::mousePressCard( Card *c, QPoint p )
{
Q_UNUSED(p);
if ( !c->getCardPile()->isAllowedToBeMoved(c) ) {
moving = NULL;
return TRUE;
}
return FALSE;
}
void FreecellCardGame::readConfig( Config& cfg )
{
cfg.setGroup("GameState");
// Create Cards, but don't shuffle or deal them yet
createDeck();
// Move the cards to their piles (deal them to their previous places)
beginDealing();
diff --git a/noncore/games/solitaire/freecellcardgame.h b/noncore/games/solitaire/freecellcardgame.h
index f1b09ab..2df751b 100644
--- a/noncore/games/solitaire/freecellcardgame.h
+++ b/noncore/games/solitaire/freecellcardgame.h
@@ -25,64 +25,65 @@
extern int numberOfFreeCells;
class FreecellDiscardPile : public PatienceDiscardPile
{
public:
FreecellDiscardPile(int x, int y, QCanvas *canvas) :
PatienceDiscardPile(x, y, canvas) { }
};
class FreecellWorkingPile : public PatienceWorkingPile
{
public:
FreecellWorkingPile(int x, int y, QCanvas *canvas) :
PatienceWorkingPile(x, y, canvas) { }
virtual bool isAllowedOnTop(Card *card) {
if ( cardOnBottom() == NULL ) {
int numberOfCardsBeingMoved = 0;
Card *tempCard = card;
-
+
while ((tempCard != NULL)) {
numberOfCardsBeingMoved++;
tempCard = cardInfront(tempCard);
}
if (numberOfCardsBeingMoved > numberOfFreeCells)
return FALSE;
}
if ( card->isFacing() &&
cardOnTop() == NULL )
return TRUE;
return PatienceWorkingPile::isAllowedOnTop( card );
}
+
virtual bool isAllowedToBeMoved(Card *card) {
int nextExpectedValue = (int)card->getValue();
bool nextExpectedColor = card->isRed();
int numberOfCardsBeingMoved = 0;
while ((card != NULL)) {
numberOfCardsBeingMoved++;
if ( (int)card->getValue() != nextExpectedValue )
return FALSE;
if ( card->isRed() != nextExpectedColor )
return FALSE;
nextExpectedValue--;;
nextExpectedColor = !nextExpectedColor;
card = cardInfront(card);
}
if (numberOfCardsBeingMoved <= (numberOfFreeCells + 1))
return TRUE;
return FALSE;
}
virtual void cardRemoved(Card *card) {
if ( !isDealing() && !cardOnTop() )
numberOfFreeCells++;
@@ -117,36 +118,38 @@ public:
virtual void cardRemoved(Card *card) {
Q_UNUSED(card);
numberOfFreeCells++;
}
};
class FreecellCardGame : public CanvasCardGame
{
public:
FreecellCardGame(QCanvas *c, bool snap, QWidget *parent = 0);
virtual void deal(void);
virtual bool haveWeWon() {
return ( discardPiles[0]->kingOnTop() &&
discardPiles[1]->kingOnTop() &&
discardPiles[2]->kingOnTop() &&
discardPiles[3]->kingOnTop() );
}
virtual void mousePress(QPoint p) { Q_UNUSED(p); }
virtual void mouseRelease(QPoint p) { Q_UNUSED(p); }
// virtual void mouseMove(QPoint p);
virtual bool mousePressCard(Card *card, QPoint p);
virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
// virtual void mouseMoveCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+ virtual void checkUnusable();
void readConfig( Config& cfg );
void writeConfig( Config& cfg );
bool snapOn;
private:
+ bool checkNeeded(Card *card);
FreecellFreecellPile *freecellPiles[8];
FreecellWorkingPile *workingPiles[8];
FreecellDiscardPile *discardPiles[4];
};
#endif