added patience plugin

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2245 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
defnax 2010-02-08 22:33:14 +00:00
parent 024e7f4b44
commit 0b78ed6ff8
430 changed files with 7336 additions and 0 deletions

View File

@ -0,0 +1,59 @@
#include "Ablagestapel.h"
#include "Karte.h"
#include "Proportionen.h"
#include "Scene.h"
using namespace std;
Ablagestapel::Ablagestapel(const QPixmap& pixmap, Scene* oparent, QGraphicsItem* gparent) : Basisstapel(pixmap, oparent, gparent)
{
}
Ablagestapel::~Ablagestapel()
{
}
QPointF Ablagestapel::ablageposition() const
{
QPointF erg;
// im ablagestapel sollen die karten aufgefaechert abgelegt werden, deshalb YDRIFT hinzufuegen. die position ist relative zum parent grafik objekt
if (kartenliste.size() > 0) erg.setY(boundingRect().height() / ABLAGESTAPEL_YDRIFT_VERHAELTNIS);
return erg;
}
bool Ablagestapel::ablage_moeglich(Karte* karte) const
{
bool erg = false;
if (Basisstapel::ablage_moeglich(karte) == true && ((oberste_karte() == 0 && karte->wert() == 13) || (oberste_karte() != 0 && oberste_karte()->farbe() != karte->farbe() && karte->wert() == (oberste_karte()->wert() - 1)))) erg = true;
if (erg == true && oberste_karte() != 0)
{
if (karte->farbe() == KARTEN_KREUTZ && oberste_karte()->farbe() == KARTEN_PIK) erg = false;
else if (karte->farbe() == KARTEN_PIK && oberste_karte()->farbe() == KARTEN_KREUTZ) erg = false;
else if (karte->farbe() == KARTEN_HERZ && oberste_karte()->farbe() == KARTEN_KARO) erg = false;
else if (karte->farbe() == KARTEN_KARO && oberste_karte()->farbe() == KARTEN_HERZ) erg = false;
}
return erg;
}
void Ablagestapel::passe_groesse_an(double wert)
{
if (oberste_karte() != 0) oberste_karte()->nach_hause();
Basisstapel::passe_groesse_an(wert);
for (register int idx = 1; idx < kartenliste.size(); idx++)
{
kartenliste.at(idx)->setPos(kartenliste.at(idx)->pos().x(), (double) boundingRect().height() / ABLAGESTAPEL_YDRIFT_VERHAELTNIS);
kartenliste.at(idx)->speichere_zuhause();
}
}

View File

@ -0,0 +1,23 @@
#ifndef ABLAGESTAPEL_H
#define ABLAGESTAPEL_H
#include "Basisstapel.h"
class Ablagestapel : public Basisstapel
{
Q_OBJECT
public:
Ablagestapel(const QPixmap& pixmap, Scene* oparent, QGraphicsItem* gparent = 0);
virtual ~Ablagestapel();
virtual bool ablage_moeglich(Karte*) const;
public slots:
virtual void passe_groesse_an(double);
protected:
virtual QPointF ablageposition() const;
};
#endif

View File

@ -0,0 +1,141 @@
#include "Austeilcostapel.h"
#include "Karte.h"
#include "Proportionen.h"
#include "Scene.h"
using namespace std;
Austeilcostapel::Austeilcostapel(const QPixmap& pixmap, Scene* oparent, QGraphicsItem* gparent) : Basisstapel(pixmap, oparent, gparent), austeilstapel(0), ablagenummer(0)
{
}
Austeilcostapel::~Austeilcostapel()
{
}
void Austeilcostapel::registriere_austeilstapel(Basisstapel* stapel)
{
austeilstapel = stapel;
}
bool Austeilcostapel::ablage_moeglich(Karte * karte) const
{
bool erg = false;
if (karte->eigentuemer_stapel()->objectName() == BASISSTAPEL_AUSTEILSTAPEL) erg = true;
return erg;
}
QPointF Austeilcostapel::ablageposition() const
{
QPointF erg(Basisstapel::ablageposition());
// wenn drei karten gezogen werden und die ablagenummer groesser als 0 ist eine drift nach rechts zur position hinzufuegen
if (nur_eine_wird_gezogen() == false && ablagenummer > 0) erg.setX(erg.x() + (boundingRect().width() / AUSTEILCOSTAPEL_XDRIFT_VERHAELTNIS));
return erg;
}
bool Austeilcostapel::lege_karte_ab(Karte* karte)
{
bool erg = false;
// nur, wenn eine ablage ueberhaupt moeglich ist
if (ablage_moeglich(karte) == true)
{
if (nur_eine_wird_gezogen() == false && oberste_karte() != 0) oberste_karte()->setFlag(QGraphicsItem::ItemIsMovable, false);
// wenn bereits 3 karten aufgefaechert daliegen
if (nur_eine_wird_gezogen() == false && ablagenummer == 3)
{
// ablagenummer wieder zuruecksetzen (die nachste karte wird ohne drift eingefuegt)
ablagenummer = 0;
// die bisher im stapel befindlichen karten sollen ohne drift am stapel liegen
alle_karten_einreihen();
}
erg = Basisstapel::lege_karte_ab(karte);
// wenn drei karten gezogen werden die ablagenummer um 1 erhoehen
if (nur_eine_wird_gezogen() == false) ablagenummer++;
}
return erg;
}
void Austeilcostapel::alle_karten_einreihen()
{
// von allen karten im stapel die drift entfernen
for (register int idx = 0; idx < kartenliste.size(); idx++) kartenliste.at(idx)->setPos(0, 0);
}
void Austeilcostapel::resette_ablagenummer()
{
// die ablagenummer zuruecksetzen
ablagenummer = 0;
// von allen karten im stapel die drift entfernen
alle_karten_einreihen();
}
void Austeilcostapel::entferne_karte(Karte* karte)
{
Basisstapel::entferne_karte(karte);
if (oberste_karte() != 0) oberste_karte()->setFlag(QGraphicsItem::ItemIsMovable);
}
void Austeilcostapel::hilfsanfrage_start(Karte*)
{
}
const QStringList Austeilcostapel::speichere() const
{
QStringList erg(Basisstapel::speichere());
// die ablegenummer speichern
erg.append(QString::number(ablagenummer));
return erg;
}
bool Austeilcostapel::lade(const QStringList& daten)
{
bool erg = Basisstapel::lade(daten);
if (erg == true && daten.size() >= AUSTEILSTAPEL_ANZAHL_SPEICHERELEMENTE)
{
// die ablagenummer laden
ablagenummer = daten.at(AUSTEILSTAPEL_ABLAGENUMMER_IDX).toInt();
}
return erg;
}
void Austeilcostapel::passe_groesse_an(double wert)
{
if (oberste_karte() != 0) oberste_karte()->nach_hause();
Basisstapel::passe_groesse_an(wert);
for (register int idx1 = kartenliste.size() - 1, idx2 = 0; eine_wird_gezogen() == false && idx1 > 0 && idx2 < ablagenummer; idx1--, idx2++)
{
kartenliste.at(idx1)->setPos(QPointF(boundingRect().width() / AUSTEILCOSTAPEL_XDRIFT_VERHAELTNIS, kartenliste.at(idx1)->pos().y()));
kartenliste.at(idx1)->speichere_zuhause();
}
}

View File

@ -0,0 +1,37 @@
#ifndef AUSTEILCOSTAPEL_H
#define AUSTEILCOSTAPEL_H
#include "Basisstapel.h"
class Austeilcostapel : public Basisstapel
{
Q_OBJECT
public:
Austeilcostapel(const QPixmap& pixmap, Scene* oparent, QGraphicsItem* gparent = 0);
virtual ~Austeilcostapel();
virtual void registriere_austeilstapel(Basisstapel*);
virtual bool ablage_moeglich(Karte *) const;
virtual bool lege_karte_ab(Karte*);
virtual void entferne_karte(Karte*);
virtual const QStringList speichere() const;
virtual bool lade(const QStringList&);
public slots:
virtual void resette_ablagenummer();
virtual void hilfsanfrage_start(Karte*);
virtual void passe_groesse_an(double);
private:
Basisstapel *austeilstapel;
bool nur_eine_ziehen;
virtual void alle_karten_einreihen();
protected:
int ablagenummer;
virtual QPointF ablageposition() const;
};
#endif

View File

@ -0,0 +1,100 @@
#include "Austeilstapel.h"
#include "Karte.h"
#include "Proportionen.h"
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
using namespace std;
Austeilstapel::Austeilstapel(const QPixmap& pixmap, Scene* oparent , QGraphicsItem* gparent) : Basisstapel(pixmap, oparent , gparent), costapel(0)
{
}
Austeilstapel::~Austeilstapel()
{
}
void Austeilstapel::registriere_costapel(Basisstapel* costapel_)
{
costapel = costapel_;
}
void Austeilstapel::karte_wurde_aufgedeckt(Karte* karte)
{
Basisstapel::karte_wurde_aufgedeckt(karte);
costapel->lege_karte_ab(karte);
// nur, wenn drei karten gezogen werden
if (nur_eine_wird_gezogen() == false)
{
// zwei weitere karten ...
for (register int idx = 0; idx < 2 && oberste_karte() != 0; idx++)
{
Karte *tmp_karte = oberste_karte();
// ... auf costapel legen, ...
costapel->lege_karte_ab(tmp_karte);
// ... und dort aufdecken
tmp_karte->zeige_vorderseite();
}
// die neue oberste karte auf costapel beweglich machen
if (costapel->oberste_karte() != 0) costapel->oberste_karte()->setFlag(QGraphicsItem::ItemIsMovable);
}
normalisiere_zwert();
}
bool Austeilstapel::ablage_moeglich(Karte *karte) const
{
bool erg = false;
if (karte->eigentuemer_stapel()->objectName() == BASISSTAPEL_AUSTEILCOSTAPEL && karte->ist_rueckseite() == true) erg = true;
return erg;
}
void Austeilstapel::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
QGraphicsPixmapItem::mousePressEvent(event);
if (event->button() == Qt::LeftButton)
{
if (kartenliste.isEmpty() == true)
{
if (nur_eine_wird_gezogen() == false) costapel->resette_ablagenummer();
while (costapel->karten() > 0)
{
costapel->oberste_karte()->zeige_rueckseite();
lege_karte_ab(costapel->oberste_karte());
}
if (kartenliste.isEmpty() == false) emit stapel_durch();
}
// sicherstellen, das die scene aktualisiert wird. ist dies ein fehler in QT ???
scene()->update();
}
}
void Austeilstapel::hilfsanfrage_start(Karte*)
{
}
void Austeilstapel::undo_karten_ablage(Karte* karte)
{
karte->zeige_rueckseite();
Basisstapel::undo_karten_ablage(karte);
}

View File

@ -0,0 +1,28 @@
#ifndef AUSTEILSTAPEL_H
#define AUSTEILSTAPEL_H
#include "Basisstapel.h"
class Austeilstapel : public Basisstapel
{
Q_OBJECT
public:
Austeilstapel(const QPixmap& pixmap, Scene* oparent, QGraphicsItem* gparent = 0);
virtual ~Austeilstapel();
virtual void registriere_costapel(Basisstapel*);
virtual void karte_wurde_aufgedeckt(Karte*);
virtual bool ablage_moeglich(Karte*) const;
virtual void undo_karten_ablage(Karte*);
public slots:
virtual void hilfsanfrage_start(Karte*);
private:
Basisstapel *costapel;
virtual void mousePressEvent(QGraphicsSceneMouseEvent*);
};
#endif

View File

@ -0,0 +1,410 @@
#include "Basisstapel.h"
#include "Karte.h"
#include "Rahmen.h"
#include "Hilfszeiger.h"
#include "Scene.h"
#include "Proportionen.h"
using namespace std;
Basisstapel::Basisstapel(const QPixmap& pixmap, Scene* oparent, QGraphicsItem* gparent) : QObject(oparent), QGraphicsPixmapItem(pixmap, gparent), meine_scene(oparent), nur_eine_ziehen(true), meinrahmen(0), meinhilfszeiger(0), bild(pixmap), bild_skaliert(pixmap), stapelgroesse(pixmap.height())
{
// den hilfszeiger erstellen
meinhilfszeiger = new Hilfszeiger(this);
meinhilfszeiger->hide();
}
Basisstapel::~Basisstapel()
{
}
bool Basisstapel::lege_karte_ab(Karte* karte)
{
bool erg = false;
if (ablage_moeglich(karte) == true)
{
erg = true;
Basisstapel *quelle(karte->eigentuemer_stapel());
// die oberste karte,oder den stapel, wenn keine karte vorhanden ist zum parent der karte machen
if (oberste_karte() == 0) karte->setParentItem(this);
else karte->setParentItem(oberste_karte());
// die position der karte einstellen
karte->setPos(ablageposition());
// die karte aus dem alten stapel entfernen
karte->eigentuemer_stapel()->entferne_karte(karte);
// der karten den stapel, zu der sie jetzt gehoert mitteilen
karte->setze_meinstapel(this);
// die rueckkehrposition der karte anpassen
karte->setze_rueckehrkoordinaten(karte->pos());
// den zwert der karte setzen
karte->setZValue(zwert());
// die karte in die kartenliste einfuegen
kartenliste.append(karte);
// die kinder karten der karten ebenfalls ablegen
lege_child_karten_ab(karte);
emit zug(Zug(karte, quelle, this));
ablage_erfolgt();
}
return erg;
}
bool Basisstapel::beruehrungstest(Karte* karte)
{
return gesamt_rect().intersects(karte->gesamt_rect());
}
bool Basisstapel::ablage_moeglich(Karte* karte) const
{
bool erg = false;
if ((oberste_karte() == 0 || (oberste_karte() != 0 && oberste_karte()->ist_vorderseite() == true)) && karte->eigentuemer_stapel() != this) erg = true;
return erg;
}
QPointF Basisstapel::ablageposition() const
{
return QPointF(0, 0);
}
void Basisstapel::initialisiere_karte(Karte* karte)
{
// die oberste karte,oder den stapel wenn keine karte vorhanden ist zum parent der karte machen
if (oberste_karte() == 0) karte->setParentItem(this);
else karte->setParentItem(oberste_karte());
// die position der karte einstellen
karte->setPos(ablageposition());
// der karten den stapel, zu der sie jetzt gehoert mitteilen
karte->setze_meinstapel(this);
// die rueckkehrposition der karte anpassen
karte->setze_rueckehrkoordinaten(karte->pos());
// den zwert der karte setzen
karte->setZValue(zwert());
// die karte in die kartenliste einfuegen
kartenliste.append(karte);
}
int Basisstapel::zwert() const
{
int erg = zValue();
if (kartenliste.isEmpty() == false) erg = kartenliste.last()->zValue();
erg++;
return erg;
}
Karte* Basisstapel::oberste_karte() const
{
Karte* erg = 0;
if (kartenliste.isEmpty() == false) erg = kartenliste.last();
return erg;
}
bool Basisstapel::ist_oberste_karte(Karte* karte)
{
bool erg = false;
if (oberste_karte() != 0 && oberste_karte() == karte) erg = true;
return erg;
}
void Basisstapel::entferne_karte(Karte* karte)
{
if (kartenliste.contains(karte) == true) kartenliste.removeAll(karte);
}
void Basisstapel::karte_wurde_aufgedeckt(Karte* karte)
{
emit zug(Zug(karte, this));
}
void Basisstapel::lege_child_karten_ab(Karte* karte)
{
QList<Karte*> kinder(karte->kinderkarten());
for (register int idx = 0; idx < kinder.size(); idx++)
{
// die position der karte einstellen
kinder.at(idx)->setPos(ablageposition());
// die karte aus dem alten stapel entfernen
kinder.at(idx)->eigentuemer_stapel()->entferne_karte(kinder.at(idx));
// der karten den stapel, zu der sie jetzt gehoert mitteilen
kinder.at(idx)->setze_meinstapel(this);
// die rueckkehrposition der karte anpassen
kinder.at(idx)->setze_rueckehrkoordinaten(kinder.at(idx)->pos());
// den zwert der karte setzen
kinder.at(idx)->setZValue(zwert());
// die karte in die kartenliste einfuegen
kartenliste.append(kinder.at(idx));
}
}
void Basisstapel::erhoehe_zwert()
{
setZValue(1000);
}
void Basisstapel::normalisiere_zwert()
{
setZValue(0);
}
int Basisstapel::karten() const
{
return kartenliste.size();
}
void Basisstapel::setze_kartenliste_zurueck()
{
kartenliste.clear();
}
void Basisstapel::ablage_erfolgt()
{
}
QRectF Basisstapel::gesamt_rect() const
{
QRectF erg(sceneBoundingRect());
if (oberste_karte() != 0) erg.setBottomRight(oberste_karte()->sceneBoundingRect().bottomRight());
return erg;
}
int Basisstapel::ueberlappungs_flaeche(Karte* karte)
{
QRectF ueberlappung_rect(gesamt_rect().intersect(karte->gesamt_rect()));
return ueberlappung_rect.width() * ueberlappung_rect.height();
}
bool Basisstapel::nur_eine_wird_gezogen() const
{
return nur_eine_ziehen;
}
void Basisstapel::eine_ziehen()
{
nur_eine_ziehen = true;
}
void Basisstapel::drei_ziehen()
{
nur_eine_ziehen = false;
}
void Basisstapel::registriere_costapel(Basisstapel*)
{
}
void Basisstapel::registriere_austeilstapel(Basisstapel*)
{
}
void Basisstapel::resette_ablagenummer()
{
}
void Basisstapel::alle_karten_einreihen()
{
}
void Basisstapel::registriere_siegkontrolle(Siegkontrolle*)
{
}
void Basisstapel::registriere_nachbar_zielstapel(Basisstapel*, Basisstapel*, Basisstapel*)
{
}
void Basisstapel::registriere_rahmen(Rahmen *rahmen)
{
meinrahmen = rahmen;
}
void Basisstapel::zeige_rahmen()
{
if (meinrahmen != 0)
{
QPointF position(scenePos());
if (oberste_karte() != 0) position = oberste_karte()->scenePos();
meinrahmen->zeige(this, position);
}
}
void Basisstapel::hilfsanfrage_start(Karte* karte)
{
// wenn die ablage der karte moeglich ist
if (ablage_moeglich(karte) == true)
{
// die position des hilfszeiger setzen
meinhilfszeiger->setPos(QPointF(boundingRect().width() / 2 - meinhilfszeiger->boundingRect().width() / 2, gesamt_rect().height() + stapelgroesse / BASISSTAPEL_ABSTAND_HILFSZEIGER_VERHAELTNIS));
meinhilfszeiger->show();
}
}
void Basisstapel::hilfsanfrage_ende()
{
// den hilfszeiger verstecken
meinhilfszeiger->hide();
}
void Basisstapel::undo_karten_ablage(Karte* karte)
{
// die oberste karte,oder den stapel, wenn keine karte vorhanden ist zum parent der karte machen
if (oberste_karte() == 0) karte->setParentItem(this);
else karte->setParentItem(oberste_karte());
// die position der karte einstellen
karte->setPos(ablageposition());
// die karte aus dem alten stapel entfernen
karte->eigentuemer_stapel()->entferne_karte(karte);
// der karten den stapel, zu der sie jetzt gehoert mitteilen
karte->setze_meinstapel(this);
// die rueckkehrposition der karte anpassen
karte->setze_rueckehrkoordinaten(karte->pos());
// den zwert der karte setzen
karte->setZValue(zwert());
// die karte in die kartenliste einfuegen
kartenliste.append(karte);
// die kinder karten der karten ebenfalls ablegen
lege_child_karten_ab(karte);
}
const QStringList Basisstapel::speichere() const
{
QStringList erg;
// den namen des stapels als id speichern
erg.append(objectName());
// die enthaltenen karten speichern
QString karten;
for (register int idx = 0; idx < kartenliste.size(); idx++)
{
if (idx > 0) karten.append(BASISSTAPEL_KARTEN_SPLITTER);
karten.append(kartenliste.at(idx)->objectName());
}
erg.append(karten);
return erg;
}
bool Basisstapel::lade(const QStringList& daten)
{
bool erg = false;
if (daten.size() >= BASISSTAPEL_ANZAHL_SPEICHERELEMENTE && daten.first() == objectName())
{
erg = true;
// die enthaltenen karten laden und an den stapel anhaengen
QStringList karten(daten.at(BASISSTAPEL_KARTEN_IDX).split(BASISSTAPEL_KARTEN_SPLITTER, QString::SkipEmptyParts));
for (register int idx = 0; idx < karten.size(); idx++)
{
Karte *karte = meine_scene->suche_karte(karten.at(idx));
if (karte == 0) erg = false;
else initialisiere_karte(karte);
}
}
return erg;
}
void Basisstapel::passe_groesse_an(double wert)
{
stapelgroesse = wert;
bild_skaliert = bild.scaledToHeight(stapelgroesse, Qt::SmoothTransformation);
setPixmap(bild_skaliert);
// auch den hiflszeiger und den rahmen anpassen
if (meinhilfszeiger != 0) meinhilfszeiger->passe_groesse_an(boundingRect());
if (meinrahmen != 0) meinrahmen->passe_groesse_an(boundingRect());
}
bool Basisstapel::eine_wird_gezogen()
{
return nur_eine_ziehen;
}

View File

@ -0,0 +1,85 @@
#ifndef BASISSTAPEL_H
#define BASISSTAPEL_H
#include "Zug.h"
#include <QGraphicsPixmapItem>
#include <QObject>
#include <QPixmap>
#include <QList>
#include <QPointF>
#include <QRectF>
class Karte;
class Siegkontrolle;
class Rahmen;
class Hilfszeiger;
class Scene;
class Basisstapel : public QObject, public QGraphicsPixmapItem
{
Q_OBJECT
public:
Basisstapel(const QPixmap& pixmap, Scene* oparent, QGraphicsItem* gparent = 0);
virtual ~Basisstapel();
void registriere_rahmen(Rahmen*);
void zeige_rahmen();
virtual bool beruehrungstest(Karte*);
virtual Karte* oberste_karte() const;
virtual bool ist_oberste_karte(Karte*);
virtual void lege_child_karten_ab(Karte*);
virtual void erhoehe_zwert();
virtual void normalisiere_zwert();
virtual int karten() const;
virtual void setze_kartenliste_zurueck();
virtual QRectF gesamt_rect() const;
virtual int ueberlappungs_flaeche(Karte*);
virtual bool nur_eine_wird_gezogen() const;
virtual bool ablage_moeglich(Karte *) const;
virtual bool lege_karte_ab(Karte*);
virtual void undo_karten_ablage(Karte*);
virtual void initialisiere_karte(Karte*);
virtual void karte_wurde_aufgedeckt(Karte*);
virtual void ablage_erfolgt();
virtual void entferne_karte(Karte*);
virtual void registriere_costapel(Basisstapel*);
virtual void registriere_austeilstapel(Basisstapel*);
virtual void resette_ablagenummer();
virtual void registriere_siegkontrolle(Siegkontrolle*);
virtual void registriere_nachbar_zielstapel(Basisstapel*, Basisstapel*, Basisstapel*);
virtual const QStringList speichere() const;
virtual bool lade(const QStringList&);
bool eine_wird_gezogen();
public slots:
virtual void eine_ziehen();
virtual void drei_ziehen();
virtual void hilfsanfrage_start(Karte*);
virtual void hilfsanfrage_ende();
virtual void passe_groesse_an(double);
signals:
void zug(const Zug&);
void stapel_durch();
protected:
QList<Karte*> kartenliste;
virtual QPointF ablageposition() const;
virtual int zwert() const;
private:
Scene *meine_scene;
bool nur_eine_ziehen;
Rahmen *meinrahmen;
Hilfszeiger *meinhilfszeiger;
QPixmap bild, bild_skaliert;
double stapelgroesse;
virtual void alle_karten_einreihen();
};
#endif

View File

@ -0,0 +1,180 @@
#include "Highscore.h"
#include "Proportionen.h"
#include <QTableWidgetItem>
#include <QStringList>
#include <QDir>
#include <QInputDialog>
#include <QSettings>
using namespace std;
Highscore::Highscore(QWidget *parent) : QDialog(parent), einstellungen(0)
{
setupUi(this);
tabelle->setRowCount(HIGHSCORE_ZEILEN);
// die tabelle mit elementen befuellen
for (register int idx1 = 0; idx1 < tabelle->rowCount(); idx1++)
{
for (register int idx2 = 0; idx2 <= HIGHSCORE_ZEIT_POSITION; idx2++)
{
QTableWidgetItem *tmp_item = new QTableWidgetItem();
tmp_item->setText(HIGHSCORE_LEER);
tabelle->setItem(idx1, idx2, tmp_item);
}
}
}
Highscore::~Highscore()
{
}
bool Highscore::neues_ergebnis(int punkte, long sekunden)
{
bool erg = false;
int ziel = -1;
for (register int idx = HIGHSCORE_ZEILEN - 1; idx >= 0; idx--)
{
int element_sekundenverbrauch = 0, element_ergebnis = 0;
QStringList tmp_zeit(tabelle->item(idx, HIGHSCORE_ZEIT_POSITION)->text().split(HIGHSCORE_SPLITTER, QString::SkipEmptyParts));
// wenn das element an idx leer ist ist es auf jeden fall unterlegen
if (tabelle->item(idx, HIGHSCORE_NAME_POSITION)->text() == HIGHSCORE_LEER || tabelle->item(idx, HIGHSCORE_PUNKTE_POSITION)->text() == HIGHSCORE_LEER || tabelle->item(idx, HIGHSCORE_ZEIT_POSITION)->text() == HIGHSCORE_LEER)
{
ziel = idx;
}
// ansonsten
else if (tmp_zeit.size() == 3)
{
// die bewertung des tabellenelements an idx berechnen. je mehr mienen und felder, je mehr punkte
element_ergebnis = tabelle->item(idx, HIGHSCORE_PUNKTE_POSITION)->text().toInt();
// den sekundenverbrauch fuer des tabellenelements an idx berechnen
element_sekundenverbrauch = (tmp_zeit.at(0).toInt() * 3600) + (tmp_zeit.at(1).toInt() * 60) + tmp_zeit.at(2).toInt();
}
// wenn das neue ergebnis mehr punkte hat als das tabellenelement oder gleich viel punkte wie das tabellenelement enthaelt, aber weniger zeit verbraucht hat ist es ueberlegen
if (punkte > element_ergebnis || (punkte == element_ergebnis && sekunden < element_sekundenverbrauch)) ziel = idx;
}
// wenn das neue element in die tabelle darf
if (ziel >= 0 && ziel < tabelle->rowCount())
{
// eine neue reihe an ziel in die tabelle einfuegen ...
tabelle->insertRow(ziel);
// ... und mit elementen befuellen
tabelle->setItem(ziel, HIGHSCORE_NAME_POSITION, new QTableWidgetItem());
tabelle->setItem(ziel, HIGHSCORE_PUNKTE_POSITION, new QTableWidgetItem());
tabelle->setItem(ziel, HIGHSCORE_ZEIT_POSITION, new QTableWidgetItem());
// der letzte muss die tabelle verlassen
tabelle->removeRow(tabelle->rowCount() - 1);
erg = true;
bool ok;
// den namen des nutzers abfragen
QString name_vorbereitung(QDir::home().dirName());
// wenn name_vorbereitung nicht leer ist
if (name_vorbereitung.isEmpty() == false)
{
QChar erstes_zeichen = name_vorbereitung.at(0);
if (erstes_zeichen.isLower() == true) name_vorbereitung[0] = erstes_zeichen.toUpper();
}
QString name = QInputDialog::getText(parentWidget(), tr("Patience"), tr("You got a Highscore !"), QLineEdit::Normal, name_vorbereitung, &ok);
// wenn kein nutzername eingegeben wurde den namen auf unbekannt setzen
if (ok == false || name.isEmpty() == true) name = tr("Unknown");
// wenn der name LEER entspricht den namen ebenfalls auf unbekannt setzen
if (name == HIGHSCORE_LEER) name = tr("Unknown");
int stunden = sekunden / 3600;
int minuten = (sekunden - (stunden * 3600)) / 60;
int sekunden_ = sekunden - (minuten * 60) - (stunden * 3600);
QString stunden_string = QString::number(stunden);
QString minuten_string = QString::number(minuten);
QString sekunden_string = QString::number(sekunden_);
if (stunden < 10) stunden_string.prepend('0');
if (minuten < 10) minuten_string.prepend('0');
if (sekunden_ < 10) sekunden_string.prepend('0');
tabelle->item(ziel, HIGHSCORE_NAME_POSITION)->setText(name);
tabelle->item(ziel, HIGHSCORE_PUNKTE_POSITION)->setText(QString::number(punkte));
tabelle->item(ziel, HIGHSCORE_ZEIT_POSITION)->setText(stunden_string + HIGHSCORE_SPLITTER + minuten_string + HIGHSCORE_SPLITTER + sekunden_string);
// die highscoretabelle anzeigen
show();
}
return erg;
}
void Highscore::registriere_einstellungen(QSettings* einstellungen_)
{
einstellungen = einstellungen_;
}
void Highscore::einstellungen_laden()
{
if (einstellungen != 0)
{
// die breite der spalten laden
tabelle->setColumnWidth(HIGHSCORE_NAME_POSITION, einstellungen->value(QString("tabelle/spalte_") + QString::number(HIGHSCORE_NAME_POSITION), HIGHSCORE_NAME_SPALTE_STANDARTGROESSE).toInt());
tabelle->setColumnWidth(HIGHSCORE_PUNKTE_POSITION, einstellungen->value(QString("tabelle/spalte_") + QString::number(HIGHSCORE_PUNKTE_POSITION), tabelle->columnWidth(HIGHSCORE_PUNKTE_POSITION)).toInt());
tabelle->setColumnWidth(HIGHSCORE_ZEIT_POSITION, einstellungen->value(QString("tabelle/spalte_") + QString::number(HIGHSCORE_ZEIT_POSITION), tabelle->columnWidth(HIGHSCORE_ZEIT_POSITION)).toInt());
}
// den inhalt der tabelle laden
for (register int idx = 0; idx < tabelle->rowCount() && einstellungen != 0; idx++)
{
// den namen laden
tabelle->item(idx, HIGHSCORE_NAME_POSITION)->setText(einstellungen->value(QString("highscore/") + QString::number(idx) + QString("name"), HIGHSCORE_LEER).toString());
// die punkte laden
tabelle->item(idx, HIGHSCORE_PUNKTE_POSITION)->setText(einstellungen->value(QString("highscore/") + QString::number(idx) + QString("breite"), HIGHSCORE_LEER).toString());
// die zeit laden
tabelle->item(idx, HIGHSCORE_ZEIT_POSITION)->setText(einstellungen->value(QString("highscore/") + QString::number(idx) + QString("hoehe"), HIGHSCORE_LEER).toString());
}
}
void Highscore::einstellungen_speichern()
{
// die breite der spalten speichern
einstellungen->setValue(QString("tabelle/spalte_") + QString::number(HIGHSCORE_NAME_POSITION), tabelle->columnWidth(HIGHSCORE_NAME_POSITION));
einstellungen->setValue(QString("tabelle/spalte_") + QString::number(HIGHSCORE_PUNKTE_POSITION), tabelle->columnWidth(HIGHSCORE_PUNKTE_POSITION));
einstellungen->setValue(QString("tabelle/spalte_") + QString::number(HIGHSCORE_ZEIT_POSITION), tabelle->columnWidth(HIGHSCORE_ZEIT_POSITION));
// den inhalt der tabelle speichern
for (register int idx = 0; idx < tabelle->rowCount() && einstellungen != 0; idx++)
{
// den namen speichern
einstellungen->setValue(QString("highscore/") + QString::number(idx) + QString("name"), tabelle->item(idx, HIGHSCORE_NAME_POSITION)->text());
// die punkte speichern
einstellungen->setValue(QString("highscore/") + QString::number(idx) + QString("breite"), tabelle->item(idx, HIGHSCORE_PUNKTE_POSITION)->text());
// die zeit speichern
einstellungen->setValue(QString("highscore/") + QString::number(idx) + QString("hoehe"), tabelle->item(idx, HIGHSCORE_ZEIT_POSITION)->text());
}
}

View File

@ -0,0 +1,27 @@
#ifndef HIGHSCORE_H
#define HIGHSCORE_H
#include <QDialog>
#include <QString>
#include "ui_Highscore.h"
class QSettings;
class Highscore : public QDialog, private Ui::Highscore
{
Q_OBJECT
public:
Highscore(QWidget *parent);
virtual ~Highscore();
bool neues_ergebnis(int, long);
void registriere_einstellungen(QSettings*);
void einstellungen_laden();
void einstellungen_speichern();
private:
QSettings *einstellungen;
};
#endif

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Highscore</class>
<widget class="QDialog" name="Highscore">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>528</width>
<height>300</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>528</width>
<height>300</height>
</size>
</property>
<property name="windowTitle">
<string>Patience - Highscore</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTableWidget" name="tabelle">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Points</string>
</property>
</column>
<column>
<property name="text">
<string>Time</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="ok_button">
<property name="text">
<string>Ok</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>ok_button</sender>
<signal>clicked()</signal>
<receiver>Highscore</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>485</x>
<y>275</y>
</hint>
<hint type="destinationlabel">
<x>356</x>
<y>263</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,49 @@
#include "Hilfszeiger.h"
#include "Basisstapel.h"
#include "Proportionen.h"
#include <QPainter>
using namespace std;
Hilfszeiger::Hilfszeiger(Basisstapel *parent) : QObject(parent), QGraphicsItem(parent), meinstapel(parent), breite(parent->boundingRect().width() / HILFSZEIGER_BREITE_VERHAELTNIS), hoehe(parent->boundingRect().height() / HILFSZEIGER_HOEHE_VERHAELTNIS), dicke(parent->boundingRect().height() / HILFSZEIGER_DICKE_VERHAELTNIS)
{
setZValue(1000);
}
Hilfszeiger::~Hilfszeiger()
{
}
void Hilfszeiger::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
{
painter->setPen(Qt::darkBlue);
painter->setBrush(Qt::darkBlue);
QPen stift(painter->pen());
stift.setWidth(dicke);
painter->setPen(stift);
painter->drawLine(breite / 2, 0 + (dicke / 2), breite / 2, hoehe - (dicke / 2));
painter->drawLine(breite / 2, 0 + (dicke / 2), dicke / 2, (hoehe / 2));
painter->drawLine(breite / 2, 0 + (dicke / 2), breite - (dicke / 2), (hoehe / 2));
}
QRectF Hilfszeiger::boundingRect() const
{
return QRectF(0, 0, breite, hoehe);
}
void Hilfszeiger::passe_groesse_an(const QRectF& wert)
{
prepareGeometryChange();
breite = wert.width() / HILFSZEIGER_BREITE_VERHAELTNIS;
hoehe = wert.height() / HILFSZEIGER_HOEHE_VERHAELTNIS;
dicke = wert.height() / HILFSZEIGER_DICKE_VERHAELTNIS;
update();
}

View File

@ -0,0 +1,27 @@
#ifndef HILFSZEIGER_H
#define HILFSZEIGER_H
#include <QObject>
#include <QGraphicsItem>
class Basisstapel;
class Hilfszeiger : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
Hilfszeiger(Basisstapel *parent);
virtual ~Hilfszeiger();
virtual QRectF boundingRect() const;
void passe_groesse_an(const QRectF&);
private:
Basisstapel *meinstapel;
double breite, hoehe, dicke;
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
};
#endif

View File

@ -0,0 +1,424 @@
#include "Karte.h"
#include "Basisstapel.h"
#include "Proportionen.h"
#include "Scene.h"
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
using namespace std;
Karte::Karte(const QPixmap& vorderseite, const QPixmap& hinterseite, Scene *oparent, QGraphicsItem *gparent) : QObject(oparent), QGraphicsPixmapItem(hinterseite, gparent), vorne(vorderseite), hinten(hinterseite), vorne_skaliert(vorderseite), hinten_skaliert(hinterseite), Wert(0), vorderseite_oben(false), rahmen_anzeigen(true), double_click_sperre(false), gegrabbt(false), scene(oparent), kreutzstapel(0), pikstapel(0), herzstapel(0), karostapel(0), kartengroesse(vorderseite.height())
{
setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
}
Karte::~Karte()
{
}
void Karte::setze_farbe(const QString& farbe_)
{
Farbe = farbe_;
}
const QString& Karte::farbe() const
{
return Farbe;
}
void Karte::setze_wert(int wert_)
{
Wert = wert_;
}
int Karte::wert() const
{
return Wert;
}
void Karte::zeige_vorderseite()
{
vorderseite_oben = true;
setPixmap(vorne_skaliert);
Meinstapel->karte_wurde_aufgedeckt(this);
// wenn es sich beim stapel nicht um austeilcostapel handelt die karte beweglich machen
if (Meinstapel->objectName() != BASISSTAPEL_AUSTEILCOSTAPEL) setFlag(QGraphicsItem::ItemIsMovable, true);
// ansonsten die karte unbeweglich machen. dies muss spaeter, im mouse release event wieder rueckgaengig gemacht werden
else setFlag(QGraphicsItem::ItemIsMovable, false);
}
void Karte::zeige_rueckseite()
{
vorderseite_oben = false;
setPixmap(hinten_skaliert);
setFlag(QGraphicsItem::ItemIsMovable, false);
}
bool Karte::ist_vorderseite() const
{
return vorderseite_oben;
}
bool Karte::ist_rueckseite() const
{
return !vorderseite_oben;
}
void Karte::registriere_stapel(const QList<Basisstapel*>& stapelliste_)
{
stapelliste = stapelliste_;
}
void Karte::setze_meinstapel(Basisstapel *meinstapel_)
{
Meinstapel = meinstapel_;
}
void Karte::setze_rueckehrkoordinaten(const QPointF& punkt)
{
Rueckkehrkoordinaten = punkt;
}
// diese methode ist fuer das ablegen der karte auf dem passenden zielstapel zustaendig, sofern moeglich
void Karte::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
{
if (event->buttons() == Qt::LeftButton && gegrabbt == false && flags() == QGraphicsItem::ItemIsMovable && event->button() == Qt::LeftButton && ist_vorderseite() == true && Meinstapel->ist_oberste_karte(this) == true && hat_kinderkarten() == false && Meinstapel->objectName().contains(BASISSTAPEL_ZIELSTAPEL) == false)
{
// nach einem double click soll die karte bis zum naechsten release gegen bewegungen geschuetzt werden
double_click_sperre = true;
// die karte soll nicht mehr über die anderen erhoeht werden
Meinstapel->normalisiere_zwert();
if (farbe() == KARTEN_KREUTZ) kreutzstapel->lege_karte_ab(this);
else if (farbe() == KARTEN_PIK) pikstapel->lege_karte_ab(this);
else if (farbe() == KARTEN_HERZ) herzstapel->lege_karte_ab(this);
else if (farbe() == KARTEN_KARO) karostapel->lege_karte_ab(this);
// sicherstellen, das die scene aktualisiert wird
scene->update();
}
}
void Karte::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
// linke maustaste
if (event->button() == Qt::LeftButton && gegrabbt == false)
{
gegrabbt = true;
// die karte soll ueber den anderen erhoeht angezeigt werden
Meinstapel->erhoehe_zwert();
if (ist_vorderseite() == true) QGraphicsPixmapItem::mousePressEvent(event);
// wenn diese karte die oberste karte ist und noch nicht die vorderseite gezeigt wird die vorderseite zeigen
else if (Meinstapel->ist_oberste_karte(this) == true && ist_vorderseite() == false) zeige_vorderseite();
}
// wenn die rechte maustaste gedrueckt wurde und die karte beweglich, jedoch nicht gegrabbt ist eine hilfsanfrage starten
else if (event->button() == Qt::RightButton && flags() == QGraphicsItem::ItemIsMovable && gegrabbt == false)
{
gegrabbt = true;
emit hilfsanfrage_start(this);
}
}
void Karte::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
// die karte soll nicht mehr über die anderen erhoeht werden
Meinstapel->normalisiere_zwert();
QGraphicsPixmapItem::mouseReleaseEvent(event);
// nur wenn keine weitere maustaste mehr gehalten wird
if (event->buttons() == Qt::NoButton)
{
// wenn double klick sperre nicht aktive ist
if (double_click_sperre == false)
{
Basisstapel *ziel = suche_ziel();
if (ziel == 0) setPos(Rueckkehrkoordinaten);
else if (ziel != 0 && ziel->lege_karte_ab(this) == false) setPos(Rueckkehrkoordinaten);
else setPos(Rueckkehrkoordinaten);
// die ist noetig, weil beim aufdecken auf dem austeilcostapel die karte unbeweglich gemacht wurde. dies ist jedoch nur zulaessig, wenn nur eine karte gezogen wird. wenn 3 gezogen werden, erfolgt die freigabe aus dem austeilstapel heraus
if (Meinstapel->objectName() == BASISSTAPEL_AUSTEILCOSTAPEL && Meinstapel->nur_eine_wird_gezogen() == true) setFlag(QGraphicsItem::ItemIsMovable, true);
}
// wenn double klick sperre doch aktive ist
else setPos(Rueckkehrkoordinaten);
}
// wenn doch noch eine weitere maustaste gehalten wird
else setPos(Rueckkehrkoordinaten);
// den rahmen wieder verstecken
emit rahmen_verstecken();
// den hilfs pfeil wieder ausblenden
emit hilfsanfrage_ende();
// die double click sperre wieder aufheben, damit die karte zukuenftig wieder beweglich ist
double_click_sperre = false;
gegrabbt = false;
// sicherstellen, das das element nicht laenger gegrabbt ist !!!
ungrabMouse();
}
Basisstapel* Karte::eigentuemer_stapel()
{
return Meinstapel;
}
void Karte::registriere_zielstapel(Basisstapel* kreutzstapel_, Basisstapel* pikstapel_, Basisstapel* herzstapel_, Basisstapel* karostapel_)
{
kreutzstapel = kreutzstapel_;
pikstapel = pikstapel_;
herzstapel = herzstapel_;
karostapel = karostapel_;
}
void Karte::setze_kartenbilder(const QPixmap& vorne_, const QPixmap& hinten_)
{
vorne = vorne_;
hinten = hinten_;
passe_groesse_an(kartengroesse);
}
Basisstapel* Karte::suche_ziel()
{
QList<Basisstapel*> moegliche_ziele(stapelliste);
Basisstapel *erg = 0;
// den eigenen stapel aus moegliche_ziele entfernen
moegliche_ziele.removeAll(Meinstapel);
// alle unmoeglichen stapel entfernen
for (register int idx = 0; idx < moegliche_ziele.size(); idx++) if (moegliche_ziele.at(idx)->ablage_moeglich(this) == false && (moegliche_ziele.at(idx)->objectName().contains("ziel") == false || (moegliche_ziele.at(idx)->objectName().contains("ziel") == true && kreutzstapel->ablage_moeglich(this) == false && pikstapel->ablage_moeglich(this) == false && herzstapel->ablage_moeglich(this) == false && karostapel->ablage_moeglich(this) == false)))
{
moegliche_ziele.removeAt(idx);
idx--;
}
// wenn das ziel noch nicht eindeutig ist die groesste ueberlappung finden
if (moegliche_ziele.size() > 1)
{
// das ziel mit der groessten ueberlappenden flaeche finden
Basisstapel *ziel = 0;
int groesste_ueberlappung = 0;
for (register int idx = 0; idx < moegliche_ziele.size(); idx++)
{
int ueberlappung = moegliche_ziele.at(idx)->ueberlappungs_flaeche(this);
if (ueberlappung > groesste_ueberlappung)
{
groesste_ueberlappung = ueberlappung;
ziel = moegliche_ziele.at(idx);
}
}
erg = ziel;
}
else if (moegliche_ziele.size() == 1) erg = moegliche_ziele.first();
// besteht mit dem sieger eine beruehrung ?
if (erg != 0 && erg->beruehrungstest(this) == false) erg = 0;
// wird ein zielstapel angepeilt?
if (erg != 0 && erg->objectName().contains("ziel") == true)
{
if (farbe() == KARTEN_KREUTZ && kreutzstapel->ablage_moeglich(this) == true) erg = kreutzstapel;
else if (farbe() == KARTEN_PIK && pikstapel->ablage_moeglich(this) == true) erg = pikstapel;
else if (farbe() == KARTEN_HERZ && herzstapel->ablage_moeglich(this) == true) erg = herzstapel;
else if (farbe() == KARTEN_KARO && karostapel->ablage_moeglich(this) == true) erg = karostapel;
else erg = 0;
}
return erg;
}
void Karte::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
if (gegrabbt == true)
{
if (double_click_sperre == false && event->buttons() == Qt::LeftButton) QGraphicsPixmapItem::mouseMoveEvent(event);
else setPos(Rueckkehrkoordinaten);
if (rahmen_anzeigen == true)
{
Basisstapel *ziel = suche_ziel();
if (ziel != 0) ziel->zeige_rahmen();
else
{
emit rahmen_verstecken();
}
}
}
}
void Karte::sichtbarkeit_rahmen(bool wert)
{
rahmen_anzeigen = wert;
}
QRectF Karte::gesamt_rect()
{
QRectF erg(sceneBoundingRect());
Karte *testkarte = unterste_karte();
erg.setBottomRight(testkarte->sceneBoundingRect().bottomRight());
return erg;
}
Karte* Karte::unterste_karte()
{
Karte *erg = this;
if (hat_kinderkarten() == true) erg = kinderkarten().last();
return erg;
}
// wenn die karte child items besitzt, die nicht vom typ karte sind muessen diese hier herausgefiltert werden !!!
bool Karte::hat_kinderkarten() const
{
bool erg = false;
if (childItems().size() > 1)
{
qDebug() << tr("The Card ") << objectName() << tr(" have more than one Child Card");
exit(1);
}
if (childItems().size() > 0) erg = true;
return erg;
}
// wenn die karte child items besitzt, die nicht vom typ karte sind muessen diese hier herausgefiltert werden !!!
QList<Karte*> Karte::kinderkarten()
{
QList<Karte*> erg;
if (childItems().size() > 1)
{
qDebug() << tr("The Card ") << objectName() << tr(" have more than one Child Card");
exit(1);
}
if (childItems().isEmpty() == false) erg.append((Karte*) childItems().first());
if (erg.isEmpty() == false) erg.append(erg.first()->kinderkarten());
return erg;
}
const QStringList Karte::speichere() const
{
QStringList erg;
// die karten id speichern
erg.append(objectName());
// die kartenseite speichern
erg.append(QString::number(ist_vorderseite()));
return erg;
}
bool Karte::lade(const QStringList& daten)
{
bool erg = false;
if (daten.size() == KARTE_ANZAHL_SPEICHERELEMENTE && daten.first() == objectName())
{
erg = true;
if (daten.at(KARTE_IST_VORNE_IDX).toInt() == 1) zeige_vorderseite();
else zeige_rueckseite();
}
return erg;
}
void Karte::passe_groesse_an(double wert)
{
kartengroesse = wert;
vorne_skaliert = vorne.scaledToHeight(kartengroesse, Qt::SmoothTransformation);
hinten_skaliert = hinten.scaledToHeight(kartengroesse, Qt::SmoothTransformation);
if (ist_vorderseite() == true) setPixmap(vorne_skaliert);
else setPixmap(hinten_skaliert);
}
void Karte::nach_hause()
{
setPos(Rueckkehrkoordinaten);
emit rahmen_verstecken();
if (scene->mouseGrabberItem() == this) ungrabMouse();
}
void Karte::speichere_zuhause()
{
Rueckkehrkoordinaten = pos();
}

View File

@ -0,0 +1,74 @@
#ifndef KARTE_H
#define KARTE_H
#include <QObject>
#include <QGraphicsPixmapItem>
#include <QGraphicsItem>
#include <QPixmap>
#include <QColor>
#include <QList>
#include <QPointF>
class Scene;
class Basisstapel;
class Karte : public QObject, public QGraphicsPixmapItem
{
Q_OBJECT
public:
Karte(const QPixmap& vorderseite, const QPixmap& hinterseite, Scene *oparent, QGraphicsItem *gparent = 0);
virtual ~Karte();
void setze_farbe(const QString&);
const QString& farbe() const;
void setze_wert(int);
int wert() const;
bool ist_vorderseite() const;
bool ist_rueckseite() const;
void registriere_stapel(const QList<Basisstapel*>& stapelliste_);
void setze_meinstapel(Basisstapel *meinstapel_);
void setze_rueckehrkoordinaten(const QPointF&);
void registriere_zielstapel(Basisstapel* kreutzstapel_, Basisstapel* pikstapel_, Basisstapel* herzstapel_, Basisstapel* karoherzstapel_);
Basisstapel* eigentuemer_stapel();
void setze_kartenbilder(const QPixmap&, const QPixmap&);
Basisstapel* suche_ziel();
QList<Karte*> kinderkarten();
QRectF gesamt_rect();
Karte* unterste_karte();
bool hat_kinderkarten() const;
const QStringList speichere() const;
bool lade(const QStringList&);
void nach_hause();
void speichere_zuhause();
public slots:
void zeige_vorderseite();
void zeige_rueckseite();
void sichtbarkeit_rahmen(bool);
void passe_groesse_an(double);
signals:
void rahmen_verstecken();
void hilfsanfrage_start(Karte*);
void hilfsanfrage_ende();
private:
QPixmap vorne, hinten, vorne_skaliert, hinten_skaliert;
QString Farbe;
int Wert;
bool vorderseite_oben, rahmen_anzeigen, double_click_sperre, gegrabbt;
Scene *scene;
QList<Basisstapel*> stapelliste;
Basisstapel *Meinstapel;
QPointF Rueckkehrkoordinaten;
Basisstapel *kreutzstapel, *pikstapel, *herzstapel, *karostapel;
double kartengroesse;
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*);
virtual void mousePressEvent(QGraphicsSceneMouseEvent*);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*);
};
#endif

View File

@ -0,0 +1,350 @@
#include "MainWindow.h"
#include "Scene.h"
#include "Highscore.h"
#include "Speichern_frage.h"
#include <QMessageBox>
#include <QSettings>
#include <QMessageBox>
#include <QActionGroup>
#include <QLabel>
#include <QCloseEvent>
using namespace std;
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
// die benutzeroberflaeche aufbauen
setupUi(this);
// osx spezifische einstellungen vornehmen
#ifdef Q_WS_MAC
setUnifiedTitleAndToolBarOnMac(true);
#endif
// einstellungen erstellen
einstellungen = new QSettings("konarski-wuppertal", "Patience", this);
// es ist noetigm das einige einstellungen vorab geladen werden, damit sie von vorne herein verfuegbar sind !!!
// den kartentyp laden
QString kartentyp(einstellungen->value("deckblatt", "french").toString());
// sicherstellen, das der geladene kartentyp gueltig ist
if (kartentyp != "french" && kartentyp != "german") kartentyp = "french";
// action_french und action_german zu einer gruppe verbinden
QActionGroup *deckblatt_gruppe = new QActionGroup(this);
deckblatt_gruppe->addAction(action_french);
deckblatt_gruppe->addAction(action_german);
// die action gruppe initialisieren
if (kartentyp == "french") action_french->setChecked(true);
else action_german->setChecked(true);
// action_eine_ziehen und action_drei_ziehen zu einer gruppe verbinden ...
QActionGroup *spieltyp_gruppe = new QActionGroup(this);
spieltyp_gruppe->addAction(action_eine_ziehen);
spieltyp_gruppe->addAction(action_drei_ziehen);
// ... und initialisieren
action_eine_ziehen->setChecked(true);
// action_speichern und action_nicht_speichern zu eoner gruppe verbinden
QActionGroup *speichern_gruppe = new QActionGroup(this);
speichern_gruppe->addAction(action_speichern);
speichern_gruppe->addAction(action_nicht_speichern);
// scene erstellen ...
scene = new Scene(kartentyp, viewer);
scene->setObjectName("scene");
scene->setSceneRect(0, 0, 795, 595);
scene->registriere_einstellungen(einstellungen);
// ... und in viewer registrieren
viewer->setScene(scene);
// siegmeldung erzeugen
siegmeldung = new QMessageBox(this);
siegmeldung->setWindowModality(Qt::WindowModal);
siegmeldung->setWindowTitle(tr("Patience - You won !"));
siegmeldung->setText(tr("You won, but you don't reach a highscore."));
siegmeldung->addButton(QMessageBox::Ok);
sicherheitsfrage = new QMessageBox(this);
sicherheitsfrage->setWindowModality(Qt::WindowModal);
sicherheitsfrage->setWindowTitle(tr("Patience - Start new game ?"));
sicherheitsfrage->setText(tr("Start a new Game and break the current Game ?"));
sicherheitsfrage->addButton(QMessageBox::Yes);
sicherheitsfrage->addButton(QMessageBox::No);
// punktelabel und zeitlabel erzeugen ...
punktelabel = new QLabel(this);
zeitlabel = new QLabel(this);
// ... und der statusleiste als permanentes widget hinzufuegen
statusBar()->addPermanentWidget(punktelabel);
statusBar()->addPermanentWidget(zeitlabel);
// highscore erzeugen
highscore = new Highscore(this);
highscore->registriere_einstellungen(einstellungen);
// speichern_frage erstellen
speichern_frage = new Speichern_frage(this);
speichern_frage->setObjectName("speichern_frage");
// signal - slot verbindungen
// das starten neuer spiele ermoeglichen
connect(action_neues_spiel, SIGNAL(triggered(bool)), this, SLOT(neues_spiel()));
// action_about ermoeglichen
connect(action_about, SIGNAL(triggered(bool)), this, SLOT(about()));
// action_about_qt ermoeglichen
connect(action_about_qt, SIGNAL(triggered(bool)), qApp, SLOT(aboutQt()));
// das anzeigen der siegmeldung ermoeglichen
connect(scene, SIGNAL(gewonnen(int, long)), this, SLOT(gewonnen(int, long)));
// das umschalten des deckblattes waehrend des spiels ermoeglichen
connect(action_french, SIGNAL(triggered(bool)), scene, SLOT(lade_franzoesisches_deckblatt()));
connect(action_german, SIGNAL(triggered(bool)), scene, SLOT(lade_deutsches_deckblatt()));
// das aktualisieren der punkte ermoeglichen
connect(scene, SIGNAL(neue_punktzahl(int)), this, SLOT(aktualisiere_punktelabel(int)));
// das aktualisieren der spielzeit ermoeglichen
connect(scene, SIGNAL(verstrichene_sekunden(long)), this, SLOT(aktualisiere_spielzeit(long)));
// das anzeigen der highscore ermoeglichen
connect(action_highscore, SIGNAL(triggered(bool)), highscore, SLOT(show()));
// das umschalten des spieltyps ermoeglichen
connect(action_eine_ziehen, SIGNAL(triggered(bool)), this, SLOT(eine_ziehen()));
connect(action_drei_ziehen, SIGNAL(triggered(bool)), this, SLOT(drei_ziehen()));
// das steuern der rahmen sichtbarkeit ermoeglichen
connect(action_rahmen, SIGNAL(triggered(bool)), scene, SIGNAL(rahmen_anzeigen(bool)));
// action_schliessen ermoeglichen
connect(action_beenden, SIGNAL(triggered(bool)), this, SLOT(close()));
// action_undo ermoeglichen
connect(action_undo, SIGNAL(triggered(bool)), scene, SLOT(rueckgaengig()));
// steuerung der verfuegbarkeit von action_undo ermoeglichen
connect(scene, SIGNAL(undo_verfuegbar(bool)), action_undo, SLOT(setEnabled(bool)));
// action_fragen und speichern_frage verbinden
connect(action_fragen, SIGNAL(toggled(bool)), speichern_frage, SLOT(verbindung_merken(bool)));
connect(speichern_frage, SIGNAL(verbindung_merk_status(bool)), action_fragen, SLOT(setChecked(bool)));
// den speicher status mit action_speichern und action_nicht_speichern verbinden
connect(speichern_frage, SIGNAL(wird_gespeichert(bool)), action_speichern, SLOT(setChecked(bool)));
connect(speichern_frage, SIGNAL(wird_nicht_gespeichert(bool)), action_nicht_speichern, SLOT(setChecked(bool)));
connect(action_speichern, SIGNAL(toggled(bool)), speichern_frage, SLOT(setze_speichern(bool)));
// die restlichen einstellungen laden
restliche_einstellungen_laden();
}
MainWindow::~MainWindow()
{
// die einstellungen speichern
einstellungen_speichern();
}
void MainWindow::neues_spiel()
{
// wenn kein spiel laueft, einfach eins starten ...
if (scene->laufendes_spiel() == false) scene->neues_spiel();
// ansonsten erst nach einer sicherheitsfrage ein neues spiel starten
else
{
QAbstractButton *sicherheitsfrage_ja = sicherheitsfrage->button(QMessageBox::Yes);
sicherheitsfrage->exec();
if (sicherheitsfrage->clickedButton() == sicherheitsfrage_ja) scene->neues_spiel();
}
}
void MainWindow::about()
{
QMessageBox::about(this, tr("About Patience"), tr("Patience Version " VERSION " \n\nAuthor:\tAndreas Konarski\nLizenz:\tgpl\n\nKontakt:\n\nprogrammieren@konarski-wuppertal.de\nwww.konarski-wuppertal.de"));
}
void MainWindow::restliche_einstellungen_laden()
{
// die fenstergeometrie laden
restoreGeometry(einstellungen->value("mainwindow/geometry").toByteArray());
// den spieltyp laden
if (einstellungen->value("spieltyp", 1).toInt() == 3)
{
scene->drei_ziehen();
action_drei_ziehen->setChecked(true);
}
// die sichtbarkeit des rahmens laden
action_rahmen->setChecked(einstellungen->value("mainwindow/rahmen", true).toBool());
scene->initialisiere_rahmen(action_rahmen->isChecked());
// die highscore laden
highscore->einstellungen_laden();
// den spielstand laden oder ein neues spiel starten
if (einstellungen->value("begonnenes_spiel", false).toBool() == false) scene->neues_spiel();
else scene->lade_spielstand();
// einstellungen fuer speichern_frage laden
speichern_frage->setze_merken(einstellungen->value("speichern_frage/merken", false).toBool());
speichern_frage->setze_speichern(einstellungen->value("speichern_frage/speichern", true).toBool());
}
void MainWindow::einstellungen_speichern()
{
// die fenstergeometrie speichern
einstellungen->setValue("mainwindow/geometry", saveGeometry());
// den spieltyp speichern
if (scene->nur_eine_wird_gezogen() == true) einstellungen->setValue("spieltyp", 1);
else einstellungen->setValue("spieltyp", 3);
// die sichtbarkeit des rahmens speichern
einstellungen->setValue("mainwindow/rahmen", action_rahmen->isChecked());
// die deckblatt sprache speichern
if (action_french->isChecked() == true) einstellungen->setValue("deckblatt", "french");
else einstellungen->setValue("deckblatt", "german");
// die highscore speichern
highscore->einstellungen_speichern();
// wenn ein spiel laueft und der spielstand gespeichert werden soll, den spielstand speichern
if (scene->begonnenes_spiel() == true && speichern_frage->soll_speichern() == true)
{
scene->speichere_spielstand();
// speichern, ob ein spiel begonnen wurde
einstellungen->setValue("begonnenes_spiel", scene->begonnenes_spiel());
}
else einstellungen->setValue("begonnenes_spiel", false);
// einstellungen fuer speichern_frage speichern
einstellungen->setValue("speichern_frage/merken", speichern_frage->soll_merken());
einstellungen->setValue("speichern_frage/speichern", speichern_frage->soll_speichern());
}
void MainWindow::gewonnen(int punkte, long sekunden)
{
if (highscore->neues_ergebnis(punkte, sekunden) == false) siegmeldung->show();
}
void MainWindow::aktualisiere_punktelabel(int wert)
{
punktelabel->setText(QString::number(wert) + tr(" Points"));
}
void MainWindow::aktualisiere_spielzeit(long verstrichene_sekunden)
{
// die verstrichenen sekunden aufbereiten
int stunden = verstrichene_sekunden / 3600;
int minuten = (verstrichene_sekunden - (stunden * 3600)) / 60;
int sekunden = verstrichene_sekunden - (minuten * 60) - (stunden * 3600);
QString stunden_string = QString::number(stunden);
QString minuten_string = QString::number(minuten);
QString sekunden_string = QString::number(sekunden);
if (stunden < 10) stunden_string.prepend('0');
if (minuten < 10) minuten_string.prepend('0');
if (sekunden < 10) sekunden_string.prepend('0');
zeitlabel->setText(stunden_string + ":" + minuten_string + ":" + sekunden_string);
}
void MainWindow::eine_ziehen()
{
// wenn kein spiel laueft, einfach eins starten ...
if (scene->laufendes_spiel() == false)
{
scene->eine_ziehen();
scene->neues_spiel();
}
// ansonsten erst nach einer sicherheitsfrage ein neues spiel starten
else
{
QAbstractButton *sicherheitsfrage_ja = sicherheitsfrage->button(QMessageBox::Yes);
sicherheitsfrage->exec();
if (sicherheitsfrage->clickedButton() == sicherheitsfrage_ja)
{
scene->eine_ziehen();
scene->neues_spiel();
}
else action_drei_ziehen->setChecked(true);
}
}
void MainWindow::drei_ziehen()
{
// wenn kein spiel laueft, einfach eins starten ...
if (scene->laufendes_spiel() == false)
{
scene->drei_ziehen();
scene->neues_spiel();
}
// ansonsten erst nach einer sicherheitsfrage ein neues spiel starten
else
{
QAbstractButton *sicherheitsfrage_ja = sicherheitsfrage->button(QMessageBox::Yes);
sicherheitsfrage->exec();
if (sicherheitsfrage->clickedButton() == sicherheitsfrage_ja)
{
scene->drei_ziehen();
scene->neues_spiel();
}
else action_eine_ziehen->setChecked(true);
}
}
void MainWindow::closeEvent(QCloseEvent* event)
{
bool brauche_frage = true;
// wenn kein spiel begonnen wurde oder speichern_frage auf merken (dabei jedoch nicht auf reject) eingestellt ist wird keine frage gebraucht
if (scene->begonnenes_spiel() == false || (speichern_frage->soll_merken() == true && speichern_frage->result() != QDialog::Rejected)) brauche_frage = false;
// wenn eine frage gebraucht wird
if (brauche_frage == true) speichern_frage->exec();
// wenn speichern_frage akzeptiert wurde das schliessen der anwendung erlauben, ...
if (speichern_frage->result() == QDialog::Accepted) QMainWindow::closeEvent(event);
// ... ansonsten, wenn nicht akzeptiert, verhindern
else if (speichern_frage->result() == QDialog::Rejected) event->ignore();
}

View File

@ -0,0 +1,46 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#define VERSION "0.81"
#include <QMainWindow>
#include "ui_MainWindow.h"
class Scene;
class QSettings;
class QMessageBox;
class QLabel;
class Highscore;
class Speichern_frage;
class MainWindow : public QMainWindow, private Ui::MainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
virtual ~MainWindow();
private slots:
void neues_spiel();
void about();
void restliche_einstellungen_laden();
void einstellungen_speichern();
void gewonnen(int, long);
void aktualisiere_punktelabel(int);
void aktualisiere_spielzeit(long);
void eine_ziehen();
void drei_ziehen();
private:
Scene *scene;
QSettings *einstellungen;
QMessageBox *siegmeldung, *sicherheitsfrage;
QLabel *punktelabel, *zeitlabel;
Highscore *highscore;
Speichern_frage *speichern_frage;
virtual void closeEvent(QCloseEvent*);
};
#endif

View File

@ -0,0 +1,269 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>810</width>
<height>653</height>
</rect>
</property>
<property name="windowTitle">
<string>Patience</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>5</number>
</property>
<item row="0" column="0">
<widget class="Viewer" name="viewer">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="renderHints">
<set>QPainter::Antialiasing|QPainter::HighQualityAntialiasing|QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing</set>
</property>
<property name="cacheMode">
<set>QGraphicsView::CacheBackground</set>
</property>
<property name="viewportUpdateMode">
<enum>QGraphicsView::FullViewportUpdate</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>810</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuSpiel">
<property name="title">
<string>Game</string>
</property>
<addaction name="action_neues_spiel"/>
<addaction name="separator"/>
<addaction name="action_beenden"/>
</widget>
<widget class="QMenu" name="menu_Hilfe">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="action_about"/>
<addaction name="action_about_qt"/>
</widget>
<widget class="QMenu" name="menu_Einstellungen">
<property name="title">
<string>&amp;Settings</string>
</property>
<widget class="QMenu" name="menu_Cardset">
<property name="title">
<string>&amp;Cardset</string>
</property>
<addaction name="action_french"/>
<addaction name="action_german"/>
</widget>
<widget class="QMenu" name="menu_Gametype">
<property name="title">
<string>Gametype</string>
</property>
<addaction name="action_eine_ziehen"/>
<addaction name="action_drei_ziehen"/>
</widget>
<widget class="QMenu" name="menuSave_Game">
<property name="title">
<string>Save Game</string>
</property>
<addaction name="action_speichern"/>
<addaction name="action_nicht_speichern"/>
<addaction name="separator"/>
<addaction name="action_fragen"/>
</widget>
<addaction name="menu_Cardset"/>
<addaction name="menu_Gametype"/>
<addaction name="menuSave_Game"/>
<addaction name="separator"/>
<addaction name="action_rahmen"/>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menu_Highscore">
<property name="title">
<string>&amp;Highscore</string>
</property>
<addaction name="action_highscore"/>
</widget>
<widget class="QMenu" name="menu_Edit">
<property name="title">
<string>&amp;Edit</string>
</property>
<addaction name="action_undo"/>
</widget>
<addaction name="menuSpiel"/>
<addaction name="menu_Edit"/>
<addaction name="menu_Einstellungen"/>
<addaction name="menu_Highscore"/>
<addaction name="menu_Hilfe"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="action_neues_spiel">
<property name="text">
<string>&amp;New Game</string>
</property>
<property name="shortcut">
<string>Ctrl+N</string>
</property>
</action>
<action name="action_beenden">
<property name="text">
<string>Close</string>
</property>
</action>
<action name="action_about">
<property name="text">
<string>About Patience</string>
</property>
</action>
<action name="action_about_qt">
<property name="text">
<string>About QT</string>
</property>
</action>
<action name="action_french_">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>French</string>
</property>
</action>
<action name="action_german_">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>German</string>
</property>
</action>
<action name="action_highscore">
<property name="text">
<string>&amp;Show</string>
</property>
</action>
<action name="action_eine_ziehen_">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Take One</string>
</property>
</action>
<action name="action_drei_ziehen_">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Take Three</string>
</property>
</action>
<action name="action_french">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>French</string>
</property>
</action>
<action name="action_german">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>German</string>
</property>
</action>
<action name="action_eine_ziehen">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Take One</string>
</property>
</action>
<action name="action_drei_ziehen">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Take Three</string>
</property>
</action>
<action name="action_rahmen">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>Frame</string>
</property>
</action>
<action name="action_undo">
<property name="text">
<string>Undo</string>
</property>
</action>
<action name="action_fragen">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>Ask</string>
</property>
</action>
<action name="action_speichern">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="text">
<string>Save</string>
</property>
</action>
<action name="action_nicht_speichern">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Don't save</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>Viewer</class>
<extends>QGraphicsView</extends>
<header>Viewer.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="resourcen.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1 @@
IDI_ICON1 ICON DISCARDABLE "icon.ico"

View File

@ -0,0 +1,53 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2010 RetroShare Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
//#include <QApplication>
//#include <QString>
//#include <QPushButton>
#include "PatiencePlugin.h"
#include "MainWindow.h"
QString
PatiencePlugin::pluginDescription() const
{
QString res;
res = "a Patience plugin" ;
return res;
}
QString
PatiencePlugin::pluginName() const
{
return "Patience" ;
}
QWidget*
PatiencePlugin::pluginWidget(QWidget * parent )
{
MainWindow* window = new MainWindow();
return window;
}
Q_EXPORT_PLUGIN2(patience_plugin, PatiencePlugin)

View File

@ -0,0 +1,48 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2010 RetroShare Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#ifndef _PATIENCE_PLUGIN_H_
#define _PATIENCE_PLUGIN_H_
#include <QObject>
#include <QString>
#include <QWidget>
#include <PluginInterface.h>
#include <QDebug>
class PatiencePlugin: public QObject, public PluginInterface
{
Q_OBJECT
Q_INTERFACES(PluginInterface)
public slots:
virtual QString pluginDescription() const ;
virtual QString pluginName() const ;
virtual QWidget* pluginWidget(QWidget * parent = 0) ;
};
#endif

View File

@ -0,0 +1,128 @@
#ifndef PROPORTIONEN_H
#define PROPORTIONEN_H
// fuer Basisstapel
#define BASISSTAPEL_AUSTEILSTAPEL "austeilstapel"
#define BASISSTAPEL_AUSTEILCOSTAPEL "austeilcostapel"
#define BASISSTAPEL_ZIELSTAPEL "zielstapel"
#define BASISSTAPEL_ABLAGESTAPEL "ablagestapel"
#define BASISSTAPEL_ABSTAND_HILFSZEIGER_VERHAELTNIS 28.0
#define BASISSTAPEL_ANZAHL_SPEICHERELEMENTE 2
#define BASISSTAPEL_SAVE_ID_IDX 0
#define BASISSTAPEL_KARTEN_IDX 1
#define BASISSTAPEL_KARTEN_SPLITTER ","
// fuer Ablagestapel
#define ABLAGESTAPEL_YDRIFT_VERHAELTNIS 9.333333333333333
// fuer Austeilcostapel
#define AUSTEILCOSTAPEL_XDRIFT_VERHAELTNIS 7.0
// muss um 1 groesser sein als BASISSTAPEL_KARTEN_IDX !!!
#define AUSTEILSTAPEL_ABLAGENUMMER_IDX 2
// muss um mindestens 1 groesser sein als BASISSTAPEL_ANZAHL_SPEICHERELEMENTE !!!
#define AUSTEILSTAPEL_ANZAHL_SPEICHERELEMENTE 3
// fuer Highscore
#define HIGHSCORE_NAME_POSITION 0
#define HIGHSCORE_PUNKTE_POSITION 1
#define HIGHSCORE_ZEIT_POSITION 2
#define HIGHSCORE_ZEILEN 15
#define HIGHSCORE_LEER "n / a"
#define HIGHSCORE_SPLITTER ":"
#define HIGHSCORE_NAME_SPALTE_STANDARTGROESSE 250
// fuer Hilfszeiger
#define HILFSZEIGER_BREITE_VERHAELTNIS 6.0
#define HILFSZEIGER_HOEHE_VERHAELTNIS 7.0
#define HILFSZEIGER_DICKE_VERHAELTNIS 70
// fuer Karten
#define KARTEN_KREUTZ "kreutz"
#define KARTEN_PIK "pik"
#define KARTEN_HERZ "herz"
#define KARTEN_KARO "karo"
#define KARTEN_ASS "ass"
#define KARTEN_BUBE "bube"
#define KARTEN_DAME "dame"
#define KARTEN_KOENIG "koenig"
#define KARTE_ANZAHL_SPEICHERELEMENTE 2
#define KARTE_SAVE_ID_IDX 0
#define KARTE_IST_VORNE_IDX 1
#define KARTE_VERHAELTNIS_BREITE_ZU_HOEHE 1.555555555555556
// fuer Punktezaehler
// punkte wenn nur eine karte gezogen wird
#define PUNKTEZAEHLER_EINE_ZIEHEN_AUSTEILSTAPEL_ZU_ABLAGESTAPEL 5
#define PUNKTEZAEHLER_EINE_ZIEHEN_AUSTEILSTAPEL_ZU_ZIELSTAPEL 15
#define PUNKTEZAEHLER_EINE_ZIEHEN_ABLAGESTAPEL_ZU_ZIELSTAPEL 10
#define PUNKTEZAEHLER_EINE_ZIEHEN_PUNKTEABZUG_ZEIT 2
#define PUNKTEZAEHLER_EINE_ZIEHEN_KARTE_AUF_ABLAGESTAPEL_AUFGEDECKT 5
#define PUNKTEZAEHLER_EINE_ZIEHEN_AUSTEILSTAPEL_DURCH 100
// punkte wenn drei karten gezogen werden
#define PUNKTEZAEHLER_DREI_ZIEHEN_AUSTEILSTAPEL_ZU_ABLAGESTAPEL 5
#define PUNKTEZAEHLER_DREI_ZIEHEN_AUSTEILSTAPEL_ZU_ZIELSTAPEL 15
#define PUNKTEZAEHLER_DREI_ZIEHEN_ABLAGESTAPEL_ZU_ZIELSTAPEL 10
#define PUNKTEZAEHLER_DREI_ZIEHEN_PUNKTEABZUG_ZEIT 1
#define PUNKTEZAEHLER_DREI_ZIEHEN_KARTE_AUF_ABLAGESTAPEL_AUFGEDECKT 5
#define PUNKTEZAEHLER_DREI_ZIEHEN_AUSTEILSTAPEL_DURCH 50
#define PUNKTEZAEHLER_SPLITTER "<<<"
#define PUNKTEZAEHLER_ANZAHL_SPEICHERELEMENTE 4
#define PUNKTEZAEHLER_STRING_SPLITTER ","
#define PUNKTEZAEHLER_SAVE_ID_IDX 0
#define PUNKTEZAEHLER_STRAFTIMER_ON_IDX 1
#define PUNKTEZAEHLER_NACH_OBEN_LISTE_IDX 2
#define PUNKTEZAEHLER_PUNKTE_IDX 3
// fuer Rahmen
#define RAHMEN_DICKE_VERHAELTNIS 23.333333333333333
#define RAHMEN_ECKRADIUS_VERHAELTNIS 9.333333333333333
// fuer Scene
#define SCENE_ABLAGE_STAPELZAHL 7
#define SCENE_ANZAHL_SPEICHERELEMENTE 3
#define SCENE_SAVE_ID_IDX 0
#define SCENE_EINE_ZIEHEN_IDX 1
#define SCENE_VERSTRICHENE_ZEIT_IDX 2
#define SCENE_AUSGANGSBREITE 795.0
#define SCENE_AUSGANGSHOEHE 595.0
#define SCENE_AUSTEILSTAPEL_X_VERHAELTNIS 34.565217391304348
#define SCENE_AUSTEILCOSTAPEL_X_VERHAELTNIS 5.977443609022556
#define SCENE_KREUTZZIELSTAPEL_X_VERHAELTNIS 2.252124645892351
#define SCENE_PIKZIELSTAPEL_X_VERHAELTNIS 1.717062634989201
#define SCENE_KAROZIELSTAPEL_X_VERHAELTNIS 1.387434554973822
#define SCENE_HERZZIELSTAPEL_X_VERHAELTNIS 1.16398243045388
#define SCENE_ABLAGESTAPEL_01_X_VERHAELTNIS 34.565217391304348
#define SCENE_ABLAGESTAPEL_02_X_VERHAELTNIS 5.977443609022556
#define SCENE_ABLAGESTAPEL_03_X_VERHAELTNIS 3.271604938271605
#define SCENE_ABLAGESTAPEL_04_X_VERHAELTNIS 2.252124645892351
#define SCENE_ABLAGESTAPEL_05_X_VERHAELTNIS 1.717062634989201
#define SCENE_ABLAGESTAPEL_06_X_VERHAELTNIS 1.387434554973822
#define SCENE_ABLAGESTAPEL_07_X_VERHAELTNIS 1.16398243045388
#define SCENE_ABLAGESTAPEL_Y_VERHAELTNIS 3.305555555555556
#define SCENE_VERHAELTNIS_BREITE_ZU_HOEHE 1.336134453781513
#define SCENE_VERHAELTNIS_HOEHE_ZU_BREITE 0.748427672955975
#define SCENE_HOEHE_ZU_KARTENHOEHE 4.25
#define SCENE_OBERE_STAPEL_Y_VERHAELTNIS 59.5
// fuer Undo
#define ZUEGE_PRO_BEWEGUNG 1.0
#define ZUEGE_PRO_AUFDECKUNG 0.5
#define UNDO_LIMIT 3.0
#define ZUEGE_SPLITTER ","
#define ZUEGE_NACH_SPLITTER "."
#define UNDO_ANZAHL_SPEICHERELEMENTE 2
#define UNDO_SAVE_ID_IDX 0
#define UNDO_VERLAUF_IDX 1
#endif

View File

@ -0,0 +1,284 @@
#include "Punktezaehler.h"
#include "Scene.h"
#include "Basisstapel.h"
#include "Proportionen.h"
#include <QTimer>
#include <QDebug>
using namespace std;
Punktezaehler::Punktezaehler(Scene *parent) : QObject(parent), punkte(0), scene(parent), nur_eine_ziehen(true)
{
// straftimer erstellen und seinen intervall auf 10 sekunden einstellen
straftimer = new QTimer(this);
straftimer->setInterval(10000);
// signal - slot verbindungen
// reaktionen auf straftimer ermoeglichen
connect(straftimer, SIGNAL(timeout()), this, SLOT(reaktion_auf_timeout()));
}
Punktezaehler::~Punktezaehler()
{
}
void Punktezaehler::neuer_zug(const Zug& zug)
{
// auf ungueltigen zug pruefen
if (zug.ist_gueltig() == false)
{
qDebug() << tr("Invalid move in Punktzaehler::neuer_zug()");
exit(1);
}
// nur, wenn ein spiel laeuft
if (scene->laufendes_spiel() == true)
{
// wenn straftimer noch nicht laueft
if (straftimer->isActive() == false && scene->laufendes_spiel() == true)
{
straftimer->start();
emit erster_zug();
}
punkte += kalkuliere_punkte(zug);
if (straftimer->isActive() == true && bringt_zeitaufschub(zug) == true)
{
straftimer->stop();
straftimer->start();
}
emit neue_punktzahl(punkte);
}
}
void Punktezaehler::neues_spiel()
{
straftimer->stop();
punkte = 0;
emit neue_punktzahl(punkte);
nach_oben_liste.clear();
}
void Punktezaehler::spiel_zuende()
{
straftimer->stop();
}
void Punktezaehler::reaktion_auf_timeout()
{
if (punkte > 0)
{
if (nur_eine_ziehen == true) punkte -= PUNKTEZAEHLER_EINE_ZIEHEN_PUNKTEABZUG_ZEIT;
else punkte -= PUNKTEZAEHLER_DREI_ZIEHEN_PUNKTEABZUG_ZEIT;
if (punkte < 0) punkte = 0;
emit neue_punktzahl(punkte);
}
}
void Punktezaehler::stapel_durch()
{
if (punkte > 0)
{
if (nur_eine_ziehen == true) punkte -= PUNKTEZAEHLER_EINE_ZIEHEN_AUSTEILSTAPEL_DURCH;
else punkte -= PUNKTEZAEHLER_DREI_ZIEHEN_AUSTEILSTAPEL_DURCH;
if (punkte < 0) punkte = 0;
emit neue_punktzahl(punkte);
}
}
int Punktezaehler::punktstand() const
{
return punkte;
}
void Punktezaehler::eine_ziehen()
{
nur_eine_ziehen = true;
}
void Punktezaehler::drei_ziehen()
{
nur_eine_ziehen = false;
}
void Punktezaehler::undo_meldung(const Zug& zug)
{
// die punke des rueckgaengi gemachten zuges wieder abziehen
nach_oben_liste.removeAll(zug.karte_name());
punkte -= kalkuliere_punkte(zug);
emit neue_punktzahl(punkte);
}
int Punktezaehler::kalkuliere_punkte(const Zug& zug) const
{
int erg = 0;
// wenn es sich um eine bewegung handelt
if (zug.ist_bewegung() == true)
{
// vom austeilstapel zu einem ablagestapel bringt 5 punkte
if (zug.herkunft_name() == BASISSTAPEL_AUSTEILCOSTAPEL && zug.ziel_name().contains(BASISSTAPEL_ABLAGESTAPEL) == true)
{
if (nur_eine_ziehen == true) erg += PUNKTEZAEHLER_EINE_ZIEHEN_AUSTEILSTAPEL_ZU_ABLAGESTAPEL;
else erg += PUNKTEZAEHLER_DREI_ZIEHEN_AUSTEILSTAPEL_ZU_ABLAGESTAPEL;
}
// vom austeilcostapel zum zielstapel bringt 15 punkte
else if (zug.herkunft_name() == BASISSTAPEL_AUSTEILCOSTAPEL && zug.ziel_name().contains(BASISSTAPEL_ZIELSTAPEL) == true && nach_oben_liste.contains(zug.karte_name()) == false)
{
// man soll fuer das hochlegen einer karte nicht mehrfach punkte kassieren koennen
if (nur_eine_ziehen == true) erg += PUNKTEZAEHLER_EINE_ZIEHEN_AUSTEILSTAPEL_ZU_ZIELSTAPEL;
else erg += PUNKTEZAEHLER_DREI_ZIEHEN_AUSTEILSTAPEL_ZU_ZIELSTAPEL;
}
// von unten zum zielstapel bringt 10 punkte
else if (zug.herkunft_name().contains(BASISSTAPEL_ABLAGESTAPEL) == true && zug.ziel_name().contains(BASISSTAPEL_ZIELSTAPEL) == true && nach_oben_liste.contains(zug.karte_name()) == false)
{
if (nur_eine_ziehen == true) erg += PUNKTEZAEHLER_EINE_ZIEHEN_ABLAGESTAPEL_ZU_ZIELSTAPEL;
else erg += PUNKTEZAEHLER_DREI_ZIEHEN_ABLAGESTAPEL_ZU_ZIELSTAPEL;
}
}
// wenn es sich bei zug um eine aufdeckung handelt
else if (zug.ist_aufdeckgung() == true)
{
// wenn eine karte vom ablagestapel aufgedeckt wurde gibt's dafuer 5 punkte
if (zug.herkunft_name().contains(BASISSTAPEL_ABLAGESTAPEL) == true)
{
if (nur_eine_ziehen == true) erg += PUNKTEZAEHLER_EINE_ZIEHEN_KARTE_AUF_ABLAGESTAPEL_AUFGEDECKT;
else erg += PUNKTEZAEHLER_DREI_ZIEHEN_KARTE_AUF_ABLAGESTAPEL_AUFGEDECKT;
}
}
// wenn es sich weder um eine bewegung noch um eine aufdeckung handelt ist zug ungueltig
else
{
qDebug() << tr("Invalid move in Punktzaehler::kalkuliere_punkte(const Zug& zug)");
exit(1);
}
return erg;
}
bool Punktezaehler::bringt_zeitaufschub(const Zug& zug) const
{
bool erg = false;
// wenn es sich um eine bewegung handelt
if (zug.ist_bewegung() == true)
{
// vom austeilstapel zu einem ablagestapel bringt zeitaufschub
if (zug.herkunft_name() == BASISSTAPEL_AUSTEILCOSTAPEL && zug.ziel_name().contains(BASISSTAPEL_ABLAGESTAPEL) == true) erg = true;
// vom austeilcostapel zum zielstapel bringt zeitaufschub
else if (zug.herkunft_name() == BASISSTAPEL_AUSTEILCOSTAPEL && zug.ziel_name().contains(BASISSTAPEL_ZIELSTAPEL) == true && nach_oben_liste.contains(zug.karte_name()) == false) erg = true;
// karte unten umstapeln bringt zeitaufschub
else if (zug.herkunft_name().contains(BASISSTAPEL_ABLAGESTAPEL) == true && zug.ziel_name().contains(BASISSTAPEL_ABLAGESTAPEL) == true) erg = true;
// von unten zum zielstapel bringt zeitaufschub
else if (zug.herkunft_name().contains(BASISSTAPEL_ABLAGESTAPEL) == true && zug.ziel_name().contains(BASISSTAPEL_ZIELSTAPEL) == true && nach_oben_liste.contains(zug.karte_name()) == false) erg = true;
// karten vom zielstapel nach unten bringt nur zeitaufschub
else if (zug.herkunft_name().contains(BASISSTAPEL_ZIELSTAPEL) == true && zug.ziel_name().contains(BASISSTAPEL_ABLAGESTAPEL) == true) erg = true;
}
// wenn es sich bei zug um eine aufdeckung handelt
else if (zug.ist_aufdeckgung() == true)
{
// wenn eine karte vom ablagestapel aufgedeckt wurde gibt's dafuer 5 punkte
if (zug.herkunft_name().contains(BASISSTAPEL_ABLAGESTAPEL) == true) erg = true;
}
else
{
qDebug() << tr("Invalid move in Punktzaehler::bringt_zeitaufschub(const Zug& zug)");
exit(1);
}
return erg;
}
const QStringList Punktezaehler::speichere() const
{
QStringList erg;
// die id speichern
erg.append(objectName());
// straftimer zustand speichern
erg.append(QString::number(straftimer->isActive()));
// die nach_oben_liste speichern
QString nach_oben_string;
for (register int idx = 0; idx < nach_oben_liste.size(); idx++)
{
if (idx > 0) nach_oben_string.append(PUNKTEZAEHLER_STRING_SPLITTER);
nach_oben_string.append(nach_oben_liste.at(idx));
}
erg.append(nach_oben_string);
// die punkte speichern
erg.append(QString::number(punkte));
return erg;
}
bool Punktezaehler::lade(const QStringList& daten)
{
bool erg = false;
if (daten.size() == PUNKTEZAEHLER_ANZAHL_SPEICHERELEMENTE && daten.first() == objectName())
{
erg = true;
// noetigenfalls den straftimer starten
if (daten.at(PUNKTEZAEHLER_STRAFTIMER_ON_IDX).toInt() == 1) straftimer->start();
// die nach_oben_liste laden
nach_oben_liste = daten.at(PUNKTEZAEHLER_NACH_OBEN_LISTE_IDX).split(PUNKTEZAEHLER_STRING_SPLITTER, QString::SkipEmptyParts);
// die punkte laden
punkte = daten.at(PUNKTEZAEHLER_PUNKTE_IDX).toInt();
emit neue_punktzahl(punkte);
}
return erg;
}
bool Punktezaehler::begonnenes_spiel() const
{
return straftimer->isActive();
}

View File

@ -0,0 +1,52 @@
#ifndef PUNKTEZAEHLER_H
#define PUNKTEZAEHLER_H
#include <QObject>
#include <QString>
#include <QStringList>
#include "Zug.h"
class QTimer;
class Scene;
class Punktezaehler : public QObject
{
Q_OBJECT
public:
Punktezaehler(Scene *parent);
virtual ~Punktezaehler();
int punktstand() const;
const QStringList speichere() const;
bool lade(const QStringList&);
bool begonnenes_spiel() const;
public slots:
void neuer_zug(const Zug&);
void stapel_durch();
void neues_spiel();
void spiel_zuende();
void eine_ziehen();
void drei_ziehen();
void undo_meldung(const Zug&);
signals:
void neue_punktzahl(int);
void erster_zug();
private slots:
void reaktion_auf_timeout();
private:
int punkte;
QTimer *straftimer;
Scene *scene;
QStringList nach_oben_liste;
bool nur_eine_ziehen;
int kalkuliere_punkte(const Zug&) const;
bool bringt_zeitaufschub(const Zug&) const;
};
#endif

View File

@ -0,0 +1,74 @@
#include "Rahmen.h"
#include "Basisstapel.h"
#include "Proportionen.h"
#include <QPainter>
using namespace std;
Rahmen::Rahmen(Basisstapel* parent) : QObject(parent), QGraphicsItem(0), Groesse(QSizeF(parent->boundingRect().size().width() + (((parent->boundingRect().size().height() / RAHMEN_DICKE_VERHAELTNIS) - 1) * 2), parent->boundingRect().size().height() + (((parent->boundingRect().size().height() / RAHMEN_DICKE_VERHAELTNIS) - 1) * 2))), meinstapel(0), dicke(parent->boundingRect().size().height() / RAHMEN_DICKE_VERHAELTNIS), eckradius(parent->boundingRect().size().height() / RAHMEN_ECKRADIUS_VERHAELTNIS)
{
setZValue(500);
setVisible(false);
}
Rahmen::~Rahmen()
{
}
void Rahmen::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
{
QPen stift(painter->pen());
stift.setWidth(dicke);
stift.setColor(Qt::darkRed);
painter->setPen(stift);
painter->drawRoundedRect(boundingRect().adjusted(dicke / 2, dicke / 2, -(dicke / 2), -(dicke / 2)), eckradius, eckradius);
}
QRectF Rahmen::boundingRect() const
{
return QRectF(QPointF(0, 0), Groesse);
}
void Rahmen::zeige(Basisstapel* stapel, const QPointF& position)
{
if (stapel != meinstapel || isVisible() == false)
meinstapel = stapel;
setPos(QPointF(position.x() - (dicke), position.y() - (dicke)));
setVisible(true);
}
void Rahmen::verstecke()
{
if (isVisible() == true) setVisible(false);
}
Basisstapel* Rahmen::aktueller_stapel() const
{
return meinstapel;
}
void Rahmen::passe_groesse_an(const QRectF& wert)
{
prepareGeometryChange();
Groesse = QSizeF(wert.size().width() + ((wert.size().height() / RAHMEN_DICKE_VERHAELTNIS) * 2), wert.size().height() + ((wert.size().height() / RAHMEN_DICKE_VERHAELTNIS) * 2));
dicke = wert.size().height() / RAHMEN_DICKE_VERHAELTNIS;
eckradius = wert.size().height() / RAHMEN_ECKRADIUS_VERHAELTNIS;
update();
}

View File

@ -0,0 +1,38 @@
#ifndef RAHMEN_H
#define RAHMEN_H
#include <QObject>
#include <QGraphicsItem>
class Basisstapel;
class Rahmen : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
Rahmen(Basisstapel* parent);
virtual ~Rahmen();
void zeige(Basisstapel*, const QPointF&);
Basisstapel *aktueller_stapel() const;
void passe_groesse_an(const QRectF&);
public slots:
void verstecke();
signals:
private slots:
private:
QSizeF Groesse;
Basisstapel* meinstapel;
double dicke;
double eckradius;
void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
QRectF boundingRect() const;
};
#endif

View File

@ -0,0 +1,77 @@
#include "Random.h"
#include <QtGlobal>
#include <QDateTime>
#include <QDebug>
#include <QObject>
#include <climits>
#include <cstdlib>
using namespace std;
namespace Random
{
int random(int min, int max)
{
int ergebnis = 0;
unsigned int differenz = 0;
unsigned int zufall = qrand();
// min muss kleiner als max sein
if (min < max)
{
// die differenz zwischen min und max berechnen
if (min < 0)
{
differenz = max + (0 - min);
}
else
{
differenz = max - min;
}
// dafuer sorgen, das auch der max als ergebnis moeglich ist. jedoch nur, wenn differenz kleiner als UINT_MAX ist !
if (differenz < UINT_MAX) differenz++;
// wenn die differenz groesser als RAND_MAX ist und RAND_MAX kleiner als UINT_MAX ist zufall durch addition zusaetzlicher zufallszahlen vergroessern
if (differenz > RAND_MAX && RAND_MAX < UINT_MAX)
{
// wie oft passt RAND_MAX in ULONG_MAX ?
int schleifen = UINT_MAX / RAND_MAX;
// so oft, wie RAND_MAX in UINT_MAX passt die schleife durchlaufen lassen. dabei beruecksichtigen, das eine abfrage bereits erledigt ist
for (register int idx = 1; idx < schleifen; idx++) zufall += qrand();
}
// zufall in den bereich der differenz bringen
if (zufall > differenz)
{
zufall = zufall % differenz;
}
ergebnis = min + zufall;
}
// wenn min gleich max ist, ist onehin nur ein wert moeglich
else if (min == max)
{
ergebnis = min;
}
else
{
qDebug() << QObject::tr("min is bigger than max !");
exit(1);
}
return ergebnis;
}
void initialisiere()
{
// den zufallssimulator initialisieren
qsrand(QDateTime::currentDateTime().toTime_t() + QTime::currentTime().msec());
}
}

View File

@ -0,0 +1,30 @@
/*
Name: Random
Autor: Andreas Konarski
Erstellt: 18.12.2009.
Version: 0.05
Lizenz: GPL v3
Plattformen: Alle Systeme, auf denen QT 4.5 verfuegbar ist.
Kontakt: programmieren@konarski-wuppertal.de
home: www.konarski-wuppertal.de
Falls ich mit diesem Programm die Rechte von irgend jemand verletzen sollte, bitte ich um einen Hinweis. Wenn dies Tatsaechlich der Fall ist, entferne ich es schnellstmoeglich von meiner Homepage.
*/
#ifndef RANDOM_H
#define RANDOM_H
namespace Random
{
int random(int min, int max);
void initialisiere();
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
#ifndef SCENE_H
#define SCENE_H
#include <QGraphicsScene>
#include <QList>
#include <QMap>
#include <QString>
#include <QDateTime>
class Karte;
class Basisstapel;
class Ablagestapel;
class Siegkontrolle;
class Punktezaehler;
class QTimer;
class Undo;
class QSettings;
class QResizeEvent;
class Scene : public QGraphicsScene
{
Q_OBJECT
public:
Scene(const QString& deckblatt, QObject *parent = 0);
virtual ~Scene();
QList<Karte*> mischen() const;
void alle_karten_verdecken();
bool laufendes_spiel() const;
bool nur_eine_wird_gezogen() const;
void initialisiere_rahmen(bool);
Karte* suche_karte(const QString&) const;
Basisstapel *suche_stapel(const QString&) const;
bool enthaelt_karte(const QString&) const;
bool enthaelt_stapel(const QString&) const;
const QStringList speichere() const;
bool lade(const QStringList&);
void registriere_einstellungen(QSettings*);
void lade_spielstand();
void speichere_spielstand();
bool begonnenes_spiel() const;
void groessenanpassung(QResizeEvent*);
public slots:
void setze_spiel_zurueck();
void neues_spiel();
void lade_franzoesisches_deckblatt();
void lade_deutsches_deckblatt();
void eine_ziehen();
void drei_ziehen();
void rueckgaengig();
signals:
void gewonnen(int, long);
void neues_spiel_gestartet();
void neue_punktzahl(int);
void verstrichene_sekunden(long);
void relay_eine_ziehen();
void relay_drei_ziehen();
void rahmen_anzeigen(bool);
void undo_verfuegbar(bool);
void neue_groesse_karten(double);
private slots:
void blockiere_alle_karten();
void starte_spieltimer();
void stoppe_spieltimer();
void reaktionen_auf_spieltimer();
void gewonnen_relay();
private:
QList<Karte*> kartenliste;
QMap<QString, Karte*> kartenfinder;
Basisstapel *austeilstapel, *austeilcostapel, *kreutzzielstapel, *pikzielstapel, *karozielstapel, *herzzielstapel;
QList<Basisstapel*> ablagestapel;
QList<Basisstapel*> allestapel;
QMap<QString, Basisstapel*> stapelfinder;
Siegkontrolle *siegkontrolle;
bool Laufendes_spiel, nur_eine_ziehen;
Punktezaehler *punktezaehler;
QTimer *spieltimer;
QDateTime startzeitpunkt;
Undo *undo;
QSettings *einstellungen;
const QByteArray berechne_pruefsumme_spielstand();
};
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -0,0 +1,29 @@
#include "Siegkontrolle.h"
#include "Basisstapel.h"
using namespace std;
Siegkontrolle::Siegkontrolle(QObject *parent) : QObject(parent)
{
}
Siegkontrolle::~Siegkontrolle()
{
}
void Siegkontrolle::teste_auf_sieg()
{
// wenn alle zielstapel 13 karten enthalten hat der spieler gewonnen
if (zielstapel.at(0)->karten() == 13 && zielstapel.at(1)->karten() == 13 && zielstapel.at(2)->karten() == 13 && zielstapel.at(3)->karten() == 13) emit gewonnen();
}
void Siegkontrolle::registriere_zielstapel(Basisstapel* kreutzstapel, Basisstapel* pikstapel, Basisstapel* herzstapel, Basisstapel* karostapel)
{
zielstapel.append(kreutzstapel);
zielstapel.append(pikstapel);
zielstapel.append(herzstapel);
zielstapel.append(karostapel);
}

View File

@ -0,0 +1,27 @@
#ifndef SIEGKONTROLLE_H
#define SIEGKONTROLLE_H
#include <QObject>
class Basisstapel;
class Karte;
class Siegkontrolle : public QObject
{
Q_OBJECT
public:
Siegkontrolle(QObject *parent = 0);
virtual ~Siegkontrolle();
void teste_auf_sieg();
void registriere_zielstapel(Basisstapel* kreutzstapel, Basisstapel* pikstapel, Basisstapel* herzstapel, Basisstapel *karostapel);
signals:
void gewonnen();
private:
QList<Basisstapel*> zielstapel;
};
#endif

View File

@ -0,0 +1,98 @@
#include "Speichern_frage.h"
using namespace std;
Speichern_frage::Speichern_frage(QWidget *parent) : QDialog(parent), speichern_wert(true)
{
setupUi(this);
// das resultat voreinstellen
setResult(QDialog::Accepted);
// die groesse des dialogs auf size hint feststellen
setFixedSize(sizeHint());
// signal - slot verbindungen
// die buttons ermoeglichen
connect(nein_button, SIGNAL(clicked()), this, SLOT(nicht_speichern()));
connect(cancel_button, SIGNAL(clicked()), this, SLOT(abbruch()));
connect(ok_button, SIGNAL(clicked()), this, SLOT(speichern()));
connect(merk_box, SIGNAL(toggled(bool)), this, SLOT(releay_verbindung_merk_status(bool)));
}
Speichern_frage::~Speichern_frage()
{
}
void Speichern_frage::speichern()
{
speichern_wert = true;
emit wird_gespeichert(true);
accept();
}
void Speichern_frage::nicht_speichern()
{
speichern_wert = false;
emit wird_nicht_gespeichert(true);
accept();
}
void Speichern_frage::abbruch()
{
merk_box->setChecked(false);
reject();
}
void Speichern_frage::setze_merken(bool wert)
{
if (wert == true) setResult(QDialog::Accepted);
merk_box->setChecked(wert);
emit verbindung_merk_status(!wert);
}
bool Speichern_frage::soll_merken() const
{
return merk_box->isChecked();
}
void Speichern_frage::setze_speichern(bool wert)
{
speichern_wert = wert;
if (wert == true) ok_button->click();
else nein_button->click();
}
bool Speichern_frage::soll_speichern() const
{
return speichern_wert;
}
void Speichern_frage::verbindung_merken(bool wert)
{
setze_merken(!wert);
}
void Speichern_frage::releay_verbindung_merk_status(bool wert)
{
emit verbindung_merk_status(!wert);
}

View File

@ -0,0 +1,38 @@
#ifndef SPEICHERN_FRAGE_H
#define SPEICHERN_FRAGE_H
#include <QDialog>
#include "ui_Speichern_frage.h"
class Speichern_frage : public QDialog, private Ui::Speichern_frage
{
Q_OBJECT
public:
Speichern_frage(QWidget *parent = 0);
virtual ~Speichern_frage();
bool soll_merken() const;
bool soll_speichern() const;
public slots:
void setze_merken(bool);
void setze_speichern(bool);
void verbindung_merken(bool);
private slots:
void speichern();
void nicht_speichern();
void abbruch();
void releay_verbindung_merk_status(bool);
signals:
void verbindung_merk_status(bool);
void wird_gespeichert(bool);
void wird_nicht_gespeichert(bool);
private:
bool speichern_wert;
};
#endif

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Speichern_frage</class>
<widget class="QDialog" name="Speichern_frage">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>365</width>
<height>127</height>
</rect>
</property>
<property name="windowTitle">
<string>Patience - Save game and quit ?</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>21</pointsize>
</font>
</property>
<property name="text">
<string>Save the game and quit ?</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="nein_button">
<property name="text">
<string>Don't Save</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="cancel_button">
<property name="text">
<string>Cancel</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ok_button">
<property name="text">
<string>OK</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="merk_box">
<property name="font">
<font>
<pointsize>15</pointsize>
</font>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Remember answer</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

Binary file not shown.

View File

@ -0,0 +1,364 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="de_DE" sourcelanguage="en">
<context>
<name>Highscore</name>
<message>
<location filename="Highscore.cpp" line="96"/>
<source>Patience</source>
<translation>Patience</translation>
</message>
<message>
<location filename="Highscore.cpp" line="96"/>
<source>You got a Highscore !</source>
<translation>Du hast eine Highscore !</translation>
</message>
<message>
<location filename="Highscore.cpp" line="99"/>
<location filename="Highscore.cpp" line="102"/>
<source>Unknown</source>
<translation>Unbekannt</translation>
</message>
<message>
<location filename="Highscore.ui" line="23"/>
<source>Patience - Highscore</source>
<translation>Patience - Highscore</translation>
</message>
<message>
<location filename="Highscore.ui" line="48"/>
<source>Name</source>
<translation>Name</translation>
</message>
<message>
<location filename="Highscore.ui" line="53"/>
<source>Points</source>
<oldsource>Poits</oldsource>
<translation>Punkte</translation>
</message>
<message>
<location filename="Highscore.ui" line="58"/>
<source>Time</source>
<translation>Zeit</translation>
</message>
<message>
<location filename="Highscore.ui" line="81"/>
<source>Ok</source>
<translation>Fertig</translation>
</message>
</context>
<context>
<name>Karte</name>
<message>
<location filename="Karte.cpp" line="327"/>
<location filename="Karte.cpp" line="345"/>
<source>The Card </source>
<translation>Die Karte </translation>
</message>
<message>
<location filename="Karte.cpp" line="327"/>
<location filename="Karte.cpp" line="345"/>
<source> have more than one Child Card</source>
<translation> hat mehr als eine Kinder Karte</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<location filename="MainWindow.cpp" line="73"/>
<source>Patience - You won !</source>
<translation>Patience - Du hast gewonnen !</translation>
</message>
<message>
<location filename="MainWindow.cpp" line="74"/>
<source>You won, but you don&apos;t reach a highscore.</source>
<translation>Du hast gewonnen, es hat jedoch zu keiner Highscore gereicht.</translation>
</message>
<message>
<location filename="MainWindow.cpp" line="79"/>
<source>Patience - Start new game ?</source>
<translation>Patience - Wirklich ein neues Spiel starten ?</translation>
</message>
<message>
<location filename="MainWindow.cpp" line="80"/>
<source>Start a new Game and break the current Game ?</source>
<translation>Wirklich ein neues Spiel starten und das momentane Spiel beenden ?</translation>
</message>
<message>
<location filename="MainWindow.ui" line="140"/>
<location filename="MainWindow.cpp" line="182"/>
<source>About Patience</source>
<translation>Über Patience</translation>
</message>
<message>
<location filename="MainWindow.cpp" line="182"/>
<source>Patience Version </source>
<translation>Patience Version</translation>
</message>
<message>
<location filename="MainWindow.cpp" line="259"/>
<source> Points</source>
<oldsource> Punkte</oldsource>
<translation> Punkte</translation>
</message>
<message>
<location filename="MainWindow.ui" line="14"/>
<source>Patience</source>
<translation>Patience</translation>
</message>
<message>
<location filename="MainWindow.ui" line="59"/>
<source>Game</source>
<translation>Spiel</translation>
</message>
<message>
<location filename="MainWindow.ui" line="67"/>
<source>&amp;Help</source>
<translation>&amp;Hilfe</translation>
</message>
<message>
<location filename="MainWindow.ui" line="78"/>
<source>&amp;Cardset</source>
<translation>&amp;Kartentyp</translation>
</message>
<message>
<location filename="MainWindow.ui" line="108"/>
<source>&amp;Highscore</source>
<translation>&amp;Highscore</translation>
</message>
<message>
<location filename="MainWindow.ui" line="85"/>
<source>Gametype</source>
<translation>Spieltyp</translation>
</message>
<message>
<location filename="MainWindow.ui" line="74"/>
<source>&amp;Settings</source>
<translation>&amp;Einstellungen</translation>
</message>
<message>
<location filename="MainWindow.ui" line="92"/>
<source>Save Game</source>
<translation>Spiel speichern</translation>
</message>
<message>
<location filename="MainWindow.ui" line="114"/>
<source>&amp;Edit</source>
<translation>&amp;Bearbeiten</translation>
</message>
<message>
<location filename="MainWindow.ui" line="127"/>
<source>&amp;New Game</source>
<translation>&amp;Neues Spiel</translation>
</message>
<message>
<location filename="MainWindow.ui" line="130"/>
<source>Ctrl+N</source>
<translation>Ctrl+N</translation>
</message>
<message>
<location filename="MainWindow.ui" line="135"/>
<source>Close</source>
<translation>Schliessen</translation>
</message>
<message>
<location filename="MainWindow.ui" line="145"/>
<source>About QT</source>
<translation>Über QT</translation>
</message>
<message>
<location filename="MainWindow.ui" line="153"/>
<location filename="MainWindow.ui" line="190"/>
<source>French</source>
<translation>Französisch</translation>
</message>
<message>
<location filename="MainWindow.ui" line="161"/>
<location filename="MainWindow.ui" line="198"/>
<source>German</source>
<translation>Deutsch</translation>
</message>
<message>
<location filename="MainWindow.ui" line="166"/>
<source>&amp;Show</source>
<translation>&amp;Anzeigen</translation>
</message>
<message>
<location filename="MainWindow.ui" line="174"/>
<location filename="MainWindow.ui" line="206"/>
<source>Take One</source>
<translation>Eine ziehen</translation>
</message>
<message>
<location filename="MainWindow.ui" line="182"/>
<location filename="MainWindow.ui" line="214"/>
<source>Take Three</source>
<translation>Drei ziehen</translation>
</message>
<message>
<location filename="MainWindow.ui" line="225"/>
<source>Frame</source>
<translation>Rahmen</translation>
</message>
<message>
<location filename="MainWindow.ui" line="241"/>
<source>Ask</source>
<translation>Fragen</translation>
</message>
<message>
<location filename="MainWindow.ui" line="252"/>
<source>Save</source>
<translation>Speichern</translation>
</message>
<message>
<location filename="MainWindow.ui" line="260"/>
<source>Don&apos;t save</source>
<translation>Nicht speichern</translation>
</message>
<message>
<source>Ask for saving on quit.</source>
<oldsource>Ask for saving on quit</oldsource>
<translation type="obsolete">Beim beenden wegen speichern fragen.</translation>
</message>
<message>
<source>Disable for slow computers.</source>
<translation type="obsolete">Für langsame Computer deaktivieren.</translation>
</message>
<message>
<location filename="MainWindow.ui" line="230"/>
<source>Undo</source>
<translation>Rückgängig</translation>
</message>
</context>
<context>
<name>Punktezaehler</name>
<message>
<location filename="Punktezaehler.cpp" line="32"/>
<source>Invalid move in Punktzaehler::neuer_zug()</source>
<translation>Ungültiger zug in Punktzaehler::neuer_zug()</translation>
</message>
<message>
<location filename="Punktezaehler.cpp" line="179"/>
<source>Invalid move in Punktzaehler::kalkuliere_punkte(const Zug&amp; zug)</source>
<translation>Ungültiger zug in Punktzaehler::kalkuliere_punkte(const Zug&amp; zug)</translation>
</message>
<message>
<location filename="Punktezaehler.cpp" line="220"/>
<source>Invalid move in Punktzaehler::bringt_zeitaufschub(const Zug&amp; zug)</source>
<translation>Ungültiger zug in Punktzaehler::bringt_zeitaufschub(const Zug&amp; zug)</translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<location filename="Random.cpp" line="64"/>
<source>min is bigger than max !</source>
<translation>min ist größer als max !</translation>
</message>
</context>
<context>
<name>Scene</name>
<message>
<location filename="Scene.cpp" line="668"/>
<source>Missing Cards in Scene !</source>
<translation>Fehlende Karte in Scene !</translation>
</message>
<message>
<location filename="Scene.cpp" line="1028"/>
<source>Unable to restore scene !</source>
<translation>Kann Scene nicht wiederherstellen !</translation>
</message>
<message>
<location filename="Scene.cpp" line="1035"/>
<source>Unable to restore stacks !</source>
<translation>Kann Stapel nicht wiederherstellen !</translation>
</message>
<message>
<location filename="Scene.cpp" line="1043"/>
<source>Unable to restore cards !</source>
<translation>Kann Karten nicht wiederherstellen !</translation>
</message>
<message>
<location filename="Scene.cpp" line="1051"/>
<source>Unable to restore undo !</source>
<translation>Kann Undo nicht wiederherstellen !</translation>
</message>
<message>
<location filename="Scene.cpp" line="1059"/>
<source>Unable to restore points !</source>
<translation>Kann Punkte nicht wiederherstellen !</translation>
</message>
<message>
<location filename="Scene.cpp" line="1067"/>
<source>Card with 0 batch after restoring gamestate !</source>
<translation>Karte mit 0 Eigentümer Stapel nach dem wiederherstellen eines Spielstandes !</translation>
</message>
<message>
<location filename="Scene.cpp" line="1077"/>
<source>Wrong checksumm while restoring saved game !</source>
<translation>Falsche Prüfsumme beim wiederherstellen des Spielstandes !</translation>
</message>
<message>
<location filename="Scene.cpp" line="1093"/>
<source>Unable to restore saved game. Trying to start a new game ...</source>
<translation>Das gespeicherte Spiel kann nicht wiederhergestellt werden. Versuche ein neues Spiel zu starten ...</translation>
</message>
</context>
<context>
<name>Speichern_frage</name>
<message>
<location filename="Speichern_frage.ui" line="17"/>
<source>Patience - Save game and quit ?</source>
<translation>Patience - Spiel beenden und speichern ?</translation>
</message>
<message>
<location filename="Speichern_frage.ui" line="55"/>
<source>Save the game and quit ?</source>
<translation>Spiel beenden &amp; speichern ?</translation>
</message>
<message>
<location filename="Speichern_frage.ui" line="81"/>
<source>Don&apos;t Save</source>
<translation>Nicht speichern</translation>
</message>
<message>
<location filename="Speichern_frage.ui" line="108"/>
<source>Cancel</source>
<translation>Abbrechen</translation>
</message>
<message>
<location filename="Speichern_frage.ui" line="121"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
<location filename="Speichern_frage.ui" line="158"/>
<source>Remember answer</source>
<translation>Antwort merken</translation>
</message>
</context>
<context>
<name>Undo</name>
<message>
<location filename="Undo.cpp" line="41"/>
<location filename="Undo.cpp" line="61"/>
<source>Invalid move in Undo::undo()</source>
<translation>Ungültiger zug in Undo::undo()</translation>
</message>
<message>
<source>Invalid cover in Undo::undo()</source>
<translation type="obsolete">Ungültige Karten zudeckung in Undo::undo()</translation>
</message>
<message>
<source>Invalid history entry in Undo</source>
<translation type="obsolete">Ungültiger History Eintrag in Undo</translation>
</message>
</context>
<context>
<name>Zielstapel</name>
<message>
<location filename="Zielstapel.cpp" line="68"/>
<source>Destination not found in Zielstapel::lege_karte_ab(Karte* karte)</source>
<translation>Zielstapel nicht auffindbar in Zielstapel::lege_karte_ab(Karte* karte)</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,194 @@
#include "Undo.h"
#include "Karte.h"
#include "Basisstapel.h"
#include "Scene.h"
#include "Proportionen.h"
#include <QDebug>
#include <cstdlib>
using namespace std;
Undo::Undo(Scene *parent) : QObject(parent), scene(parent)
{
}
Undo::~Undo()
{
}
void Undo::speichere_zug(const Zug& zug)
{
if (zug.ist_bewegung() == true)
{
verlauf.append(zug);
// wenn es sich um den ersten gespeicherten zug handelt
if (verlauf.size() == 1) emit undo_verfuegbar(true);
}
else if (zug.ist_aufdeckgung() == true)
{
verlauf.append(zug);
// wenn es sich um den ersten gespeicherten zug handelt
if (verlauf.size() == 1) emit undo_verfuegbar(true);
}
else
{
qDebug() << tr("Invalid move in Undo::undo()");
exit(1);
}
// ueberschuessige undoelemente loeschen
loesche_ueberschuessige_undoelemente();
}
void Undo::undo()
{
// wenn der verlauf nicht leer ist
if (verlauf.isEmpty() == false)
{
Zug zugelement(verlauf.takeLast());
// wenn das zug element ungueltig ist eine fehlermeldung ausgeben und das programm abbrechen
if (zugelement.ist_gueltig() == false)
{
qDebug() << tr("Invalid move in Undo::undo()");
exit(1);
}
// wenn es sich um eine bewegung handelt
if (zugelement.ist_bewegung() == true)
{
// den zug unter umgehung der ueberpruefungen und signale rueckgaengig machen.
zugelement.herkunft()->undo_karten_ablage(zugelement.karte());
scene->update();
}
// wenn es sich um eine karten aufdeckung handelt
else if (zugelement.ist_aufdeckgung() == true)
{
// die karten aufdeckung unter umgehung der ueberpruefungen und signale rueckgaengig machen.
zugelement.karte()->zeige_rueckseite();
scene->update();
}
emit undo_verfuegbar(!verlauf.isEmpty());
emit undo_meldung(zugelement);
}
}
void Undo::clear()
{
emit undo_verfuegbar(false);
verlauf.clear();
}
void Undo::loesche_ueberschuessige_undoelemente()
{
float summe = 0;
// den wert der zuege, die sich derzeit in verlauf befinden berechnen
for (register int idx = 0; idx < verlauf.size(); idx++)
{
if (verlauf.at(idx).ist_bewegung() == true) summe += ZUEGE_PRO_BEWEGUNG;
else if (verlauf.at(idx).ist_aufdeckgung() == true) summe += ZUEGE_PRO_AUFDECKUNG;
}
// den ueberschuss entfernen
float ueberschuss = summe - UNDO_LIMIT;
// wenn ein ueberschuss vorhanden ist ...
if (ueberschuss > 0.1)
{
// solange, wie ein ueberschuss vorhanden ist
while (verlauf.isEmpty() == false && ueberschuss > 0.1)
{
// dem zug entsprechende punktzahl abziehen
if (verlauf.first().ist_bewegung() == true) ueberschuss -= ZUEGE_PRO_BEWEGUNG;
else if (verlauf.first().ist_aufdeckgung() == true) ueberschuss -= ZUEGE_PRO_AUFDECKUNG;
// das aelteste element entfernen
verlauf.removeFirst();
}
}
}
const QStringList Undo::speichere() const
{
QStringList erg;
// die id speichern
erg.append(objectName());
// die verlauf liste speichern
QString verlauf_string;
for (register int idx = 0; idx < verlauf.size(); idx++)
{
if (idx > 0) verlauf_string.append(ZUEGE_SPLITTER);
verlauf_string.append(verlauf.at(idx).karte_name());
verlauf_string.append(ZUEGE_NACH_SPLITTER);
verlauf_string.append(verlauf.at(idx).herkunft_name());
if (verlauf.at(idx).ist_bewegung() == true)
{
verlauf_string.append(ZUEGE_NACH_SPLITTER);
verlauf_string.append(verlauf.at(idx).ziel_name());
}
}
erg.append(verlauf_string);
return erg;
}
bool Undo::lade(const QStringList& daten)
{
bool erg = false;
if (daten.size() == UNDO_ANZAHL_SPEICHERELEMENTE && daten.first() == objectName())
{
erg = true;
QStringList tmp_daten(daten.at(UNDO_VERLAUF_IDX).split(ZUEGE_SPLITTER, QString::SkipEmptyParts));
for (register int idx = 0; idx < tmp_daten.size(); idx++)
{
QStringList tmp_zug(tmp_daten.at(idx).split(ZUEGE_NACH_SPLITTER, QString::SkipEmptyParts));
if (tmp_zug.size() == 2)
{
if (scene->enthaelt_karte(tmp_zug.at(0)) == true && scene->enthaelt_stapel(tmp_zug.at(1)) == true) verlauf.append(Zug(scene->suche_karte(tmp_zug.at(0)), scene->suche_stapel(tmp_zug.at(1))));
else erg = false;
}
else if (tmp_zug.size() == 3)
{
if (scene->enthaelt_karte(tmp_zug.at(0)) == true && scene->enthaelt_stapel(tmp_zug.at(1)) == true && scene->enthaelt_stapel(tmp_zug.at(2)) == true) verlauf.append(Zug(scene->suche_karte(tmp_zug.at(0)), scene->suche_stapel(tmp_zug.at(1)), scene->suche_stapel(tmp_zug.at(2))));
else erg = false;
}
else erg = false;
}
}
if (erg == true && verlauf.isEmpty() == false) emit undo_verfuegbar(true);
return erg;
}

View File

@ -0,0 +1,40 @@
#ifndef UNDO_H
#define UNDO_H
#include <QObject>
#include <QMap>
#include <QList>
#include "Zug.h"
class Karte;
class Basisstapel;
class Scene;
class Undo : public QObject
{
Q_OBJECT
public:
Undo(Scene *parent);
virtual ~Undo();
const QStringList speichere() const;
bool lade(const QStringList&);
public slots:
void speichere_zug(const Zug&);
void undo();
void clear();
signals:
void undo_meldung(const Zug&);
void undo_verfuegbar(bool);
private:
QList<Zug> verlauf;
Scene *scene;
void loesche_ueberschuessige_undoelemente();
};
#endif

View File

@ -0,0 +1,22 @@
#include "Viewer.h"
#include "Scene.h"
#include <QResizeEvent>
using namespace std;
Viewer::Viewer(QWidget *parent) : QGraphicsView(parent)
{
}
Viewer::~Viewer()
{
}
void Viewer::resizeEvent(QResizeEvent* event)
{
QGraphicsView::resizeEvent(event);
if (scene() != 0) ((Scene*) scene())->groessenanpassung(event);
}

View File

@ -0,0 +1,18 @@
#ifndef VIEWER_H
#define VIEWER_H
#include <QGraphicsView>
class Viewer : public QGraphicsView
{
Q_OBJECT
public:
Viewer(QWidget *parent = 0);
virtual ~Viewer();
private:
virtual void resizeEvent(QResizeEvent*);
};
#endif

View File

@ -0,0 +1,80 @@
#include "Zielstapel.h"
#include "Karte.h"
#include "Siegkontrolle.h"
#include <QDebug>
using namespace std;
Zielstapel::Zielstapel(const QPixmap& pixmap, Scene* oparent, QGraphicsItem* gparent) : Basisstapel(pixmap, oparent, gparent), siegkontrolle(0)
{
}
Zielstapel::~Zielstapel()
{
}
bool Zielstapel::ablage_moeglich(Karte* karte) const
{
bool erg = false;
if (Basisstapel::ablage_moeglich(karte) == true && ((oberste_karte() == 0 && karte->wert() == 1) || (oberste_karte() != 0 &&oberste_karte()->farbe() == karte->farbe() && karte->wert() == (oberste_karte()->wert() + 1))) && karte->hat_kinderkarten() == false) erg = true;
return erg;
}
void Zielstapel::registriere_siegkontrolle(Siegkontrolle* siegkontrolle_)
{
siegkontrolle = siegkontrolle_;
}
void Zielstapel::ablage_erfolgt()
{
siegkontrolle->teste_auf_sieg();
}
void Zielstapel::registriere_nachbar_zielstapel(Basisstapel* erster, Basisstapel* zweiter, Basisstapel* dritter)
{
nachbarn.append(erster);
nachbarn.append(zweiter);
nachbarn.append(dritter);
}
bool Zielstapel::lege_karte_ab(Karte* karte)
{
bool erg = false;
Basisstapel *ziel = 0;
QString quelle(karte->eigentuemer_stapel()->objectName());
// wenn dieser stapel der richtige ist ...
if (objectName().contains(karte->farbe()) == true) erg = Basisstapel::lege_karte_ab(karte);
// ansonsten den richtigen stapel suchen ...
else
{
for (register int idx = 0; idx < nachbarn.size() && ziel == 0; idx++) if (nachbarn.at(idx)->objectName().contains(karte->farbe()) == true) ziel = nachbarn.at(idx);
// ... und die karte auf diesem ablegen
if (ziel != 0) erg = ziel->lege_karte_ab(karte);
else
{
qDebug() << tr("Destination not found in Zielstapel::lege_karte_ab(Karte* karte)");
}
}
return erg;
}
void Zielstapel::hilfsanfrage_start(Karte* karte)
{
// dafuer sorgen, das der hilfspfeil nur uber dem richtigen zielstapel erscheint
if (objectName().contains(karte->farbe()) == true) Basisstapel::hilfsanfrage_start(karte);
}

View File

@ -0,0 +1,32 @@
#ifndef ZIELSTAPEL_H
#define ZIELSTAPEL_H
#include "Basisstapel.h"
#include <QList>
class Siegkontrolle;
class Zielstapel : public Basisstapel
{
Q_OBJECT
public:
Zielstapel(const QPixmap& pixmap, Scene* oparent, QGraphicsItem* gparent = 0);
virtual ~Zielstapel();
virtual void registriere_siegkontrolle(Siegkontrolle*);
virtual void registriere_nachbar_zielstapel(Basisstapel*, Basisstapel*, Basisstapel*);
virtual void ablage_erfolgt();
virtual bool ablage_moeglich(Karte *) const;
virtual bool lege_karte_ab(Karte*);
public slots:
virtual void hilfsanfrage_start(Karte*);
private:
Siegkontrolle *siegkontrolle;
QList<Basisstapel*> nachbarn;
};
#endif

View File

@ -0,0 +1,131 @@
#include "Zug.h"
#include "Karte.h"
#include "Basisstapel.h"
#include <QObject>
using namespace std;
Zug::Zug() : Karte_(0), Herkunft(0), Ziel(0)
{
}
Zug::~Zug()
{
}
bool Zug::ist_gueltig() const
{
bool erg = false;
if (ist_bewegung() == true) erg = true;
else if (ist_aufdeckgung() == true) erg = true;
return erg;
}
bool Zug::ist_bewegung() const
{
bool erg = false;
if (Karte_ != 0 && Herkunft != 0 && Ziel != 0) erg = true;
return erg;
}
bool Zug::ist_aufdeckgung() const
{
bool erg = false;
if (Karte_ != 0 && Herkunft != 0 && Ziel == 0) erg = true;
return erg;
}
void Zug::setze_bewegung(Karte* karte, Basisstapel *herkunft_, Basisstapel *ziel_)
{
Karte_ = karte;
Herkunft = herkunft_;
Ziel = ziel_;
}
void Zug::setze_aufdeckung(Karte* karte, Basisstapel *ort)
{
Karte_ = karte;
Herkunft = ort;
Ziel = 0;
}
Karte* Zug::karte() const
{
return Karte_;
}
Basisstapel* Zug::herkunft() const
{
return Herkunft;
}
Basisstapel* Zug::ziel() const
{
return Ziel;
}
QString Zug::karte_name() const
{
QString erg;
if (Karte_ != 0) erg = Karte_->objectName();
return erg;
}
QString Zug::herkunft_name() const
{
QString erg;
if (Herkunft != 0) erg = Herkunft->objectName();
return erg;
}
QString Zug::ziel_name() const
{
QString erg;
if (Ziel != 0) erg = Ziel->objectName();
return erg;
}
Zug::Zug(Karte* karte, Basisstapel *herkunft, Basisstapel *ziel) : Karte_(karte), Herkunft(herkunft), Ziel(ziel)
{
}
Zug::Zug(Karte* karte, Basisstapel *ort) : Karte_(karte), Herkunft(ort), Ziel(0)
{
}
bool Zug::operator==(const Zug& anderer) const
{
bool erg = false;
if (karte() == anderer.karte() && herkunft() == anderer.herkunft() && ziel() == anderer.ziel()) erg = true;
return erg;
}

View File

@ -0,0 +1,40 @@
#ifndef ZUG_H
#define ZUG_H
#include <QString>
class Karte;
class Basisstapel;
class Zug
{
public:
Zug();
Zug(Karte* karte, Basisstapel *herkunft, Basisstapel *ziel);
Zug(Karte* karte, Basisstapel *ort);
virtual ~Zug();
bool ist_gueltig() const;
bool ist_bewegung() const;
bool ist_aufdeckgung() const;
void setze_bewegung(Karte* karte, Basisstapel *herkunft_, Basisstapel *ziel_);
void setze_aufdeckung(Karte* karte, Basisstapel *ort);
Karte* karte() const;
Basisstapel* herkunft() const;
Basisstapel* ziel() const;
QString karte_name() const;
QString herkunft_name() const;
QString ziel_name() const;
bool operator==(const Zug& anderer) const;
private:
Karte *Karte_;
Basisstapel *Herkunft, *Ziel;
};
#endif

View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 919 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Some files were not shown because too many files have changed in this diff Show More