summaryrefslogtreecommitdiffstats
path: root/kpat/computation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kpat/computation.cpp')
-rw-r--r--kpat/computation.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/kpat/computation.cpp b/kpat/computation.cpp
new file mode 100644
index 00000000..22f104aa
--- /dev/null
+++ b/kpat/computation.cpp
@@ -0,0 +1,120 @@
+/***********************-*-C++-*-********
+
+ computation.h implements a patience card game
+
+ Copyright (C) 1995 Paul Olav Tvete
+
+ * 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.
+
+//
+// This one was discussed on the newsgroup rec.games.abstract
+//
+****************************************/
+
+#include "computation.h"
+#include <klocale.h>
+#include "deck.h"
+#include <assert.h>
+#include "cardmaps.h"
+
+Computation::Computation( KMainWindow *parent, const char *name )
+ :Dealer( parent, name)
+{
+ deck = Deck::new_deck(this);
+ deck->hide();
+
+ for (int i = 0; i < 4; i++) {
+ play[i] = new Pile(1 + i, this);
+ play[i]->move(10 + (i+1) * cardMap::CARDX() * 14 / 10, 10 + cardMap::CARDY() * 15 / 10);
+ play[i]->setAddFlags(Pile::addSpread);
+ play[i]->setCheckIndex(1);
+
+ target[i] = new Pile(5 + i, this);
+ target[i]->move(10 + (i+1) * cardMap::CARDX() * 14 / 10, 10);
+ target[i]->setRemoveFlags(Pile::disallow);
+ target[i]->setCheckIndex(0);
+ target[i]->setTarget(true);
+ }
+
+ pile = new Pile(13, this);
+ pile->setAddFlags(Pile::disallow);
+ pile->setRemoveFlags(Pile::autoTurnTop);
+ pile->move(10, 10);
+
+ setActions(Dealer::Demo | Dealer::Hint);
+}
+
+void Computation::restart() {
+ deck->collectAndShuffle();
+ deal();
+}
+
+void Computation::deal() {
+ while (!deck->isEmpty()) {
+ Card *c = deck->nextCard();
+ pile->add(c, true, false);
+ }
+ // no animation
+ pile->top()->turn(true);
+}
+
+inline bool matches(const CardList &cl, Card *start, int offset)
+{
+ Card *before = start; // maybe 0 for ignore first card
+ for (CardList::ConstIterator it = cl.begin(); it != cl.end(); ++it)
+ {
+ if (before && (*it)->rank() % 13 != (before->rank() + offset) % 13)
+ return false;
+ before = *it;
+ }
+ return true;
+}
+
+bool Computation::checkStore( const Pile*, const CardList& cl) const
+{
+ if (cl.count() != 1)
+ return false;
+ return (cl.first()->source()->index() == 13);
+}
+
+bool Computation::checkAdd( int index, const Pile* c1, const CardList& cl) const
+{
+ if (index == 1)
+ return checkStore(c1, cl);
+
+ assert(c1->index() >= 5 && c1->index() <= 8);
+
+ if ( c1->top() && c1->top()->rank() == Card::King) // finished
+ return false;
+
+ if ( c1->cardsLeft() == 13 )
+ return false;
+
+ int offset = c1->index() - 4;
+
+ if (c1->isEmpty()) {
+ Card::Rank start = static_cast<Card::Rank>(Card::Ace + (offset - 1));
+ return cl.first()->rank() == start && matches(cl, 0, offset);
+ }
+
+ return matches(cl, c1->top(), offset);
+}
+
+static class LocalDealerInfo6 : public DealerInfo
+{
+public:
+ LocalDealerInfo6() : DealerInfo(I18N_NOOP("&Calculation"), 6) {}
+ virtual Dealer *createGame(KMainWindow *parent) { return new Computation(parent); }
+} ldi6;
+
+#include "computation.moc"