summaryrefslogtreecommitdiffstats
path: root/kpat/mod3.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitc90c389a8a8d9d8661e9772ec4144c5cf2039f23 (patch)
tree6d8391395bce9eaea4ad78958617edb20c6a7573 /kpat/mod3.cpp
downloadtdegames-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.cpp312
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"
+
+//-------------------------------------------------------------------------//
+