diff options
author | Thomas Günther <tom@toms-cafe.de> | 2005-05-15 00:18:18 +0200 |
---|---|---|
committer | Thomas Günther <tom@toms-cafe.de> | 2005-05-15 00:18:18 +0200 |
commit | 1b80a09e835a6cd68d4160f9799a7268e54a5b53 (patch) | |
tree | fa5f92848ed602216ed76ed84980921c9af95a07 /heap.c | |
download | vdr-plugin-spider-1b80a09e835a6cd68d4160f9799a7268e54a5b53.tar.gz vdr-plugin-spider-1b80a09e835a6cd68d4160f9799a7268e54a5b53.tar.bz2 |
Initial versionv0.1.0
Diffstat (limited to 'heap.c')
-rw-r--r-- | heap.c | 302 |
1 files changed, 302 insertions, 0 deletions
@@ -0,0 +1,302 @@ +/* + * Spider-Arachnid: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id$ + */ + +#include "heap.h" +#include "deck.h" + + +/** --- base class Heap ---------------------------------------------------- **/ + +/** Constructor */ +Heap::Heap(unsigned int maxCards) +{ + maxCount = maxCards; + emptyChanged = true; +} + +/** Destructor */ +Heap::~Heap() +{ +} + +/** Current count of cards */ +int Heap::count() const +{ + return allCards.size(); +} + +/** Card in heap */ +const Card& Heap::card(int position) const +{ + return allCards[position]; +} + +/** Top card of the heap */ +const Card& Heap::top() const +{ + return allCards.back(); +} + +/** Add a new card */ +void Heap::add(const Card& card) +{ + if (allCards.size() < maxCount) + { + if (allCards.empty()) + emptyChanged = true; + allCards.push_back(card); + } +} + +/** Remove the top card */ +void Heap::remove() +{ + if (!allCards.empty()) + { + allCards.pop_back(); + if (allCards.empty()) + emptyChanged = true; + } +} + +/** Move some matching cards to an other heap */ +void Heap::moveTo(Heap* other, int countToMove) +{ + for (int i = count() - countToMove; i < count(); ++i) + other->add(card(i)); + for (int i = 0; i < countToMove; ++i) + remove(); +} + +/** Is the heap empty? */ +bool Heap::empty() const +{ + return allCards.empty(); +} + +/** Is the heap changed? */ +bool Heap::changed() const +{ + return emptyChanged; +} + +/** Reset changed property */ +void Heap::resetChanged() +{ + emptyChanged = false; +} + + +/** --- class Pack --------------------------------------------------------- **/ + +/** Constructor */ +Pack::Pack(const Deck& deck) : + Heap(deck.count()) +{ + for (int pos = 0; pos < deck.count(); ++pos) + add(deck.card(pos)); +} + +/** First initial deal of a game */ +void Pack::initialDeal(Piles& piles, int rows, Piles& extra) +{ + for (int r = 0; r < rows; ++r) + deal(piles); + deal(extra); + + // turn all open cards + for (unsigned int p = 0; p < piles.size(); ++p) + piles[p]->turn(); +} + +/** Deal one row to the piles */ +void Pack::deal(Piles& piles) +{ + for (unsigned int p = 0; p < piles.size(); ++p) + { + piles[p]->add(top()); + remove(); + } +} + +/** Cancel the deal */ +void Pack::takeBackDeal(Piles& piles) +{ + for (int p = piles.size(); --p >= 0; ) + { + add(piles[p]->top()); + piles[p]->remove(); + } +} + + +/** --- class Pile --------------------------------------------------------- **/ + +/** Constructor */ +Pile::Pile(const Deck& deck) : + Heap(deck.count()) +{ + currentOpen = 0; + currentMatching = 0; + currentSelected = 0; + currentChanged = 0; +} + +/** Add a new card */ +void Pile::add(const Card& card) +{ + Heap::add(card); + ++currentOpen; + if (topCardsMatches()) + ++currentMatching; + currentSelected = 0; + ++currentChanged; +} + +/** Remove top card from pile */ +void Pile::remove() +{ + if (currentSelected > 0) + --currentSelected; + if (topCardsMatches()) + --currentMatching; + if (currentOpen > 0) + --currentOpen; + Heap::remove(); + if (currentChanged > 0) + --currentChanged; + if (currentChanged < 1 && !empty()) + currentChanged = 1; +} + +/** Turn all open top cards or rather open the top card */ +void Pile::turn() +{ + if (currentOpen < 1 && !empty()) + currentOpen = 1; + else + currentOpen = 0; + currentMatching = 0; + if (currentChanged < 1 && !empty()) + currentChanged = 1; +} + +/** Current count of open cards */ +int Pile::open() const +{ + return currentOpen; +} + +/** Current count of matching cards */ +int Pile::getMatching() const +{ + return currentMatching; +} + +/** The two open top cards are matching */ +bool Pile::topCardsMatches() const +{ + return (open() >= 2 && card(count() - 1).matchesTo(card(count() - 2))); +} + +/** Current count of selected cards */ +int Pile::selected() const +{ + return currentSelected; +} + +/** Select up to max matching cards on the end of this pile */ +void Pile::select(int max) +{ + currentSelected = 0; + if (open() > 0) + { + currentSelected = 1; + for (int i = count(); --i > count() - open(); ) + if (card(i).matchesTo(card(i - 1))) + currentSelected++; + else + break; + } + if (currentSelected > max && max > 0) + currentSelected = max; + if (currentChanged < currentSelected) + currentChanged = currentSelected; +} + +/** Unselect this pile */ +void Pile::unselect() +{ + if (currentChanged < currentSelected) + currentChanged = currentSelected; + currentSelected = 0; +} + +/** Adapt the selection to match an other pile */ +void Pile::adaptSelectionTo(const Pile* other) +{ + if (!other->empty()) + { + if (currentChanged < currentSelected) + currentChanged = currentSelected; + int diff = other->top().rank - top().rank; + if (diff > 0 && diff <= currentSelected) + currentSelected = diff; + else + currentSelected = 0; + } +} + +/** Matches the selection to an other pile? */ +bool Pile::selectionMatchesTo(const Pile* other, bool matchSuit) const +{ + return (!other->empty() && + (other->top().rank == top().rank + currentSelected) && + (other->top().suit == top().suit || !matchSuit)); +} + +/** Is the heap changed? */ +bool Pile::changed() const +{ + return (Heap::changed() || currentChanged > 0); +} + +/** Reset changed property */ +void Pile::resetChanged() +{ + Heap::resetChanged(); + currentChanged = 0; +} + +/** How many cards are changed? */ +int Pile::cardsChanged() const +{ + return currentChanged; +} + + +/** --- class FinalHeap ---------------------------------------------------- **/ + +/** Constructor */ +FinalHeap::FinalHeap(const Deck& deck) : + Heap(deck.cardsInSuit) +{ + bonus = false; +} + +/** Set bonus of the final heap */ +void FinalHeap::setBonus(bool newBonus) +{ + bonus = newBonus; +} + +/** Has this final heap bonus? */ +bool FinalHeap::getBonus() const +{ + return bonus; +} |