27 files changed, 2978 insertions, 0 deletions
diff --git a/noncore/games/solitaire/.cvsignore b/noncore/games/solitaire/.cvsignore new file mode 100644 index 0000000..edfa921 --- a/dev/null +++ b/noncore/games/solitaire/.cvsignore @@ -0,0 +1,3 @@ +moc_* +*.moc +Makefile diff --git a/noncore/games/solitaire/Makefile.in b/noncore/games/solitaire/Makefile.in new file mode 100644 index 0000000..3c50345 --- a/dev/null +++ b/noncore/games/solitaire/Makefile.in @@ -0,0 +1,235 @@ +############################################################################# + +####### Compiler, tools and options + +CXX = $(SYSCONF_CXX) $(QT_CXX_MT) +CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) +CC = $(SYSCONF_CC) $(QT_C_MT) +CFLAGS = $(SYSCONF_CFLAGS) +INCPATH = -I$(QPEDIR)/include +LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) +LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP) +MOC = $(SYSCONF_MOC) +UIC = $(SYSCONF_UIC) + +####### Target + +DESTDIR = $(QPEDIR)/bin/ +VER_MAJ = 1 +VER_MIN = 0 +VER_PATCH = 0 +TARGET = patience +TARGET1 = lib$(TARGET).so.$(VER_MAJ) + +####### Files + +HEADERS = canvascard.h \ + canvasshapes.h \ + cardgame.h \ + cardgamelayout.h \ + cardpile.h \ + card.h \ + carddeck.h \ + canvascardgame.h \ + freecellcardgame.h \ + patiencecardgame.h \ + canvascardwindow.h +SOURCES = canvascard.cpp \ + canvasshapes.cpp \ + cardgame.cpp \ + cardgamelayout.cpp \ + cardpile.cpp \ + card.cpp \ + carddeck.cpp \ + canvascardgame.cpp \ + freecellcardgame.cpp \ + patiencecardgame.cpp \ + canvascardwindow.cpp \ + main.cpp +OBJECTS = canvascard.o \ + canvasshapes.o \ + cardgame.o \ + cardgamelayout.o \ + cardpile.o \ + card.o \ + carddeck.o \ + canvascardgame.o \ + freecellcardgame.o \ + patiencecardgame.o \ + canvascardwindow.o \ + main.o +INTERFACES = +UICDECLS = +UICIMPLS = +SRCMOC = moc_canvascardwindow.cpp +OBJMOC = moc_canvascardwindow.o + + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + + +all: $(DESTDIR)$(TARGET) + +$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) + $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) + +moc: $(SRCMOC) + +tmake: + tmake solitaire.pro + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) + -rm -f *~ core + -rm -f allmoc.cpp + +####### Extension Modules + +listpromodules: + @echo + +listallmodules: + @echo + +listaddonpromodules: + @echo + +listaddonentmodules: + @echo + + +REQUIRES=patience + +####### Sub-libraries + + +###### Combined headers + + + +####### Compile + +canvascard.o: canvascard.cpp \ + cardgame.h \ + card.h \ + cardpile.h \ + carddeck.h \ + cardgamelayout.h \ + canvascard.h \ + $(QPEDIR)/include/qpe/resource.h + +canvasshapes.o: canvasshapes.cpp \ + canvasshapes.h + +cardgame.o: cardgame.cpp \ + cardgame.h \ + card.h \ + cardpile.h \ + carddeck.h \ + cardgamelayout.h + +cardgamelayout.o: cardgamelayout.cpp \ + cardgamelayout.h \ + cardpile.h + +cardpile.o: cardpile.cpp \ + cardpile.h \ + card.h \ + $(QPEDIR)/include/qpe/config.h + +card.o: card.cpp \ + card.h \ + $(QPEDIR)/include/qpe/config.h + +carddeck.o: carddeck.cpp \ + card.h \ + carddeck.h + +canvascardgame.o: canvascardgame.cpp \ + cardgame.h \ + card.h \ + cardpile.h \ + carddeck.h \ + cardgamelayout.h \ + canvasshapes.h \ + canvascard.h \ + canvascardgame.h \ + $(QPEDIR)/include/qpe/resource.h \ + $(QPEDIR)/include/qpe/config.h \ + $(QPEDIR)/include/qpe/qpemenubar.h + +freecellcardgame.o: freecellcardgame.cpp \ + freecellcardgame.h \ + patiencecardgame.h \ + canvascardgame.h \ + cardgame.h \ + card.h \ + cardpile.h \ + carddeck.h \ + cardgamelayout.h \ + canvasshapes.h \ + canvascard.h \ + $(QPEDIR)/include/qpe/resource.h \ + $(QPEDIR)/include/qpe/config.h \ + $(QPEDIR)/include/qpe/qpemenubar.h + +patiencecardgame.o: patiencecardgame.cpp \ + patiencecardgame.h \ + canvascardgame.h \ + cardgame.h \ + card.h \ + cardpile.h \ + carddeck.h \ + cardgamelayout.h \ + canvasshapes.h \ + canvascard.h \ + $(QPEDIR)/include/qpe/resource.h \ + $(QPEDIR)/include/qpe/config.h \ + $(QPEDIR)/include/qpe/qpemenubar.h + +canvascardwindow.o: canvascardwindow.cpp \ + canvascardwindow.h \ + patiencecardgame.h \ + canvascardgame.h \ + cardgame.h \ + card.h \ + cardpile.h \ + carddeck.h \ + cardgamelayout.h \ + canvasshapes.h \ + canvascard.h \ + $(QPEDIR)/include/qpe/resource.h \ + $(QPEDIR)/include/qpe/config.h \ + $(QPEDIR)/include/qpe/qpemenubar.h \ + freecellcardgame.h + +main.o: main.cpp \ + canvascardwindow.h \ + $(QPEDIR)/include/qpe/qpeapplication.h + +moc_canvascardwindow.o: moc_canvascardwindow.cpp \ + canvascardwindow.h + +moc_canvascardwindow.cpp: canvascardwindow.h + $(MOC) canvascardwindow.h -o moc_canvascardwindow.cpp + + diff --git a/noncore/games/solitaire/canvascard.cpp b/noncore/games/solitaire/canvascard.cpp new file mode 100644 index 0000000..ae3c859 --- a/dev/null +++ b/noncore/games/solitaire/canvascard.cpp @@ -0,0 +1,282 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "cardgame.h" +#include "canvascard.h" + +#include <qpe/resource.h> + +#include <qpainter.h> +#include <qimage.h> +#include <qpaintdevice.h> +#include <qbitmap.h> + +#include <math.h> + +#if defined( QT_QWS_CASSIOPEIA ) +#define SLOW_HARDWARE +#endif + +// Seems to be fast enough to me even without Transformations in the library +//#if defined( QT_NO_TRANSFORMATIONS ) && defined( QT_QWS_IPAQ ) +//#define SLOW_HARDWARE +//#endif + + +QBitmap *Create180RotatedBitmap(QBitmap *srcBitmap) +{ +#ifdef QT_NO_TRANSFORMATIONS + int w = srcBitmap->width(); + int h = srcBitmap->height(); + QBitmap *dstBitmap = new QBitmap( w, h ); + // ### this is very poorly implemented and probably could be much faster + for (int i = 0; i < w; i++) + for (int j = 0; j < h; j++) + bitBlt( dstBitmap, i, j, srcBitmap, w - i - 1, h - j - 1, 1, 1 ); + return dstBitmap; +#else + QWMatrix m; + m.rotate( 180.0 ); + return new QBitmap( srcBitmap->xForm( m ) ); +#endif +} + + +QPixmap *CreateScaledPixmap(QPixmap *srcPixmap, double scaleX, double scaleY) +{ +#ifdef QT_NO_TRANSFORMATIONS + int w = srcPixmap->width(); + int h = srcPixmap->height(); + int newW = (int)(w * scaleX); + int newH = (int)(h * scaleY); + QPixmap *dstPixmap = new QPixmap( newW, newH ); + // ### this is very poorly implemented and probably could be much faster + for (int i = 0; i < newW; i++) { + int srcX = w * i / newW; + if (newH == h) { + // Optimise for scaleing in the X-axis only + bitBlt( dstPixmap, i, 0, srcPixmap, srcX, 0, 1, h ); + } else { + for (int j = 0; j < newH; j++) { + int srcY = h * j / newH; + bitBlt( dstPixmap, i, j, srcPixmap, srcX, srcY, 1, 1 ); + } + } + } + return dstPixmap; +#else + QWMatrix s; + s.scale( scaleX, scaleY ); + return new QPixmap( srcPixmap->xForm( s ) ); +#endif +} + + +// Initialise static member variables to NULL +QPixmap *CanvasCard::cardsFaces = NULL; +QPixmap *CanvasCard::cardsBacks = NULL; +QBitmap *CanvasCard::cardsChars = NULL; +QBitmap *CanvasCard::cardsSuits = NULL; +QBitmap *CanvasCard::cardsCharsUpsideDown = NULL; +QBitmap *CanvasCard::cardsSuitsUpsideDown = NULL; + + +CanvasCard::CanvasCard( eValue v, eSuit s, bool f, QCanvas *canvas ) : + Card(v, s, f), QCanvasRectangle( 0, 0, 1, 1, canvas ), cardBack(1), scaleX(1.0), scaleY(1.0) +{ + if ( !cardsFaces ) { + cardsFaces = new QPixmap( Resource::loadPixmap( "cards/card_face" ) ); + cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0001" ) ); + cardsChars = new QBitmap( Resource::loadBitmap( "cards/card_chars" ) ); + cardsSuits = new QBitmap( Resource::loadBitmap( "cards/card_suits" ) ); + cardsCharsUpsideDown = Create180RotatedBitmap( cardsChars ); + cardsSuitsUpsideDown = Create180RotatedBitmap( cardsSuits ); + } + xOff = cardsFaces->width() / 2; + yOff = cardsFaces->height() / 2; + setSize( cardsFaces->width(), cardsFaces->height() ); + setPen( NoPen ); + flipping = FALSE; +} + + +void CanvasCard::setCardBack(int b) +{ + if ( cardBack != b ) { + + cardBack = b; + + if ( cardsBacks ) + delete cardsBacks; + + switch (cardBack) { + case 0: + cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0001" ) ); break; + case 1: + cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0002" ) ); break; + case 2: + cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0003" ) ); break; + case 3: + cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0004" ) ); break; + case 4: + cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0005" ) ); break; + } + + if ( !isFacing() ) + redraw(); + } +} + + +void CanvasCard::draw(QPainter &painter) +{ + int ix = (int)x(), iy = (int)y(); + + QPainter *p = &painter; + QPixmap *unscaledCard = NULL; + + if ((scaleX <= 0.98) || (scaleY <= 0.98)) + { + p = new QPainter(); + unscaledCard = new QPixmap( cardsFaces->width(), cardsFaces->height() ); + p->begin(unscaledCard); + ix = 0; + iy = 0; + } + + if ( isFacing() ) { + +/* + // Now add the joker and card backs to the list of pixmaps + QPixmap *CardsBack = new QPixmap( Resource::loadPixmap( "cards/card_joker.png" ) ); + QPoint *newBackHotspot = new QPoint( 0, 0 ); + pixmaps->append((const QPixmap *)CardsBack); + hotspots->append((const QPoint *)newBackHotspot); +*/ + + int w = cardsFaces->width(), h = cardsFaces->height(); + +// p->setBrush( NoBrush ); + p->setBrush( QColor( 0xFF, 0xFF, 0xFF ) ); + + if ( isRed() == TRUE ) + p->setPen( QColor( 0xFF, 0, 0 ) ); + else + p->setPen( QColor( 0, 0, 0 ) ); + + p->drawPixmap( ix + 0, iy + 0, *cardsFaces ); + p->drawPixmap( ix + 4, iy + 4, *cardsChars, 7*(getValue()-1), 0, 7, 7 ); + p->drawPixmap( ix + 12, iy + 4, *cardsSuits, 7*(getSuit()-1), 0, 7, 8 ); + p->drawPixmap( ix + w-4-7, iy + h-4-7, *cardsCharsUpsideDown, 7*(12-getValue()+1), 0, 7, 7 ); + p->drawPixmap( ix + w-12-7, iy + h-5-7, *cardsSuitsUpsideDown, 7*(3-getSuit()+1), 0, 7, 8 ); + + } else { + + p->drawPixmap( ix, iy, *cardsBacks ); + + } + + if (p != &painter) + { + p->end(); + QPixmap *scaledCard = CreateScaledPixmap( unscaledCard, scaleX, scaleY ); + int xoff = scaledCard->width() / 2; + int yoff = scaledCard->height() / 2; + painter.drawPixmap( (int)x() + xOff - xoff, (int)y() + yOff - yoff, *scaledCard ); + delete p; + delete unscaledCard; + delete scaledCard; + } +} + + +static const double flipLift = 1.5; + + +void CanvasCard::flipTo(int x2, int y2, int steps) +{ + flipSteps = steps; + +#ifdef SLOW_HARDWARE + move(x2,y2); + Card::flipTo(x2,y2,steps); +#else + int x1 = (int)x(); + int y1 = (int)y(); + double dx = x2 - x1; + double dy = y2 - y1; + + flipping = TRUE; + destX = x2; + destY = y2; + animSteps = flipSteps; + setVelocity(dx/animSteps, dy/animSteps-flipLift); + setAnimated(TRUE); +#endif +} + + +void CanvasCard::advance(int stage) +{ + if ( stage==1 ) { + if ( animSteps-- <= 0 ) { + scaleX = 1.0; + scaleY = 1.0; + flipping = FALSE; + setVelocity(0,0); + setAnimated(FALSE); + move(destX,destY); // exact + } else { + if ( flipping ) { + if ( animSteps > flipSteps / 2 ) { + // animSteps = flipSteps .. flipSteps/2 (flip up) -> 1..0 + scaleX = ((double)animSteps/flipSteps-0.5)*2; + } else { + // animSteps = flipSteps/2 .. 0 (flip down) -> 0..1 + scaleX = 1-((double)animSteps/flipSteps)*2; + } + if ( animSteps == flipSteps / 2-1 ) { + setYVelocity(yVelocity()+flipLift*2); + setFace( !isFacing() ); + } + } + } + } + QCanvasRectangle::advance(stage); +} + + +void CanvasCard::animatedMove(int x2, int y2, int steps) +{ + destX = x2; + destY = y2; + + double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1; + + // Ensure a good speed + while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 ) + steps--; + + setAnimated(TRUE); + setVelocity(dx/steps, dy/steps); + + animSteps = steps; +} + diff --git a/noncore/games/solitaire/canvascard.h b/noncore/games/solitaire/canvascard.h new file mode 100644 index 0000000..cd9691f --- a/dev/null +++ b/noncore/games/solitaire/canvascard.h @@ -0,0 +1,82 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef CANVAS_CARD_H +#define CANVAS_CARD_H + + +#include <qpainter.h> +#include <qbitmap.h> +#include <qpixmap.h> +#include <qpoint.h> +#include <qcanvas.h> +#include "cardgame.h" + + +// ### Just made the number up, is that what you do??? +static const int canvasCardId = 2434321; + + +class CanvasCard : public Card, public QCanvasRectangle +{ +public: + CanvasCard( eValue v, eSuit s, bool f, QCanvas *canvas ); + virtual ~CanvasCard() { canvas()->removeItem(this); } + + int rtti () const { return canvasCardId; } + void move(QPoint p) { QCanvasItem::move( p.x(), p.y() ); } + void move(int x, int y) { QCanvasItem::move( x, y ); } + void animatedMove(int x, int y, int steps = 10); + void animatedMove() { animatedMove(savedX, savedY); } + void savePos(void) { savedX = (int)x(); savedY = (int)y(); } + void moveToPile(int p) { Q_UNUSED(p); } + void setCardBack(int b); + + /*virtual*/ void flipTo(int x, int y, int steps = 8); + /*virtual*/ void setPos( int x, int y, int z ) { setX( x ); setY( y ); setZ( z ); } + /*virtual*/ void showCard(void) { show(); } + /*virtual*/ void redraw(void) { hide(); show(); } + /*virtual*/ void draw(QPainter &p); + + void advance(int stage); + +protected: + /*virtual*/ void flip(void) { redraw(); } + +private: + int destX, destY; + int animSteps; + int flipSteps; + bool flipping; + int savedX, savedY; + int cardBack; + int oldCardBack; + double scaleX, scaleY; + int xOff, yOff; + static QPixmap *cardsFaces; + static QPixmap *cardsBacks; + static QBitmap *cardsChars; + static QBitmap *cardsSuits; + static QBitmap *cardsCharsUpsideDown; + static QBitmap *cardsSuitsUpsideDown; +}; + + +#endif + diff --git a/noncore/games/solitaire/canvascardgame.cpp b/noncore/games/solitaire/canvascardgame.cpp new file mode 100644 index 0000000..32635a0 --- a/dev/null +++ b/noncore/games/solitaire/canvascardgame.cpp @@ -0,0 +1,380 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "cardgame.h" +#include "canvasshapes.h" +#include "canvascard.h" +#include "canvascardgame.h" + +#include <qpe/resource.h> +#include <qpe/config.h> + +#include <qmainwindow.h> +#include <qpe/qpemenubar.h> +#include <qpainter.h> + +#include <stdlib.h> +#include <limits.h> +#include <time.h> +#include <math.h> + + +extern int highestZ; + + +class CanvasCardPile : public QCanvasRectangle +{ +public: + CanvasCardPile( CanvasCardGame *ccg, QCanvas *canvas ) : QCanvasRectangle( canvas ), parent( ccg ) { + pile = new QPixmap( 0, 0 ); + pileHeight = 0; + firstCard = NULL; + } + + void addCard( CanvasCard *card ); + void advance(int stage); + void animatedMove() { animatedMove(savedX, savedY); } + void savePos(void) { savedX = (int)x(); savedY = (int)y(); } + void animatedMove(int x2, int y2, int steps = 7 ); + +protected: + virtual void draw( QPainter& p ); + +private: + CanvasCardGame *parent; + QPixmap *pile; + QImage tempImage32; + CanvasCard *firstCard; + int pileHeight; + int destX, destY; + int savedX, savedY; + int animSteps; +}; + + +void CanvasCardPile::addCard( CanvasCard *card ) +{ + if ( !firstCard ) + firstCard = card; + + int height = 36 + pileHeight * 13; + setSize( 23, height ); + pile->resize( 23, height ); + QPainter p( pile ); + p.translate( -card->x(), -card->y() + pileHeight * 13 ); + card->draw( p ); + pileHeight++; + + QImage tempImage; + tempImage = *pile; + tempImage32 = tempImage.convertDepth( 32 ); + tempImage32.setAlphaBuffer( TRUE ); + for ( int i = 0; i < tempImage32.width(); i++ ) + for ( int j = 0; j < tempImage32.height(); j++ ) { + QRgb col = tempImage32.pixel( i, j ); + int a = 255-j*220/tempImage32.height(); + QRgb alpha = qRgba( qRed( col ), qGreen( col ), qBlue( col ), a ); + tempImage32.setPixel( i, j, alpha ); + } + + QRgb alpha = qRgba( 0, 0, 0, 0 ); + tempImage32.setPixel( 1, 0, alpha ); + tempImage32.setPixel( 0, 0, alpha ); + tempImage32.setPixel( 0, 1, alpha ); + + tempImage32.setPixel( 21, 0, alpha ); + tempImage32.setPixel( 22, 0, alpha ); + tempImage32.setPixel( 22, 1, alpha ); + height--; + tempImage32.setPixel( 1, height, alpha ); + tempImage32.setPixel( 0, height - 1, alpha ); + tempImage32.setPixel( 0, height, alpha ); + + tempImage32.setPixel( 21, height, alpha ); + tempImage32.setPixel( 22, height, alpha ); + tempImage32.setPixel( 22, height - 1, alpha ); +} + + +void CanvasCardPile::advance(int stage) +{ + if ( stage==1 ) { + if ( animSteps-- <= 0 ) { + CanvasCard *item = firstCard; + while (item) { + item->show(); + item = (CanvasCard *)item->getCardPile()->cardInfront(item); + } + setVelocity(0,0); + setAnimated(FALSE); + parent->cancelMoving(); + hide(); + move(destX,destY); // exact + } + } + QCanvasRectangle::advance(stage); +} + + +void CanvasCardPile::animatedMove(int x2, int y2, int steps = 7 ) +{ + destX = x2; + destY = y2; + + double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1; + + // Ensure a good speed + while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 ) + steps--; + + setAnimated(TRUE); + setVelocity(dx/steps, dy/steps); + + animSteps = steps; +} + + +void CanvasCardPile::draw( QPainter& p ) +{ + int ix = (int)x(), iy = (int)y(); + p.drawImage( ix, iy, tempImage32 ); +} + + +CanvasCardGame::~CanvasCardGame() { + // the deletion stuff should be fixed now and only deletes + // items created by this CardGame. I haven't verified there are zero + // memory leaks yet + if ( alphaCardPile ) + delete alphaCardPile; +} + + +void CanvasCardGame::gameWon() { + + srand(time(NULL)); + + QCanvasItemList list = canvas()->allItems(); + QCanvasItemList::Iterator it = list.begin(); + + for (; it != list.end(); ++it) { + if ( (*it)->rtti() == canvasCardId ) { + // disperse the cards everywhere + int x = 300 - rand() % 1000; + int y = 300 + rand() % 200; + ((CanvasCard *)*it)->animatedMove( x, y, 50 ); + } + } +} + + +void CanvasCardGame::contentsMousePressEvent(QMouseEvent *e) { + + if ( moving ) + return; + + QCanvasItemList l = canvas()->collisions( e->pos() ); + + for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) { + + if ( (*it)->rtti() == canvasCardId ) { + + moving = (CanvasCard *)*it; + + if ( moving->animated() ) + return; + + cardXOff = (int)(e->pos().x() - moving->x()); + cardYOff = (int)(e->pos().y() - moving->y()); + + if ( !mousePressCard( moving, e->pos() ) ) { + CanvasCard *card = moving; + + if ( alphaCardPile ) + delete alphaCardPile; + + alphaCardPile = new CanvasCardPile( this, canvas() ); + alphaCardPile->move( card->x(), card->y() ); + alphaCardPile->savePos(); + alphaCardPile->show(); + + while (card) { + alphaCardPile->addCard( card ); + card->hide(); + card = (CanvasCard *)card->getCardPile()->cardInfront(card); + } + + alphaCardPile->setZ( INT_MAX ); + + moved = TRUE; + } else { + if ( alphaCardPile ) + alphaCardPile->hide(); + } + return; + } + } + + mousePress( e->pos() ); +} + +/* +// +// Should have some intelligent way to make double clicking on a +// card send it to the most appropriate pile +// +void CanvasCardGame::contentsMouseDoubleClickEvent(QMouseEvent *e) { + QCanvasItemList l = canvas()->collisions( e->pos() ); + for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) { + if ( (*it)->rtti() == canvasCardId ) { + CanvasCard *card = (CanvasCard *)*it; + + if ( card->animated() ) + return; + + if ( card->getCardPile()->isAllowedToBeMoved(card) ) { + if (card->getCardPile()->cardInfront(card) == NULL) { + CardPile *pile = first(); + if (pile && pile->isAllowedOnTop(card)) { + // move card to this pile + return; + } + } + } + } + } +} +*/ + +void CanvasCardGame::contentsMouseMoveEvent(QMouseEvent *e) { + + QPoint p = e->pos(); + + if ( moving ) { + + moved = TRUE; + + if (moving->isFacing() != TRUE) + return; + + int tx = (int)p.x() - cardXOff; + int ty = (int)p.y() - cardYOff; + + if (snapOn == TRUE) { + CardPile *pile = closestPile( tx, ty, 50 ); + if ( pile && pile->isAllowedOnTop( moving ) ) { + QPoint p = pile->getHypertheticalNextCardPos(); + if ( alphaCardPile ) + alphaCardPile->move( p.x(), p.y() ); + return; + } + } + + if ( alphaCardPile ) + alphaCardPile->move( tx, ty ); + } + +} + + +void CanvasCardGame::contentsMouseReleaseEvent(QMouseEvent *e) +{ + QPoint p = e->pos(); + + Q_UNUSED(p); + + if ( moving ) { + + CanvasCard *item = moving; + + if ( item->animated() ) + return; + + if ( alphaCardPile ) + if ( moved ) { + + CardPile *pile = closestPile((int)alphaCardPile->x(), (int)alphaCardPile->y(), 30); + + if (pile && pile->isAllowedOnTop(item)) { + CardPile *oldPile = item->getCardPile(); + Card *c = NULL; + if ( oldPile != pile) { + while ( item ) { + item->show(); + if ( oldPile ) { + c = oldPile->cardInfront(item); + oldPile->removeCard(item); + } + pile->addCardToTop(item); + item->setCardPile(pile); + //item->move( pile->getCardPos(item) ); + QPoint p = pile->getCardPos(item); + item->setPos( p.x(), p.y(), highestZ ); + highestZ++; + + if (item->getValue() == king && haveWeWon()) { + alphaCardPile->hide(); + gameWon(); + moving = NULL; + return; + } + + if (oldPile) { + item = (CanvasCard *)c; + } else { + item = NULL; + } + } + alphaCardPile->hide(); + moving = NULL; + return; + } + } + + alphaCardPile->animatedMove(); + } + } + + moved = FALSE; +} + + +void CanvasCardGame::readPile( Config& cfg, CardPile *pile, QString name, int& highestZ ) +{ + cfg.setGroup( name ); + int numberOfCards = cfg.readNumEntry("NumberOfCards", 0); + Card *card = NULL; + for ( int i = 0; i < numberOfCards; i++ ) { + QString cardStr; + cardStr.sprintf( "%i", i ); + int val = cfg.readNumEntry( "Card" + cardStr ); + bool facing = cfg.readBoolEntry( "CardFacing" + cardStr ); + card = cards[ val ]; + card->setFace(facing); + pile->addCardToTop(card); + card->setCardPile(pile); + QPoint p = pile->getCardPos( card ); + card->setPos( p.x(), p.y(), highestZ ); + card->showCard(); + highestZ++; + } +} + + diff --git a/noncore/games/solitaire/canvascardgame.h b/noncore/games/solitaire/canvascardgame.h new file mode 100644 index 0000000..4d32014 --- a/dev/null +++ b/noncore/games/solitaire/canvascardgame.h @@ -0,0 +1,95 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef CANVAS_CARD_GAME_H +#define CANVAS_CARD_GAME_H + +#include "cardgame.h" +#include "canvasshapes.h" +#include "canvascard.h" + +#include <qpe/resource.h> +#include <qpe/config.h> + +#include <qmainwindow.h> +#include <qpe/qpemenubar.h> +#include <qpainter.h> + +#include <stdlib.h> +#include <time.h> + + +class CanvasCardPile; + + +class CanvasCardGame : public QCanvasView, public CardGame +{ +public: + CanvasCardGame(QCanvas &c, bool snap, QWidget *parent = 0, const char *name = 0, WFlags f = 0) : + QCanvasView( &c, parent, name, f ), + moved(FALSE), + moving(NULL), + alphaCardPile( NULL ), + cardXOff(0), cardYOff(0), + snapOn(snap), + numberToDraw(1) { } + + virtual ~CanvasCardGame(); + + virtual Card *newCard( eValue v, eSuit s, bool f ) { + return new CanvasCard( v, s, f, canvas() ); + } + + virtual void readConfig( Config& cfg ) { Q_UNUSED( cfg ); } + virtual void writeConfig( Config& cfg ) { Q_UNUSED( cfg ); } + + virtual void gameWon(); + virtual bool haveWeWon() { return FALSE; } + + virtual bool mousePressCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); return FALSE; } + virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); } + + void cancelMoving() { moving = NULL; } + void toggleSnap() { snapOn = (snapOn == TRUE) ? FALSE : TRUE; } + void toggleCardsDrawn() { numberToDraw = (numberToDraw == 1) ? 3 : 1; } + int cardsDrawn() { return numberToDraw; } + void setNumberToDraw(int numToDraw) { this->numberToDraw = numToDraw; } + + void readPile( Config& cfg, CardPile *pile, QString name, int& highestZ ); + +protected: + void contentsMousePressEvent(QMouseEvent *e); + void contentsMouseReleaseEvent(QMouseEvent *e); + void contentsMouseMoveEvent(QMouseEvent *e); + +protected: + // Mouse event state variables + bool moved; + CanvasCard *moving; + CanvasCardPile *alphaCardPile; + int cardXOff, cardYOff; + +private: + bool snapOn; + int numberToDraw; +}; + + +#endif + diff --git a/noncore/games/solitaire/canvascardwindow.cpp b/noncore/games/solitaire/canvascardwindow.cpp new file mode 100644 index 0000000..4c365a5 --- a/dev/null +++ b/noncore/games/solitaire/canvascardwindow.cpp @@ -0,0 +1,227 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "canvascardwindow.h" +#include "patiencecardgame.h" +#include "freecellcardgame.h" + +#include <qpe/resource.h> + +#include <qmainwindow.h> +#include <qpopupmenu.h> +#include <qstyle.h> + + +CanvasCardWindow::CanvasCardWindow(QWidget* parent, const char* name, WFlags f) : + QMainWindow(parent, name, f), canvas(230, 260), snapOn(TRUE), cardBack(4), gameType(0), + cardGame(NULL) +{ + setIcon( Resource::loadPixmap( "cards" ) ); + + // Create Playing Area for Games + if ( QPixmap::defaultDepth() < 12 ) { +// canvas.setBackgroundColor(QColor(0x51, 0x74, 0x6B)); +// canvas.setBackgroundColor(QColor(0x20, 0xb0, 0x50)); + canvas.setBackgroundColor(QColor(0x08, 0x98, 0x2D)); + } else { + QPixmap bg; + bg.convertFromImage( Resource::loadImage( "table_pattern" ), ThresholdDither ); + canvas.setBackgroundPixmap(bg); + } + +#if defined( QT_QWS_CASSIOPEIA ) + canvas.setAdvancePeriod(70); +#else + canvas.setAdvancePeriod(30); +#endif + + +#ifdef _PATIENCE_USE_ACCELS_ + QPEMenuBar* menu = menuBar(); + + QPopupMenu* file = new QPopupMenu; + file->insertItem(tr("Patience"), this, SLOT(initPatience()), CTRL+Key_F); + file->insertItem(tr("Freecell"), this, SLOT(initFreecell()), CTRL+Key_F); + menu->insertItem(tr("&Game"), file); + + menu->insertSeparator(); + + settings = new QPopupMenu; + settings->insertItem(tr("&Change Card Backs"), this, SLOT(changeCardBacks()), Key_F2); + snap_id = settings->insertItem(tr("&Snap To Position"), this, SLOT(snapToggle()), Key_F3); + settings->setCheckable(TRUE); + menu->insertItem(tr("&Settings"),settings); + + menu->insertSeparator(); + + QPopupMenu* help = new QPopupMenu; + help->insertItem(tr("&About"), this, SLOT(help()), Key_F1); + help->setItemChecked(dbf_id, TRUE); + menu->insertItem(tr("&Help"),help); +#else + QMenuBar* menu = menuBar(); + + QPopupMenu* file = new QPopupMenu; + file->insertItem(tr("Patience"), this, SLOT(initPatience())); + file->insertItem(tr("Freecell"), this, SLOT(initFreecell())); + menu->insertItem(tr("Play"), file); + + menu->insertSeparator(); + + settings = new QPopupMenu; + settings->setCheckable(TRUE); + settings->insertItem(tr("Change Card Backs"), this, SLOT(changeCardBacks())); + snap_id = settings->insertItem(tr("Snap To Position"), this, SLOT(snapToggle())); + QString m; + + drawId = settings->insertItem(tr("Turn One Card"), this, SLOT(drawnToggle())); + menu->insertItem(tr("Settings"),settings); + +#endif + + menu->show(); + + Config cfg( "Patience" ); + cfg.setGroup( "GlobalSettings" ); + snapOn = cfg.readBoolEntry( "SnapOn", TRUE); + settings->setItemChecked(snap_id, snapOn); + gameType = cfg.readNumEntry( "GameType", -1 ); + drawThree = cfg.readBoolEntry( "DrawThree", TRUE); + if ( gameType == 0 ) { + cardGame = new PatienceCardGame( &canvas, snapOn, this ); + cardGame->setNumberToDraw(drawThree ? 3 : 1); + setCaption(tr("Patience")); + setCentralWidget(cardGame); + cardGame->readConfig( cfg ); + setCardBacks(); + } else if ( gameType == 1 ) { + cardGame = new FreecellCardGame( &canvas, snapOn, this ); + setCaption(tr("Freecell")); + setCentralWidget(cardGame); + //cardGame->newGame(); // Until we know how to handle reading freecell config + cardGame->readConfig( cfg ); + setCardBacks(); + } else { + // Probably there isn't a config file or it is broken + // Start a new game + initPatience(); + } + + updateDraw(); +} + + +CanvasCardWindow::~CanvasCardWindow() +{ + if (cardGame) { + Config cfg("Patience"); + cfg.setGroup( "GlobalSettings" ); + cfg.writeEntry( "GameType", gameType ); + cfg.writeEntry( "SnapOn", snapOn ); + cfg.writeEntry( "DrawThree", drawThree); + cardGame->writeConfig( cfg ); + delete cardGame; + } +} + + +void CanvasCardWindow::resizeEvent(QResizeEvent *) +{ + QSize s = centralWidget()->size(); + int fw = style().defaultFrameWidth(); + canvas.resize( s.width() - fw - 2, s.height() - fw - 2); +} + + +void CanvasCardWindow::initPatience() +{ + // Create New Game + if ( cardGame ) + delete cardGame; + cardGame = new PatienceCardGame( &canvas, snapOn, this ); + cardGame->setNumberToDraw(drawThree ? 3 : 1); + gameType = 0; + setCaption(tr("Patience")); + setCentralWidget(cardGame); + cardGame->newGame(); + setCardBacks(); + updateDraw(); +} + + +void CanvasCardWindow::initFreecell() +{ + // Create New Game + if ( cardGame ) { + delete cardGame; + } + cardGame = new FreecellCardGame( &canvas, snapOn, this ); + gameType = 1; + setCaption(tr("Freecell")); + setCentralWidget(cardGame); + cardGame->newGame(); + setCardBacks(); +} + + +void CanvasCardWindow::snapToggle() +{ + snapOn = !snapOn; + settings->setItemChecked(snap_id, snapOn); + cardGame->toggleSnap(); +} + + +void CanvasCardWindow::drawnToggle() +{ + cardGame->toggleCardsDrawn(); + updateDraw(); +} + +void CanvasCardWindow::updateDraw() { + if(cardGame->cardsDrawn() == 3) + settings->changeItem(drawId, tr("Turn One Card")); + else + settings->changeItem(drawId, tr("Turn Three Cards")); +} + + +void CanvasCardWindow::setCardBacks() +{ + QCanvasItemList l = canvas.allItems(); + + for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) { + if ( (*it)->rtti() == canvasCardId ) + ((CanvasCard *)(*it))->setCardBack( cardBack ); + } +} + + +void CanvasCardWindow::changeCardBacks() +{ + cardBack++; + + if (cardBack == 5) + cardBack = 0; + + setCardBacks(); +} + + diff --git a/noncore/games/solitaire/canvascardwindow.h b/noncore/games/solitaire/canvascardwindow.h new file mode 100644 index 0000000..b75d40a --- a/dev/null +++ b/noncore/games/solitaire/canvascardwindow.h @@ -0,0 +1,70 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef CANVAS_CARD_WINDOW_H +#define CANVAS_CARD_WINDOW_H + + +#include <qmainwindow.h> +#include <qcanvas.h> + + +class CanvasCardGame; +class QPopupMenu; + + +class CanvasCardWindow : public QMainWindow { + Q_OBJECT + +public: + CanvasCardWindow(QWidget* parent=0, const char* name=0, WFlags f=0); + virtual ~CanvasCardWindow(); + +public slots: + void setCardBacks(); + void changeCardBacks(); + void snapToggle(); + void drawnToggle(); + +private slots: + void initFreecell(); + void initPatience(); + +protected: + virtual void resizeEvent(QResizeEvent *e); + + void updateDraw(); +private: + QCanvas canvas; + bool snapOn; + bool drawThree; + int drawId; + int cardBack; + int gameType; + CanvasCardGame *cardGame; + + QPopupMenu* options; + QPopupMenu* settings; + int dbf_id; + int snap_id; +}; + + +#endif + diff --git a/noncore/games/solitaire/canvasshapes.cpp b/noncore/games/solitaire/canvasshapes.cpp new file mode 100644 index 0000000..28d0b4e --- a/dev/null +++ b/noncore/games/solitaire/canvasshapes.cpp @@ -0,0 +1,92 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include <qpainter.h> +#include <qcanvas.h> +#include "canvasshapes.h" + + +CanvasRoundRect::CanvasRoundRect(int x, int y, QCanvas *canvas) : + QCanvasRectangle( x, y, 23, 36, canvas) +{ + setZ(0); + show(); +} + + +void CanvasRoundRect::redraw() +{ + hide(); + show(); +} + + +void CanvasRoundRect::drawShape(QPainter &p) +{ + p.drawRoundRect( (int)x(), (int)y(), 23, 36); +} + + +CanvasCircleOrCross::CanvasCircleOrCross(int x, int y, QCanvas *canvas) : + QCanvasRectangle( x, y, 21, 21, canvas), circleShape(TRUE) +{ + show(); +} + + +void CanvasCircleOrCross::redraw() +{ + hide(); + show(); +} + + +void CanvasCircleOrCross::setCircle() +{ + circleShape = TRUE; + redraw(); +} + + +void CanvasCircleOrCross::setCross() +{ + circleShape = FALSE; + redraw(); +} + + +void CanvasCircleOrCross::drawShape(QPainter &p) +{ + int x1 = (int)x(), y1 = (int)y(); + // Green circle + if (circleShape == TRUE) { + p.setPen( QPen( QColor(0x10, 0xE0, 0x10), 1 ) ); + p.drawEllipse( x1 - 1, y1 - 1, 21, 21); + p.drawEllipse( x1 - 1, y1 - 0, 21, 19); + p.drawEllipse( x1 + 0, y1 + 0, 19, 19); + p.drawEllipse( x1 + 1, y1 + 0, 17, 19); + p.drawEllipse( x1 + 1, y1 + 1, 17, 17); + // Red cross + } else { + p.setPen( QPen( QColor(0xE0, 0x10, 0x10), 5 ) ); + p.drawLine( x1, y1, x1 + 20, y1 + 20); + p.drawLine( x1 + 20, y1, x1, y1 + 20); + } +} + diff --git a/noncore/games/solitaire/canvasshapes.h b/noncore/games/solitaire/canvasshapes.h new file mode 100644 index 0000000..72acf6b --- a/dev/null +++ b/noncore/games/solitaire/canvasshapes.h @@ -0,0 +1,55 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef CANVAS_SHAPES_H +#define CANVAS_SHAPES_H + + +#include <qcanvas.h> + + +class QPainter; + + +class CanvasRoundRect : QCanvasRectangle +{ +public: + CanvasRoundRect(int x, int y, QCanvas *canvas); + void redraw(); +protected: + void drawShape(QPainter &p); +}; + + +class CanvasCircleOrCross : QCanvasRectangle +{ +public: + CanvasCircleOrCross(int x, int y, QCanvas *canvas); + void redraw(); + void setCircle(); + void setCross(); +protected: + void drawShape(QPainter &p); +private: + bool circleShape; +}; + + +#endif + diff --git a/noncore/games/solitaire/card.cpp b/noncore/games/solitaire/card.cpp new file mode 100644 index 0000000..609e280 --- a/dev/null +++ b/noncore/games/solitaire/card.cpp @@ -0,0 +1,53 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "card.h" + +#include <qpe/config.h> + +#include <qpoint.h> +#include <qlist.h> + +/* +Card( eValue v, eSuit s, bool f ) : + val(v), suit(s), faceUp(f), showing(FALSE), ix(0), iy(0), iz(0), cardPile(NULL) { } +virtual ~Card() { } +eValue getValue() { return val; } +eSuit getSuit() { return suit; } +CardPile *getCardPile() { return cardPile; } +bool isFacing() { return faceUp; } +bool isShowing() { return showing; } +bool isRed() { return ((suit == diamonds) || (suit == hearts)); } +int getX(void) { return ix; } +int getY(void) { return iy; } +int getZ(void) { return iz; } +void setCardPile(CardPile *p) { cardPile = p; } +void setFace(bool f) { faceUp = f; } +void flip(void) { flipTo(getX(), getY()); } +virtual void setPos(int x, int y, int z) { ix = x; iy = y; iz = z; } +virtual void move(int x, int y) { ix = x; iy = y; } +virtual void move(QPoint p) { ix = p.x(); iy = p.y(); } +virtual void flipTo(int x, int y, int steps = 8) { ix = x; iy = y; faceUp = !faceUp; redraw(); Q_UNUSED(steps); } +virtual void showCard(void) { showing = TRUE; } +virtual void hideCard(void) { showing = FALSE; } +virtual void redraw(void) { } +*/ + + diff --git a/noncore/games/solitaire/card.h b/noncore/games/solitaire/card.h new file mode 100644 index 0000000..eb30d30 --- a/dev/null +++ b/noncore/games/solitaire/card.h @@ -0,0 +1,84 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef CARD_H +#define CARD_H + + +#include <qpoint.h> + + +class CardPile; + + +enum eSuit { + jokerSuit = 0, clubs, spades, diamonds, hearts +}; + + +enum eValue { + jokerVal = 0, ace, two, three, four, five, + six, seven, eight, nine, ten, jack, queen, king +}; + + +class Card +{ +public: + Card( eValue v, eSuit s, bool f ) : + val(v), suit(s), faceUp(f), showing(FALSE), ix(0), iy(0), iz(0), cardPile(NULL) { } + virtual ~Card() { } + + eValue getValue() { return val; } + eSuit getSuit() { return suit; } + + void setCardPile(CardPile *p) { cardPile = p; } + CardPile *getCardPile() { return cardPile; } + + void setFace(bool f) { faceUp = f; /* flip(); */ } + bool isFacing() { return faceUp; } + + bool isShowing() { return showing; } + bool isRed() { return ((suit == diamonds) || (suit == hearts)); } + + int getX(void) { return ix; } + int getY(void) { return iy; } + int getZ(void) { return iz; } + void flip(void) { flipTo(getX(), getY()); } + + virtual void setPos(int x, int y, int z) { ix = x; iy = y; iz = z; } + virtual void move(int x, int y) { ix = x; iy = y; } + virtual void move(QPoint p) { ix = p.x(); iy = p.y(); } + virtual void flipTo(int x, int y, int steps = 8) { ix = x; iy = y; faceUp = !faceUp; redraw(); Q_UNUSED(steps); } + virtual void showCard(void) { showing = TRUE; } + virtual void hideCard(void) { showing = FALSE; } +protected: + virtual void redraw(void) { } +private: + eValue val; + eSuit suit; + bool faceUp; + bool showing; + int ix, iy, iz; + CardPile *cardPile; +}; + + +#endif + diff --git a/noncore/games/solitaire/carddeck.cpp b/noncore/games/solitaire/carddeck.cpp new file mode 100644 index 0000000..87c043a --- a/dev/null +++ b/noncore/games/solitaire/carddeck.cpp @@ -0,0 +1,81 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include <stdlib.h> +#include <time.h> +#include "card.h" +#include "carddeck.h" + + +CardDeck::CardDeck(int jokers) : numberOfJokers(jokers), deckCreated(FALSE) +{ + cards = new (Card *)[getNumberOfCards()]; +} + + +CardDeck::~CardDeck() +{ + for (int i = 0; i < getNumberOfCards(); i++) + delete cards[i]; + delete cards; +} + + +void CardDeck::createDeck() +{ + if (!deckCreated) { + for (int i = 0; i < 52; i++) + cards[i] = newCard( (eValue)((i % 13) + 1), (eSuit)((i / 13) + 1), FALSE ); + for (int i = 0; i < getNumberOfJokers(); i++) + cards[52 + i] = newCard( jokerVal, jokerSuit, FALSE ); + deckCreated = TRUE; + } +} + + +void CardDeck::shuffle() +{ + srand(time(NULL)); + for (int i = 0; i < getNumberOfCards(); i++) { + int index = rand() % getNumberOfCards(); + Card *tmpCard = cards[i]; + cards[i] = cards[index]; + cards[index] = tmpCard; + } +} + + +int CardDeck::getNumberOfCards() +{ + return 52 + getNumberOfJokers(); +} + + +int CardDeck::getNumberOfJokers() +{ + return numberOfJokers; +} + + +Card *CardDeck::newCard( eValue v, eSuit s, bool f ) +{ + return new Card(v, s, f); +} + + diff --git a/noncore/games/solitaire/carddeck.h b/noncore/games/solitaire/carddeck.h new file mode 100644 index 0000000..9ad35a9 --- a/dev/null +++ b/noncore/games/solitaire/carddeck.h @@ -0,0 +1,49 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef CARD_DECK_H +#define CARD_DECK_H + + +class Card; + + +class CardDeck +{ +public: + CardDeck(int jokers = 0); + virtual ~CardDeck(); + + void createDeck(); + void shuffle(); + int getNumberOfCards(); + int getNumberOfJokers(); + + virtual Card *newCard( eValue v, eSuit s, bool f ); + virtual void deal() { } + + Card **cards; +private: + int numberOfJokers; + bool deckCreated; +}; + + +#endif + diff --git a/noncore/games/solitaire/cardgame.cpp b/noncore/games/solitaire/cardgame.cpp new file mode 100644 index 0000000..b19aeef --- a/dev/null +++ b/noncore/games/solitaire/cardgame.cpp @@ -0,0 +1,35 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "cardgame.h" + + +void CardGame::newGame() +{ + // Create Cards + createDeck(); + + // Shuffle Cards + shuffle(); + + // Deal Cards + deal(); +} + + diff --git a/noncore/games/solitaire/cardgame.h b/noncore/games/solitaire/cardgame.h new file mode 100644 index 0000000..dd7efab --- a/dev/null +++ b/noncore/games/solitaire/cardgame.h @@ -0,0 +1,45 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef CARD_GAME_H +#define CARD_GAME_H + + +#include <qpoint.h> +#include "card.h" +#include "cardpile.h" +#include "carddeck.h" +#include "cardgamelayout.h" + + +class CardGame : public CardGameLayout, public CardDeck +{ +public: + CardGame(int numOfJokers = 0) : CardGameLayout(), CardDeck(numOfJokers) { } + virtual ~CardGame() { } + virtual void newGame(); + virtual void mousePress(QPoint p) { Q_UNUSED(p); } + virtual void mouseRelease(QPoint p) { Q_UNUSED(p); } + virtual void mouseMove(QPoint p) { Q_UNUSED(p); } +private: +}; + + +#endif + diff --git a/noncore/games/solitaire/cardgamelayout.cpp b/noncore/games/solitaire/cardgamelayout.cpp new file mode 100644 index 0000000..1ceee8d --- a/dev/null +++ b/noncore/games/solitaire/cardgamelayout.cpp @@ -0,0 +1,61 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "cardgamelayout.h" + + +CardGameLayout::~CardGameLayout() +{ + // Should I just do setAutoDelete( TRUE ); ? + for (CardPile *p = first(); p != NULL; p = next()) + delete p; +} + + +CardPile *CardGameLayout::closestPile(int x, int y, int maxDistance) +{ + int closestDistance = maxDistance * maxDistance; + CardPile *closestPile = NULL; + + for (CardPile *p = first(); p != NULL; p = next()) { + int d = p->distanceFromNextPos(x, y); + if (d < closestDistance) { + closestDistance = d; + closestPile = p; + } + } + + return closestPile; +} + + +void CardGameLayout::beginDealing() +{ + for (CardPile *p = first(); p != NULL; p = next()) + p->beginDealing(); +} + + +void CardGameLayout::endDealing() +{ + for (CardPile *p = first(); p != NULL; p = next()) + p->endDealing(); +} + + diff --git a/noncore/games/solitaire/cardgamelayout.h b/noncore/games/solitaire/cardgamelayout.h new file mode 100644 index 0000000..bb36e6b --- a/dev/null +++ b/noncore/games/solitaire/cardgamelayout.h @@ -0,0 +1,42 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef CARD_GAME_LAYOUT_H +#define CARD_GAME_LAYOUT_H + + +#include <qlist.h> +#include "cardpile.h" + + +class CardGameLayout : public QList<CardPile> +{ +public: + CardGameLayout() { } + virtual ~CardGameLayout(); + + void addCardPile(CardPile *pile) { append((const CardPile *)pile); } + CardPile *closestPile(int x, int y, int maxDistance); + void beginDealing(); + void endDealing(); +}; + + +#endif + diff --git a/noncore/games/solitaire/cardpile.cpp b/noncore/games/solitaire/cardpile.cpp new file mode 100644 index 0000000..0b738d2 --- a/dev/null +++ b/noncore/games/solitaire/cardpile.cpp @@ -0,0 +1,114 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "cardpile.h" +#include "card.h" + +#include <qpe/config.h> +#include <qpoint.h> + +#include <qlist.h> + + +CardPile::CardPile(int x, int y) : pileX(x), pileY(y), dealing(FALSE) { + pileWidth = 0; + pileHeight = 0; + pileNextX = pileX; + pileNextY = pileY; + pileCenterX = x + pileWidth / 2; + pileCenterY = y + pileHeight / 2; + pileRadius = (pileWidth > pileHeight) ? pileWidth : pileHeight; +} + + +int CardPile::distanceFromPile(int x, int y) { + return (pileCenterX-x)*(pileCenterX-x)+(pileCenterY-y)*(pileCenterY-y); +} + + +int CardPile::distanceFromNextPos(int x, int y) { + return (pileNextX-x)*(pileNextX-x)+(pileNextY-y)*(pileNextY-y); +} + + +Card *CardPile::cardInfront(Card *c) { + CardPile *p = c->getCardPile(); + if (p) { + p->at(p->find(c)); + return p->next(); + } else { + return NULL; + } +} + + +bool CardPile::kingOnTop() { + Card *top = cardOnTop(); + return top && top->getValue() == king; +} + + +bool CardPile::addCardToTop(Card *c) { + if (dealing || isAllowedOnTop(c)) { + append((const Card *)c); + cardAddedToTop(c); + return TRUE; + } + return FALSE; +} + + +bool CardPile::addCardToBottom(Card *c) { + if (dealing || isAllowedOnBottom(c)) { + prepend((const Card *)c); + cardAddedToBottom(c); + return TRUE; + } + return FALSE; +} + + +bool CardPile::removeCard(Card *c) { + if (dealing || isAllowedToBeMoved(c)) { + take(find(c)); + cardRemoved(c); + return TRUE; + } + return FALSE; +} + + +void CardPile::writeConfig( Config& cfg, QString name ) { + int numberOfCards = 0; + cfg.setGroup( name ); + Card *card = cardOnBottom(); + while ( card ) { + QString cardStr; + cardStr.sprintf( "%i", numberOfCards ); + int val = (int)card->getValue() - 1 + ( (int)card->getSuit() - 1 ) * 13; + cfg.writeEntry( "Card" + cardStr, val ); + cfg.writeEntry( "CardFacing" + cardStr, card->isFacing() ); + card = cardInfront( card ); + numberOfCards++; + } + cfg.writeEntry("NumberOfCards", numberOfCards); +} + + diff --git a/noncore/games/solitaire/cardpile.h b/noncore/games/solitaire/cardpile.h new file mode 100644 index 0000000..c515bbc --- a/dev/null +++ b/noncore/games/solitaire/cardpile.h @@ -0,0 +1,101 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef CARD_PILE_H +#define CARD_PILE_H + + +#include <qpoint.h> +#include <qlist.h> + + +enum ePileStackingType { + pileCascades = 0, pileStacks, pileCascadesOrStacks +}; + + +enum ePileFaceingType { + pileFaceUp = 0, pileFaceDown, pileFaceUpOrDown +}; + + +class Card; +class Config; + + +class CardPile : public QList<Card> +{ +public: + CardPile(int x, int y); + virtual ~CardPile() { } + + int getX() { return pileX; } + int getY() { return pileY; } + int getNextX() { return pileNextX; } + int getNextY() { return pileNextY; } + int getWidth() { return pileWidth; } + int getHeight() { return pileHeight; } + + void setX(int x) { pileX = x; } + void setY(int y) { pileY = y; } + void setNextX(int x) { pileNextX = x; } + void setNextY(int y) { pileNextY = y; } + void setWidth(int width) { pileWidth = width; } + void setHeight(int height) { pileHeight = height; } + + void beginDealing() { dealing = TRUE; } + void endDealing() { dealing = FALSE; } + bool isDealing() { return dealing; } + + int distanceFromPile(int x, int y); + int distanceFromNextPos(int x, int y); + + Card *cardOnTop() { return getLast(); } + Card *cardOnBottom() { return getFirst(); } + Card *cardInfront(Card *c); + bool kingOnTop(); + + bool addCardToTop(Card *c); + bool addCardToBottom(Card *c); + bool removeCard(Card *c); + + virtual void cardAddedToTop(Card *) { } + virtual void cardAddedToBottom(Card *) { } + virtual void cardRemoved(Card *) { } + virtual bool isAllowedOnTop(Card *) { return FALSE; } + virtual bool isAllowedOnBottom(Card *) { return FALSE; } + virtual bool isAllowedToBeMoved(Card *) { return FALSE; } + virtual QPoint getCardPos(Card *) { return QPoint(pileX, pileY); } + virtual QPoint getHypertheticalNextCardPos() { return QPoint(pileX, pileY); } + + void writeConfig( Config& cfg, QString name ); + +protected: + int pileX, pileY; + int pileNextX, pileNextY; + int pileWidth, pileHeight; + int pileCenterX, pileCenterY; + int pileRadius; +private: + bool dealing; +}; + + +#endif + diff --git a/noncore/games/solitaire/freecellcardgame.cpp b/noncore/games/solitaire/freecellcardgame.cpp new file mode 100644 index 0000000..e82afd4 --- a/dev/null +++ b/noncore/games/solitaire/freecellcardgame.cpp @@ -0,0 +1,137 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "freecellcardgame.h" + + +extern int highestZ; +int numberOfFreeCells = 4; + + +FreecellCardGame::FreecellCardGame(QCanvas *c, bool snap, QWidget *parent) : CanvasCardGame(*c, snap, parent) +{ + numberOfFreeCells = 4; + highestZ = 0; + + for (int i = 0; i < 4; i++) { + freecellPiles[i] = new FreecellFreecellPile( 5 + i * 28, 10, canvas() ); + addCardPile(freecellPiles[i]); + } + for (int i = 0; i < 4; i++) { + discardPiles[i] = new FreecellDiscardPile( 125 + i * 28, 10, canvas() ); + addCardPile(discardPiles[i]); + } + for (int i = 0; i < 8; i++) { + workingPiles[i] = new FreecellWorkingPile( 10 + i * 28, 50, canvas() ); + addCardPile(workingPiles[i]); + } +} + + +void FreecellCardGame::deal(void) +{ + highestZ = 1; + + beginDealing(); + + for (int i = 0; i < 52; i++) { + Card *card = cards[i]; + card->setFace( TRUE ); + card->setPos( 0, 0, highestZ ); + card->setCardPile( workingPiles[i%8] ); + workingPiles[i%8]->addCardToTop( card ); + card->move( workingPiles[i%8]->getCardPos( card ) ); + card->showCard(); + highestZ++; + } + + endDealing(); +} + + +bool FreecellCardGame::mousePressCard( Card *c, QPoint p ) +{ + Q_UNUSED(p); + + if ( !c->getCardPile()->isAllowedToBeMoved(c) ) { + moving = NULL; + return TRUE; + } + + return FALSE; +} + + +void FreecellCardGame::readConfig( Config& cfg ) +{ + cfg.setGroup("GameState"); + + // Create Cards, but don't shuffle or deal them yet + createDeck(); + + // Move the cards to their piles (deal them to their previous places) + beginDealing(); + + highestZ = 1; + + for (int k = 0; k < 4; k++) { + QString pile; + pile.sprintf( "FreeCellPile%i", k ); + readPile( cfg, freecellPiles[k], pile, highestZ ); + } + + for (int k = 0; k < 4; k++) { + QString pile; + pile.sprintf( "DiscardPile%i", k ); + readPile( cfg, discardPiles[k], pile, highestZ ); + } + + for (int k = 0; k < 8; k++) { + QString pile; + pile.sprintf( "WorkingPile%i", k ); + readPile( cfg, workingPiles[k], pile, highestZ ); + } + + highestZ++; + + endDealing(); +} + + +void FreecellCardGame::writeConfig( Config& cfg ) +{ + cfg.setGroup("GameState"); + for ( int i = 0; i < 4; i++ ) { + QString pile; + pile.sprintf( "FreeCellPile%i", i ); + freecellPiles[i]->writeConfig( cfg, pile ); + } + for ( int i = 0; i < 4; i++ ) { + QString pile; + pile.sprintf( "DiscardPile%i", i ); + discardPiles[i]->writeConfig( cfg, pile ); + } + for ( int i = 0; i < 8; i++ ) { + QString pile; + pile.sprintf( "WorkingPile%i", i ); + workingPiles[i]->writeConfig( cfg, pile ); + } +} + + diff --git a/noncore/games/solitaire/freecellcardgame.h b/noncore/games/solitaire/freecellcardgame.h new file mode 100644 index 0000000..f1b09ab --- a/dev/null +++ b/noncore/games/solitaire/freecellcardgame.h @@ -0,0 +1,152 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef FREECELL_CARD_GAME_H +#define FREECELL_CARD_GAME_H + + +#include "patiencecardgame.h" + + +extern int numberOfFreeCells; + + +class FreecellDiscardPile : public PatienceDiscardPile +{ +public: + FreecellDiscardPile(int x, int y, QCanvas *canvas) : + PatienceDiscardPile(x, y, canvas) { } + +}; + + +class FreecellWorkingPile : public PatienceWorkingPile +{ +public: + FreecellWorkingPile(int x, int y, QCanvas *canvas) : + PatienceWorkingPile(x, y, canvas) { } + + virtual bool isAllowedOnTop(Card *card) { + if ( cardOnBottom() == NULL ) { + int numberOfCardsBeingMoved = 0; + Card *tempCard = card; + + while ((tempCard != NULL)) { + numberOfCardsBeingMoved++; + tempCard = cardInfront(tempCard); + } + + if (numberOfCardsBeingMoved > numberOfFreeCells) + return FALSE; + } + + if ( card->isFacing() && + cardOnTop() == NULL ) + return TRUE; + return PatienceWorkingPile::isAllowedOnTop( card ); + } + + virtual bool isAllowedToBeMoved(Card *card) { + int nextExpectedValue = (int)card->getValue(); + bool nextExpectedColor = card->isRed(); + int numberOfCardsBeingMoved = 0; + + while ((card != NULL)) { + numberOfCardsBeingMoved++; + if ( (int)card->getValue() != nextExpectedValue ) + return FALSE; + if ( card->isRed() != nextExpectedColor ) + return FALSE; + nextExpectedValue--;; + nextExpectedColor = !nextExpectedColor; + card = cardInfront(card); + } + + if (numberOfCardsBeingMoved <= (numberOfFreeCells + 1)) + return TRUE; + + return FALSE; + } + virtual void cardRemoved(Card *card) { + if ( !isDealing() && !cardOnTop() ) + numberOfFreeCells++; + PatienceWorkingPile::cardRemoved( card ); + } + virtual void cardAddedToTop(Card *card) { + if ( !isDealing() && cardOnBottom() == card ) + numberOfFreeCells--; + PatienceWorkingPile::cardAddedToTop( card ); + } +}; + + +class FreecellFreecellPile : public CardPile, public CanvasRoundRect +{ +public: + FreecellFreecellPile(int x, int y, QCanvas *canvas) + : CardPile(x, y), CanvasRoundRect(x, y, canvas) { } + virtual bool isAllowedOnTop(Card *card) { + if ( ( cardOnTop() == NULL ) && ( card->getCardPile()->cardInfront(card) == NULL ) ) + return TRUE; + return FALSE; + } + virtual bool isAllowedToBeMoved(Card *card) { + Q_UNUSED(card); + return TRUE; + } + virtual void cardAddedToTop(Card *card) { + Q_UNUSED(card); + numberOfFreeCells--; + } + virtual void cardRemoved(Card *card) { + Q_UNUSED(card); + numberOfFreeCells++; + } +}; + + +class FreecellCardGame : public CanvasCardGame +{ +public: + FreecellCardGame(QCanvas *c, bool snap, QWidget *parent = 0); + virtual void deal(void); + virtual bool haveWeWon() { + return ( discardPiles[0]->kingOnTop() && + discardPiles[1]->kingOnTop() && + discardPiles[2]->kingOnTop() && + discardPiles[3]->kingOnTop() ); + } + virtual void mousePress(QPoint p) { Q_UNUSED(p); } + virtual void mouseRelease(QPoint p) { Q_UNUSED(p); } +// virtual void mouseMove(QPoint p); + virtual bool mousePressCard(Card *card, QPoint p); + virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); } +// virtual void mouseMoveCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); } + void readConfig( Config& cfg ); + void writeConfig( Config& cfg ); + bool snapOn; +private: + FreecellFreecellPile *freecellPiles[8]; + FreecellWorkingPile *workingPiles[8]; + FreecellDiscardPile *discardPiles[4]; +}; + + +#endif + diff --git a/noncore/games/solitaire/main.cpp b/noncore/games/solitaire/main.cpp new file mode 100644 index 0000000..f81aa3c --- a/dev/null +++ b/noncore/games/solitaire/main.cpp @@ -0,0 +1,36 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "canvascardwindow.h" + +#include <qpe/qpeapplication.h> + + +int main( int argc, char ** argv ) +{ + QPEApplication a( argc, argv ); + + CanvasCardWindow m; + m.setCaption( CanvasCardWindow::tr("Patience") ); + a.showMainWidget( &m ); + + return a.exec(); +} + diff --git a/noncore/games/solitaire/patiencecardgame.cpp b/noncore/games/solitaire/patiencecardgame.cpp new file mode 100644 index 0000000..5a9326a --- a/dev/null +++ b/noncore/games/solitaire/patiencecardgame.cpp @@ -0,0 +1,234 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "patiencecardgame.h" + + +int highestZ = 0; + + +PatienceCardGame::PatienceCardGame(QCanvas *c, bool snap, QWidget *parent) : CanvasCardGame(*c, snap, parent) +{ + numberOfTimesThroughDeck = 0; + highestZ = 0; + + circleCross = new CanvasCircleOrCross( 7, 18, canvas() ); + rectangle = new CanvasRoundRect( 35, 10, canvas() ); + + for (int i = 0; i < 4; i++) { + discardPiles[i] = new PatienceDiscardPile( 110 + i * 30, 10, canvas() ); + addCardPile(discardPiles[i]); + } + for (int i = 0; i < 7; i++) { + workingPiles[i] = new PatienceWorkingPile( 10 + i * 30, 50, canvas() ); + addCardPile(workingPiles[i]); + } + faceDownDealingPile = new PatienceFaceDownDeck( 5, 10, canvas() ); + faceUpDealingPile = new PatienceFaceUpDeck( 35, 10, canvas() ); +} + + +PatienceCardGame::~PatienceCardGame() +{ + delete circleCross; + delete rectangle; + delete faceDownDealingPile; + delete faceUpDealingPile; +} + + +void PatienceCardGame::deal(void) +{ + highestZ = 1; + int t = 0; + + beginDealing(); + + for (int i = 0; i < 7; i++) { + cards[t]->setFace(TRUE); + for (int k = i; k < 7; k++, t++) { + Card *card = cards[t]; + workingPiles[k]->addCardToTop(card); + card->setCardPile( workingPiles[k] ); + QPoint p = workingPiles[k]->getCardPos( card ); + card->setPos( p.x(), p.y(), highestZ ); + card->showCard(); + highestZ++; + } + } + + for ( ; t < 52; t++) { + Card *card = cards[t]; + faceDownDealingPile->addCardToTop(card); + card->setCardPile( faceDownDealingPile ); + QPoint p = faceDownDealingPile->getCardPos( card ); + card->setPos( p.x(), p.y(), highestZ ); + card->showCard(); + highestZ++; + } + + endDealing(); +} + + +void PatienceCardGame::readConfig( Config& cfg ) +{ + cfg.setGroup("GameState"); + + // Do we have a config file to read in? + if ( !cfg.hasKey("numberOfTimesThroughDeck") ) { + // if not, create a new game + newGame(); + return; + } + // We have a config file, lets read it in and use it + + // Create Cards, but don't shuffle or deal them yet + createDeck(); + + // How many times through the deck have we been + numberOfTimesThroughDeck = cfg.readNumEntry("NumberOfTimesThroughDeck"); + + // restore state to the circle/cross under the dealing pile + if ( canTurnOverDeck() ) + circleCross->setCircle(); + else + circleCross->setCross(); + + // Move the cards to their piles (deal them to their previous places) + beginDealing(); + + highestZ = 1; + + for (int k = 0; k < 7; k++) { + QString pile; + pile.sprintf( "WorkingPile%i", k ); + readPile( cfg, workingPiles[k], pile, highestZ ); + } + + for (int k = 0; k < 4; k++) { + QString pile; + pile.sprintf( "DiscardPile%i", k ); + readPile( cfg, discardPiles[k], pile, highestZ ); + } + + readPile( cfg, faceDownDealingPile, "FaceDownDealingPile", highestZ ); + readPile( cfg, faceUpDealingPile, "FaceUpDealingPile", highestZ ); + + highestZ++; + + endDealing(); +} + + +void PatienceCardGame::writeConfig( Config& cfg ) +{ + cfg.setGroup("GameState"); + cfg.writeEntry("numberOfTimesThroughDeck", numberOfTimesThroughDeck); + + for ( int i = 0; i < 7; i++ ) { + QString pile; + pile.sprintf( "WorkingPile%i", i ); + workingPiles[i]->writeConfig( cfg, pile ); + } + for ( int i = 0; i < 4; i++ ) { + QString pile; + pile.sprintf( "DiscardPile%i", i ); + discardPiles[i]->writeConfig( cfg, pile ); + } + faceDownDealingPile->writeConfig( cfg, "FaceDownDealingPile" ); + faceUpDealingPile->writeConfig( cfg, "FaceUpDealingPile" ); +} + + +bool PatienceCardGame::mousePressCard( Card *card, QPoint p ) +{ + Q_UNUSED(p); + + CanvasCard *item = (CanvasCard *)card; + if (item->isFacing() != TRUE) { + // From facedown stack + if ((item->x() == 5) && ((int)item->y() == 10)) { + item->setZ(highestZ); + highestZ++; + + // Added Code + faceDownDealingPile->removeCard(item); + faceUpDealingPile->addCardToTop(item); + item->setCardPile( faceUpDealingPile ); + + item->flipTo( 35, (int)item->y() ); + } + moving = NULL; + moved = FALSE; + + // move two other cards if we flip three at a time + int flipped = 1; + QCanvasItemList l = canvas()->collisions( p ); + for (QCanvasItemList::Iterator it = l.begin(); (it != l.end()) && (flipped != cardsDrawn()); ++it) { + if ( (*it)->rtti() == canvasCardId ) { + CanvasCard *item = (CanvasCard *)*it; + if (item->animated()) + continue; + item->setZ(highestZ); + highestZ++; + flipped++; + + // Added Code + faceDownDealingPile->removeCard(item); + faceUpDealingPile->addCardToTop(item); + item->setCardPile( faceUpDealingPile ); + + item->flipTo( 35, (int)item->y(), 8 * flipped ); + } + } + + return TRUE; + } + + return FALSE; +} + + +void PatienceCardGame::mousePress(QPoint p) +{ + if ( canTurnOverDeck() && + (p.x() > 5) && (p.x() < 28) && + (p.y() > 10) && (p.y() < 46) ) { + + beginDealing(); + Card *card = faceUpDealingPile->cardOnTop(); + while ( card ) { + card->setPos( 5, 10, highestZ ); + card->setFace( FALSE ); + faceUpDealingPile->removeCard( card ); + faceDownDealingPile->addCardToTop( card ); + card->setCardPile( faceDownDealingPile ); + card = faceUpDealingPile->cardOnTop(); + highestZ++; + } + endDealing(); + + throughDeck(); + + moved = TRUE; + } +} + + diff --git a/noncore/games/solitaire/patiencecardgame.h b/noncore/games/solitaire/patiencecardgame.h new file mode 100644 index 0000000..c4f6c48 --- a/dev/null +++ b/noncore/games/solitaire/patiencecardgame.h @@ -0,0 +1,206 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef PATIENCE_CARD_GAME_H +#define PATIENCE_CARD_GAME_H + + +#include <qpopupmenu.h> +#include <qmainwindow.h> +#include <qintdict.h> +#include <qcanvas.h> +// #include "canvascardshapes.h" +// #include "canvascard.h" +#include "canvascardgame.h" + + +class PatienceFaceDownDeck : public CardPile, public CanvasRoundRect +{ +public: + PatienceFaceDownDeck(int x, int y, QCanvas *canvas) + : CardPile(x, y), CanvasRoundRect(x, y, canvas) { } + virtual bool isAllowedOnTop(Card *card) { + Q_UNUSED(card); + // Need to check it is from the faceUpDealingPile + return TRUE; + } + virtual bool isAllowedToBeMoved(Card *card) { + Q_UNUSED(card); + //if ( ( !card->isFacing() ) && ( card == cardOnTop() ) ) + if ( card == cardOnTop() ) + return TRUE; + return FALSE; + } +}; + + +class PatienceFaceUpDeck : public CardPile, public CanvasRoundRect +{ +public: + PatienceFaceUpDeck(int x, int y, QCanvas *canvas) + : CardPile(x, y), CanvasRoundRect(x, y, canvas) { } + virtual bool isAllowedOnTop(Card *card) { + Q_UNUSED(card); + // Need to check it is from the faceDownDealingPile + return TRUE; + } + virtual bool isAllowedToBeMoved(Card *card) { + Q_UNUSED(card); + //if ( ( card->isFacing() ) && ( card == cardOnTop() ) ) + if ( card == cardOnTop() ) + return TRUE; + return FALSE; + } +}; + + +class PatienceDiscardPile : public CardPile, public CanvasRoundRect +{ +public: + PatienceDiscardPile(int x, int y, QCanvas *canvas) + : CardPile(x, y), CanvasRoundRect(x, y, canvas) { } + virtual bool isAllowedOnTop(Card *card) { + if ( card->isFacing() && ( card->getCardPile()->cardInfront(card) == NULL ) && + ( ( ( cardOnTop() == NULL ) && ( card->getValue() == ace ) ) || + ( ( cardOnTop() != NULL ) && + ( (int)card->getValue() == (int)cardOnTop()->getValue() + 1 ) && + ( card->getSuit() == cardOnTop()->getSuit() ) ) ) ) + return TRUE; + return FALSE; + } + virtual bool isAllowedToBeMoved(Card *card) { + if ( card->isFacing() && ( card == cardOnTop() ) ) + return TRUE; + return FALSE; + } +}; + + +class PatienceWorkingPile : public CardPile, public CanvasRoundRect +{ +public: + PatienceWorkingPile(int x, int y, QCanvas *canvas) + : CardPile(x, y), CanvasRoundRect(x, y, canvas), top(x, y) { } + virtual bool isAllowedOnTop(Card *card) { + if ( card->isFacing() && + ( ( ( cardOnTop() == NULL ) && (card->getValue() == king) ) || + ( ( cardOnTop() != NULL ) && + ( (int)card->getValue() + 1 == (int)cardOnTop()->getValue() ) && + ( card->isRed() != cardOnTop()->isRed() ) ) ) ) + return TRUE; + return FALSE; + } + virtual bool isAllowedToBeMoved(Card *card) { + if ( card->isFacing() ) + return TRUE; + return FALSE; + } + virtual void cardAddedToTop(Card *card) { + Q_UNUSED(card); + top = getCardPos(NULL); + setNextX( top.x() ); + setNextY( top.y() ); + } + virtual void cardRemoved(Card *card) { + Q_UNUSED(card); + + Card *newTopCard = cardOnTop(); + + if ( !newTopCard ) { + top = QPoint( pileX, pileY ); + setNextX( pileX ); + setNextY( pileY ); + return; + } else { + top = getCardPos(NULL); + if ( newTopCard->isFacing() == FALSE ) { + // correct the position taking in to account the card is not + // yet flipped, but will become flipped + top = QPoint( top.x() - 1, top.y() - 3 ); + newTopCard->flipTo( top.x(), top.y() ); + top = QPoint( top.x(), top.y() + 13 ); + } + setNextX( top.x() ); + setNextY( top.y() ); + } + } + virtual QPoint getCardPos(Card *c) { + int x = pileX, y = pileY; + Card *card = cardOnBottom(); + while ((card != c) && (card != NULL)) { + if (card->isFacing()) { + y += 13; + } else { + x += 1; + y += 3; + } + card = cardInfront(card); + } + return QPoint( x, y ); + } + virtual QPoint getHypertheticalNextCardPos(void) { + return top; + // return QPoint( getNextX(), getNextY() ); + } +private: + QPoint top; + +}; + + +class PatienceCardGame : public CanvasCardGame +{ +public: + PatienceCardGame(QCanvas *c, bool snap, QWidget *parent = 0); + virtual ~PatienceCardGame(); + virtual void deal(void); + virtual bool haveWeWon() { + return ( discardPiles[0]->kingOnTop() && + discardPiles[1]->kingOnTop() && + discardPiles[2]->kingOnTop() && + discardPiles[3]->kingOnTop() );; + } + virtual void mousePress(QPoint p); + virtual void mouseRelease(QPoint p) { Q_UNUSED(p); } +// virtual void mouseMove(QPoint p); + virtual bool mousePressCard(Card *card, QPoint p); + virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); } +// virtual void mouseMoveCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); } + bool canTurnOverDeck(void) { return (numberOfTimesThroughDeck != 3); } + void throughDeck(void) { + numberOfTimesThroughDeck++; + if (numberOfTimesThroughDeck == 3) + circleCross->setCross(); + } + bool snapOn; + virtual void writeConfig( Config& cfg ); + virtual void readConfig( Config& cfg ); +private: + CanvasCircleOrCross *circleCross; + CanvasRoundRect *rectangle; + PatienceWorkingPile *workingPiles[7]; + PatienceDiscardPile *discardPiles[4]; + PatienceFaceDownDeck *faceDownDealingPile; + PatienceFaceUpDeck *faceUpDealingPile; + int numberOfTimesThroughDeck; +}; + + +#endif + diff --git a/noncore/games/solitaire/qpe-solitaire.control b/noncore/games/solitaire/qpe-solitaire.control new file mode 100644 index 0000000..71abb0c --- a/dev/null +++ b/noncore/games/solitaire/qpe-solitaire.control @@ -0,0 +1,9 @@ +Files: bin/patience apps/Games/patience.desktop pics/cards +Priority: optional +Section: qpe/games +Maintainer: Warwick Allison <warwick@trolltech.com> +Architecture: arm +Version: $QPE_VERSION-3 +Depends: qpe-base ($QPE_VERSION) +Description: Game: solitaire card games + A solitaire game for the Qtopia environment. diff --git a/noncore/games/solitaire/solitaire.pro b/noncore/games/solitaire/solitaire.pro new file mode 100755 index 0000000..8617cab --- a/dev/null +++ b/noncore/games/solitaire/solitaire.pro @@ -0,0 +1,18 @@ +TEMPLATE = app + +CONFIG += qt warn_on release +DESTDIR = $(QPEDIR)/bin + +HEADERS = canvascard.h canvasshapes.h cardgame.h cardgamelayout.h cardpile.h card.h carddeck.h canvascardgame.h freecellcardgame.h patiencecardgame.h canvascardwindow.h + +SOURCES = canvascard.cpp canvasshapes.cpp cardgame.cpp cardgamelayout.cpp cardpile.cpp card.cpp carddeck.cpp canvascardgame.cpp freecellcardgame.cpp patiencecardgame.cpp canvascardwindow.cpp main.cpp + +TARGET = patience + +INCLUDEPATH += $(QPEDIR)/include +DEPENDPATH += $(QPEDIR)/include +LIBS += -lqpe + +REQUIRES = patience + +TRANSLATIONS = ../i18n/de/patience.ts |