/* napoleon.cpp 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. */ #include "napoleon.h" #include #include "deck.h" #include "cardmaps.h" Napoleon::Napoleon( TDEMainWindow* parent, const char* _name ) : Dealer( parent, _name ) { deck = Deck::new_deck( this ); connect(deck, TQT_SIGNAL(clicked(Card *)), TQT_SLOT(deal1(Card*))); pile = new Pile( 1, this ); pile->setAddFlags( Pile::disallow ); for (int i = 0; i < 4; i++) { store[i] = new Pile( 2 + i, this ); store[i]->setCheckIndex( 0 ); target[i] = new Pile( 6 + i, this); target[i]->setRemoveFlags( Pile::disallow ); target[i]->setCheckIndex(2); target[i]->setTarget(true); } const int dist_store = cardMap::CARDX() * 55 / 100; const int dist_target = dist_store / 2; const int centre_x = 10 + cardMap::CARDX() + dist_store; const int centre_y = 10 + cardMap::CARDY() + dist_store; deck->move( centre_x + cardMap::CARDX() * 47 / 10, centre_y + cardMap::CARDY() + dist_store); pile->move( centre_x + cardMap::CARDX() * 33 / 10, centre_y + cardMap::CARDY() + dist_store); centre = new Pile( 10, this ); centre->setRemoveFlags( Pile::disallow ); centre->setCheckIndex(1); centre->setTarget(true); store[0]->move( centre_x, centre_y - cardMap::CARDY() - dist_store ); store[1]->move( centre_x + cardMap::CARDX() + dist_store, centre_y); store[2]->move( centre_x, centre_y + cardMap::CARDY() + dist_store ); store[3]->move( centre_x - cardMap::CARDX() - dist_store, centre_y); target[0]->move( centre_x - cardMap::CARDX() - dist_target, centre_y - cardMap::CARDY() - dist_target ); target[1]->move( centre_x + cardMap::CARDX() + dist_target, centre_y - cardMap::CARDY() - dist_target); target[2]->move( centre_x + cardMap::CARDX() + dist_target, centre_y + cardMap::CARDY() + dist_target); target[3]->move( centre_x - cardMap::CARDX() - dist_target, centre_y + cardMap::CARDY() + dist_target); centre->move(centre_x, centre_y); setActions(Dealer::Hint | Dealer::Demo); } void Napoleon::restart() { deck->collectAndShuffle(); deal(); } bool Napoleon::CanPutTarget( const Pile* c1, const CardList& cl) const { Card *c2 = cl.first(); if (c1->isEmpty()) return c2->rank() == Card::Seven; else return (c2->rank() == c1->top()->rank() + 1); } bool Napoleon::CanPutCentre( const Pile* c1, const CardList& cl) const { Card *c2 = cl.first(); if (c1->isEmpty()) return c2->rank() == Card::Six; if (c1->top()->rank() == Card::Ace) return (c2->rank() == Card::Six); else return (c2->rank() == c1->top()->rank() - 1); } bool Napoleon::checkAdd( int checkIndex, const Pile *c1, const CardList& c2) const { switch (checkIndex) { case 0: return c1->isEmpty(); case 1: return CanPutCentre(c1, c2); case 2: return CanPutTarget(c1, c2); default: return false; } } void Napoleon::deal() { if (deck->isEmpty()) return; for (int i=0; i<4; i++) store[i]->add(deck->nextCard(), false, false); } void Napoleon::deal1(Card *) { Card *c = deck->nextCard(); if (!c) return; pile->add(c, true, false); c->move(deck->x(), deck->y()); c->flipTo(int(pile->x()), int(pile->y()), 8); } Card *Napoleon::demoNewCards() { if (deck->isEmpty()) return 0; deal1(0); return pile->top(); } void Napoleon::getHints() { CardList cards; for (int i = 0; i < 4; i++) { if (!store[i]->isEmpty()) cards.append(store[i]->top()); } if (pile->top()) cards.append(pile->top()); for (CardList::Iterator it = cards.begin(); it != cards.end(); ++it) { CardList empty; empty.append(*it); if (CanPutCentre(centre, empty)) { newHint(new MoveHint(*it, centre)); continue; } for (int i = 0; i < 4; i++) { if (CanPutTarget(target[i], empty)) { newHint(new MoveHint(*it, target[i])); break; } } } if (pile->isEmpty()) return; for (int i = 0; i < 4; i++) { if (store[i]->isEmpty()) { newHint(new MoveHint(pile->top(), store[i])); return; } } } bool Napoleon::isGameLost() const { CardList cards; for (int i = 0; i < 4; i++) { if (store[i]->isEmpty()) return false; else cards.append(store[i]->top()); } if (pile->top()) cards.append(pile->top()); for (CardList::Iterator it = cards.begin(); it != cards.end(); ++it) { CardList empty; empty.append(*it); if(CanPutCentre(centre,empty)) return false; for(int i=0; i<4; i++) if(CanPutTarget(target[i],empty)) return false; } return (deck->isEmpty()); } static class LocalDealerInfo4 : public DealerInfo { public: LocalDealerInfo4() : DealerInfo(I18N_NOOP("&Napoleon's Tomb"), 4) {} virtual Dealer *createGame(TDEMainWindow *parent) { return new Napoleon(parent); } } ldi3; #include "napoleon.moc"