diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | c90c389a8a8d9d8661e9772ec4144c5cf2039f23 (patch) | |
tree | 6d8391395bce9eaea4ad78958617edb20c6a7573 /kpat/mod3.cpp | |
download | tdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.tar.gz tdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdegames@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kpat/mod3.cpp')
-rw-r--r-- | kpat/mod3.cpp | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/kpat/mod3.cpp b/kpat/mod3.cpp new file mode 100644 index 00000000..c69aa8e4 --- /dev/null +++ b/kpat/mod3.cpp @@ -0,0 +1,312 @@ +/*--------------------------------------------------------------------------- + + mod3.cpp implements a patience card game + + Copyright (C) 1997 Rodolfo Borges + + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + +---------------------------------------------------------------------------*/ + +#include "mod3.h" +#include "cardmaps.h" +#include <klocale.h> +#include "deck.h" +#include <kdebug.h> + +//-------------------------------------------------------------------------// + +Mod3::Mod3( KMainWindow* parent, const char* _name) + : Dealer( parent, _name ) +{ + const int dist_x = cardMap::CARDX() * 11 / 10 + 1; + const int dist_y = cardMap::CARDY() * 11 / 10 + 1; + const int margin = cardMap::CARDY() / 3; + + // This patience uses 2 deck of cards. + deck = Deck::new_deck( this, 2); + deck->move(8 + dist_x * 8 + 20, 8 + dist_y * 3 + margin); + + connect(deck, SIGNAL(clicked(Card*)), SLOT(deckClicked(Card*))); + + aces = new Pile(50, this); + aces->move(16 + dist_x * 8, 8 + dist_y / 2); + aces->setTarget(true); + aces->setCheckIndex(2); + aces->setAddFlags(Pile::addSpread | Pile::several); + + for ( int r = 0; r < 4; r++ ) { + for ( int c = 0; c < 8; c++ ) { + stack[r][c] = new Pile ( r * 10 + c + 1, this ); + stack[r][c]->move( 8 + dist_x * c, + 8 + dist_y * r + margin * ( r == 3 )); + + // The first 3 rows are the playing field, the fourth is the store. + if ( r < 3 ) { + stack[r][c]->setCheckIndex( 0 ); + stack[r][c]->setTarget(true); + } else { + stack[r][c]->setAddFlags( Pile::addSpread ); + stack[r][c]->setCheckIndex( 1 ); + } + } + } + + setTakeTargetForHints(true); + setActions(Dealer::Hint | Dealer::Demo ); +} + + +//-------------------------------------------------------------------------// + + +bool Mod3::checkAdd( int checkIndex, const Pile *c1, const CardList& cl) const +{ + // kdDebug(11111) << "checkAdd " << checkIndex << " " << c1->top()->name() << " " << c1->index() << " " << c1->index() / 10 << endl; + if (checkIndex == 0) { + Card *c2 = cl.first(); + + if (c1->isEmpty()) + return (c2->rank() == ( ( c1->index() / 10 ) + 2 ) ); + + kdDebug(11111) << "not empty\n"; + + if (c1->top()->suit() != c2->suit()) + return false; + + kdDebug(11111) << "same suit\n"; + if (c2->rank() != (c1->top()->rank()+3)) + return false; + + kdDebug(11111) << "+3 " << c1->cardsLeft() << " " << c1->top()->rank() << " " << c1->index()+1 << endl; + if (c1->cardsLeft() == 1) + return (c1->top()->rank() == ((c1->index() / 10) + 2)); + + kdDebug(11111) << "+1\n"; + + return true; + } else if (checkIndex == 1) { + return c1->isEmpty(); + } else if (checkIndex == 2) { + return cl.first()->rank() == Card::Ace; + } else return false; +} + + +bool Mod3::checkPrefering( int checkIndex, const Pile *c1, const CardList& c2) const +{ + return (checkIndex == 0 && c1->isEmpty() + && c2.first()->rank() == (c1->index()+1)); +} + + +//-------------------------------------------------------------------------// + + +void Mod3::restart() +{ + deck->collectAndShuffle(); + deal(); +} + + +//-------------------------------------------------------------------------// + + +void Mod3::dealRow(int row) +{ + if (deck->isEmpty()) + return; + + for (int c = 0; c < 8; c++) { + Card *card; + + card = deck->nextCard(); + stack[row][c]->add (card, false, true); + } +} + + +void Mod3::deckClicked(Card*) +{ + kdDebug(11111) << "deck clicked " << deck->cardsLeft() << endl; + if (deck->isEmpty()) + return; + + unmarkAll(); + dealRow(3); + takeState(); +} + + +//-------------------------------------------------------------------------// + + +void Mod3::deal() +{ + unmarkAll(); + CardList list = deck->cards(); +/* for (CardList::Iterator it = list.begin(); it != list.end(); ++it) + if ((*it)->rank() == Card::Ace) { + aces->add(*it); + (*it)->hide(); + } +*/ + kdDebug(11111) << "init " << aces->cardsLeft() << " " << deck->cardsLeft() << endl; + + for (int r = 0; r < 4; r++) + dealRow(r); +} + +Card *Mod3::demoNewCards() +{ + if (deck->isEmpty()) + return 0; + deckClicked(0); + return stack[3][0]->top(); +} + +bool Mod3::startAutoDrop() { + return false; +} + +bool Mod3::isGameLost() const +{ + int n,row,col; + kdDebug(11111) << "isGameLost ?"<< endl; + + bool nextTest=false; + + // If there is an empty stack or an ace below, the game is not lost. + for (col=0; col < 8; col++){ + if (stack[3][col]->isEmpty() + || stack[3][col]->at(0)->rank() == Card::Ace) + return false; + } + + // Ok, so no empty stack below. + // If there is neither an empty stack on the board (an ace counts + // as this) nor a card placed in the correct row, all is lost. + // Otherwise we have to do more tests. + for (n = 0; n < 24; n++) { + row = n / 8; + col = n % 8; + + // If there is a stack on the board that is either empty or + // contains an ace, the game is not finished. + if (stack[row][col]->isEmpty() + || stack[row][col]->at(0)->rank() == Card::Ace) { + nextTest = true; + break; + } + + // If there is a card that is correctly placed, the game is + // not lost. + if (stack[row][col]->at(0)->rank() == Card::Two + row) { + nextTest = true; + break; + } + } + if (!nextTest) + return true; + + // If there are more cards in the deck, the game is not lost. + if (!deck->isEmpty()) + return false; + + int n2, row2, col2, col3; + Card *ctop; + Card *card; + + // For all stacks on the board, check if: + // + for (n = 0; n < 24; n++){ + row = n / 8; + col = n % 8; + + // Empty stack: Can we move a card there? + if (stack[row][col]->isEmpty()) { + // Can we move a card from below? + for (col3=0; col3 < 8; col3++) { + if (stack[3][col3]->top()->rank() == (Card::Two+row)) + return false; + } + + // Can we move a card from another row? + for (n2 = 0; n2 < 16; n2++) { + row2 = (row + 1 + (n2 / 8)) % 3; + col2 = n2 % 8; + + if (stack[row2][col2]->isEmpty()) + continue; + if (stack[row2][col2]->top()->rank() == (Card::Two + row)) + return false; + } + } + else { + // Non-empty stack. + ctop = stack[row][col]->top(); + kdDebug(11111) << "considering ["<<row<<"]["<<col<<"] " << ctop->name() << flush; + + // Card not in its final position? Then we can't build on it. + if (stack[row][col]->at(0)->rank() != Card::Two + row) + continue; + + // Can we move a card from below here? + for (col3 = 0; col3 < 8; col3++) { + card = stack[3][col3]->top(); + if (card->suit() == ctop->suit() + && card->rank() == ctop->rank() + 3) + return false; + } + kdDebug(11111) <<" Can't stack from bottom row" << flush; + + // Can we move a card from another stack here? + for (int n_2 = 1; n_2 < 24; n_2++) { + n2 = (n + n_2) % 24; + row2 = n2 / 8; + col2 = n2 % 8; + + if (stack[row2][col2]->isEmpty()) + continue; + + card = stack[row2][col2]->top(); + + // Only consider cards that are not on top of other cards. + if (stack[row2][col2]->indexOf(card) != 0) + continue; + + if (card->suit() == ctop->suit() + && card->rank() == ctop->rank() + 3) + return false; + } + } + } + + return true; +} + + +static class LocalDealerInfo5 : public DealerInfo +{ +public: + LocalDealerInfo5() : DealerInfo(I18N_NOOP("M&od3"), 5) {} + virtual Dealer *createGame(KMainWindow *parent) { return new Mod3(parent); } +} ldi5; + +//-------------------------------------------------------------------------// + +#include"mod3.moc" + +//-------------------------------------------------------------------------// + |