summaryrefslogtreecommitdiff
path: root/noncore/games/mindbreaker
Side-by-side diff
Diffstat (limited to 'noncore/games/mindbreaker') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/mindbreaker/.cvsignore4
-rw-r--r--noncore/games/mindbreaker/Makefile.in117
-rw-r--r--noncore/games/mindbreaker/main.cpp35
-rw-r--r--noncore/games/mindbreaker/mindbreaker.cpp818
-rw-r--r--noncore/games/mindbreaker/mindbreaker.h122
-rw-r--r--noncore/games/mindbreaker/mindbreaker.pro12
-rw-r--r--noncore/games/mindbreaker/qpe-mindbreaker.control9
7 files changed, 1117 insertions, 0 deletions
diff --git a/noncore/games/mindbreaker/.cvsignore b/noncore/games/mindbreaker/.cvsignore
new file mode 100644
index 0000000..415ec09
--- a/dev/null
+++ b/noncore/games/mindbreaker/.cvsignore
@@ -0,0 +1,4 @@
+Makefile
+moc_*
+helpdialog.cpp
+helpdialog.h
diff --git a/noncore/games/mindbreaker/Makefile.in b/noncore/games/mindbreaker/Makefile.in
new file mode 100644
index 0000000..88f6fb1
--- a/dev/null
+++ b/noncore/games/mindbreaker/Makefile.in
@@ -0,0 +1,117 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = mindbreaker
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = mindbreaker.h
+SOURCES = main.cpp \
+ mindbreaker.cpp
+OBJECTS = main.o \
+ mindbreaker.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_mindbreaker.cpp
+OBJMOC = moc_mindbreaker.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake mindbreaker.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ mindbreaker.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+mindbreaker.o: mindbreaker.cpp \
+ mindbreaker.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+moc_mindbreaker.o: moc_mindbreaker.cpp \
+ mindbreaker.h
+
+moc_mindbreaker.cpp: mindbreaker.h
+ $(MOC) mindbreaker.h -o moc_mindbreaker.cpp
+
+
diff --git a/noncore/games/mindbreaker/main.cpp b/noncore/games/mindbreaker/main.cpp
new file mode 100644
index 0000000..8ba0fde
--- a/dev/null
+++ b/noncore/games/mindbreaker/main.cpp
@@ -0,0 +1,35 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mindbreaker.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char **argv )
+{
+ QPEApplication a( argc, argv );
+
+ MindBreaker w(0, "new window");
+ w.setCaption("Mind Breaker");
+ QPEApplication::setInputMethodHint( &w, QPEApplication::AlwaysOff );
+ a.showMainWidget(&w);
+
+ return a.exec();
+}
diff --git a/noncore/games/mindbreaker/mindbreaker.cpp b/noncore/games/mindbreaker/mindbreaker.cpp
new file mode 100644
index 0000000..b0e4d88
--- a/dev/null
+++ b/noncore/games/mindbreaker/mindbreaker.cpp
@@ -0,0 +1,818 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mindbreaker.h"
+
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qpe/qpetoolbar.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+#include <qmessagebox.h>
+#include <qlabel.h>
+#include <qstyle.h>
+
+#include <stdlib.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+static int pegRTTI = 3393393;
+
+/* helper class, */
+class Peg : public QCanvasRectangle
+{
+public:
+ Peg(QCanvas *canvas, int type, int go = -1, int pos = -1);
+ int rtti() const {return pegRTTI; }
+ void advance(int phase);
+
+ bool hit( const QPoint &) const;
+
+/* a placed peg is one that has been set down on the board correctly and
+ should not be moved, only copied */
+ bool placed() const;
+ void setPlaced(bool);
+
+ int pegGo() const;
+ int pegPos() const;
+ void setPegPos(int);
+
+ int type() const;
+
+ static void buildImages();
+ static QImage imageForType(int t);
+
+ static int eggLevel;
+
+protected:
+ void drawShape(QPainter &);
+private:
+ static QVector<QImage> normalPegs;
+ static QVector<QImage> specialPegs;
+
+ bool isplaced;
+ int pegtype;
+ int peg_go;
+ int peg_pos;
+
+ int aniStep;
+};
+
+int Peg::eggLevel = 0;
+QVector<QImage> Peg::normalPegs;
+QVector<QImage> Peg::specialPegs;
+
+void Peg::buildImages()
+{
+
+ QImage pegs = Resource::loadImage("mindbreaker/pegs");
+ int x = 0;
+ int y = 0;
+ int i;
+ eggLevel = 0;
+ normalPegs.resize(10);
+ for (i = 0; i < 6; i++) {
+ normalPegs.insert(i, new QImage(pegs.copy(x, y, peg_size, peg_size)));
+ x += peg_size;
+ }
+ specialPegs.resize(5);
+ for (i = 0; i < 5; i++) {
+ specialPegs.insert(i, new QImage(pegs.copy(x,y,peg_size, peg_size)));
+ x += peg_size;
+ }
+
+ QImage image = Resource::loadImage("mindbreaker/mindbreaker");
+ /* copy from master image to functional images */
+ x = 0;
+ y = panel_height;
+ normalPegs.insert(8,
+ new QImage(image.copy(x, y, panel_width, panel_height)));
+ y += panel_height;
+ y += title_height;
+ normalPegs.insert(9,
+ new QImage(image.copy(x, y, title_width, title_height)));
+ y += title_height;
+
+ x = 6 * peg_size;
+ normalPegs.insert(6,
+ new QImage(image.copy(x, y, answerpeg_size, answerpeg_size)));
+ x += answerpeg_size;
+ normalPegs.insert(7,
+ new QImage(image.copy(x, y, answerpeg_size, answerpeg_size)));
+}
+
+QImage Peg::imageForType(int t)
+{
+ if (eggLevel > t ) {
+ if( t < 5) {
+ return *specialPegs[t];
+ } else {
+ return *normalPegs[rand() % 6];
+ }
+ }
+ return *normalPegs[t];
+}
+
+Peg::Peg(QCanvas *canvas , int t, int g = -1, int p = -1)
+ : QCanvasRectangle(canvas)
+{
+ setSize(normalPegs[t]->width(), normalPegs[t]->height() );
+ pegtype = t;
+ isplaced = FALSE;
+ peg_pos = p;
+ peg_go = g;
+ aniStep = rand() % 6;
+ setAnimated(TRUE);
+}
+
+void Peg::advance(int phase) {
+ if (phase == 0)
+ aniStep = (++aniStep) % 6;
+ else {
+ hide();
+ show();
+ }
+}
+
+void Peg::drawShape(QPainter &p )
+{
+ if ((pegtype == 5) && eggLevel > 5) {
+ p.drawImage(x(), y(), *normalPegs[aniStep]);
+ } else
+ p.drawImage(x(), y(), imageForType(pegtype));
+}
+
+bool Peg::hit( const QPoint &p ) const
+{
+ int ix = p.x() - int(x());
+ int iy = p.y() - int(y());
+ if (!normalPegs[pegtype]->valid(ix, iy))
+ return FALSE;
+ QRgb pixel = normalPegs[pegtype]->pixel(ix, iy);
+ return (qAlpha(pixel ) != 0);
+}
+
+inline bool Peg::placed() const
+{
+ return isplaced;
+}
+
+inline int Peg::pegGo() const
+{
+ return peg_go;
+}
+
+inline int Peg::pegPos() const
+{
+ return peg_pos;
+}
+
+inline void Peg::setPegPos(int p)
+{
+ peg_pos = p;
+}
+
+inline void Peg::setPlaced(bool p)
+{
+ isplaced = p;
+}
+
+inline int Peg::type() const
+{
+ return pegtype;
+}
+
+/* Load the main image, copy from it the pegs, the board, and the answer image
+ * and use these to create the tray, answer and board
+ */
+MindBreaker::MindBreaker( QWidget *parent=0, const char *name=0, int wFlags=0 )
+: QMainWindow(parent, name, wFlags),
+ canvas(board_height, board_width)
+{
+ MindBreakerBoard *m = new MindBreakerBoard(canvas, this);
+ setCentralWidget(m);
+
+ setToolBarsMovable( FALSE );
+
+ QPEToolBar *tb = new QPEToolBar(this);
+ tb->setHorizontalStretchable( TRUE );
+
+ QPixmap newicon = Resource::loadPixmap("new");
+ new QToolButton(newicon, tr("New Game"), 0,
+ m, SLOT(clear()), tb, "NewGame");
+
+ score = new QToolButton(tb);
+ score->setText("");
+ score->setMaximumHeight(20);
+ score->setUsesTextLabel(TRUE);
+ tb->setStretchableWidget(score);
+
+ connect(m, SIGNAL(scoreChanged(int, int)), this, SLOT(setScore(int, int)));
+ connect(score, SIGNAL(clicked()), m, SLOT(resetScore()));
+
+ int a, b;
+ m->getScore(&a, &b);
+ setScore(a,b);
+}
+
+void MindBreaker::setScore(int turns, int games)
+{
+ double average;
+ double total_turns = turns;
+ double total_games = games;
+
+ if(total_games > 0)
+ average = total_turns / total_games;
+ else
+ average = 0.0;
+
+ score->setText(tr("win avg: %1 turns (%2 games)").arg(average).arg(games));
+}
+
+
+MindBreakerBoard::MindBreakerBoard( QCanvas &c, QWidget *parent=0,
+ const char *name=0, int wFlags=0 )
+ : QCanvasView(&c, parent, name, wFlags)
+{
+ int i, x, y;
+ struct timeval tv;
+
+ current_go = 0;
+ gettimeofday(&tv, 0);
+
+ srand(tv.tv_usec);
+
+ canvas()->setAdvancePeriod(500);
+
+ QImage image = Resource::loadImage("mindbreaker/mindbreaker");
+
+ /* copy from master image to functional images */
+ x = 0;
+ y = 0;
+ panelImage = image.copy(x,y, panel_width, panel_height);
+ y += panel_height;
+ y += panel_height;
+
+ titleImage = image.copy(x, y, title_width, title_height);
+
+ Peg::buildImages(); // must be done BEFORE any pegs are made
+
+ current_highlight = new Peg(canvas(), 8);
+ current_highlight->setPlaced(TRUE);
+ current_highlight->setX(0);
+ current_highlight->setY(board_height - ((current_go + 1) * panel_height));
+ current_highlight->setZ(0);
+ current_highlight->show();
+
+
+ /* set up the game */
+ Config c("MindBreaker", Config::User);
+ c.setGroup("Board");
+ game_over = FALSE;
+ if (c.readNumEntry("Answer0") < 0) {
+ for (i = 0; i < 4; i++) {
+ answer[i] = rand() % 6;
+ current_guess[i] = 6;
+ }
+ total_turns = 0;
+ total_games = 0;
+ } else {
+ int j;
+ c.setGroup("Score");
+ total_turns = c.readNumEntry("Turns");
+ total_games = c.readNumEntry("Games");
+ if(total_turns < 0)
+ total_turns = 0;
+ if(total_games < 0)
+ total_games = 0;
+
+
+ checkScores();
+ c.setGroup("Board");
+ for(i = 0; i < 4; i++)
+ answer[i] = c.readNumEntry(QString("Answer%1").arg(i));
+ /* read, and parse past guesses */
+ current_go = 0;
+ for(j=0; j < 9; j++) {
+ current_guess[0] = c.readNumEntry(QString("Go%1p0").arg(j));
+ if (current_guess[0] < 0)
+ break;
+ placeGuessPeg(0, current_guess[0]);
+ current_guess[1] = c.readNumEntry(QString("Go%1p1").arg(j));
+ placeGuessPeg(1, current_guess[1]);
+ current_guess[2] = c.readNumEntry(QString("Go%1p2").arg(j));
+ placeGuessPeg(2, current_guess[2]);
+ current_guess[3] = c.readNumEntry(QString("Go%1p3").arg(j));
+ placeGuessPeg(3, current_guess[3]);
+ checkGuess();
+ }
+ for(i = 0; i < 4; i++) {
+ current_guess[i] = c.readNumEntry(QString("CurrentGo%1").arg(i));
+ if (current_guess[i] != 6)
+ placeGuessPeg(i, current_guess[i]);
+ }
+ }
+
+ /* draw initial screen */
+ drawBackground();
+ canvas()->update();
+}
+
+MindBreakerBoard::~MindBreakerBoard()
+{
+ int i, j;
+ if (game_over) {
+ current_go = 0;
+ /* clear the answer, clear the guess */
+ for (i = 0; i < 4; i++) {
+ answer[i] = rand() % 6;
+ current_guess[i] = 6;
+ }
+ }
+
+ Config c("MindBreaker", Config::User);
+ c.setGroup("Board");
+ c.clearGroup();
+ /* write the board */
+ for (i = 0; i < current_go; i++) {
+ for(j = 0; j < 4; j++)
+ c.writeEntry(tr("Go%1p%2").arg(i).arg(j), past_guesses[4*i+j]);
+ }
+ for(j = 0; j < 4; j++)
+ c.writeEntry(tr("CurrentGo%1").arg(j), current_guess[j]);
+ for(j = 0; j < 4; j++)
+ c.writeEntry(tr("Answer%1").arg(j), answer[j]);
+
+ c.setGroup("Score");
+ /* write the score */
+
+ c.writeEntry("Turns", total_turns);
+ c.writeEntry("Games", total_games);
+}
+
+void MindBreakerBoard::getScore(int *a, int *b)
+{
+ *a = total_turns;
+ *b = total_games;
+ return;
+}
+
+void MindBreakerBoard::placeGuessPeg(int pos, int pegId)
+{
+ int x = first_peg_x_diff + (pos * peg_spacing);
+ int y = board_height - ((current_go + 1) * panel_height)
+ + first_peg_y_diff;
+
+ Peg *peg = new Peg(canvas(), pegId, current_go, pos);
+ peg->setPegPos(pos);
+ peg->setPlaced(TRUE);
+ peg->setX(x);
+ peg->setY(y);
+ peg->setZ(2);
+ peg->show();
+}
+
+void MindBreakerBoard::drawBackground()
+{
+ int i, j, x, y, x_gap, y_gap;
+ QPixmap background = QPixmap(canvas()->width(), canvas()->height());
+
+ QPainter painter(&background);
+
+ painter.fillRect(0, 0, canvas()->width(), canvas()->height(), QColor(0,0,0));
+ /* very first thing is to draw the bins, as everything else needs
+ * to be drawn over them */
+
+ QPen pen(QColor(85, 45, 27), 4);
+ painter.setPen(pen);
+ x_gap = canvas()->width() - (panel_width + (2 * bin_margin));
+ //x_gap += peg_size >> 1;
+ if (x_gap < 1)
+ x_gap = 1;
+
+ y_gap = board_height / 6;
+ y_gap -= (2 * bin_margin);
+ //y_gap += peg_size >> 1;
+ if (y_gap < 1)
+ y_gap = 1;
+ x = panel_width + bin_margin - (peg_size >> 1);
+ y = bin_margin - (peg_size >> 1) + 2;
+
+ for (i = 0; i < 6; i++) {
+ for (j = 0; j < 10; j++) {
+ int rx = x + (rand() % x_gap);
+ int ry = y + (rand() % y_gap);
+ painter.drawImage(rx,ry, Peg::imageForType(i));
+ }
+ y += board_height / 6;
+ }
+ /* now draw the surrounding boxes */
+ x_gap = canvas()->width() - panel_width;
+ if (x_gap < 1) x_gap = 1;
+ y_gap = board_height / 6;
+ x = panel_width;
+ y = 1;
+
+ for (i = 0; i < 6; i++) {
+ painter.drawRect(x, y, x_gap, y_gap);
+ y += y_gap;
+ }
+
+ x = 0;
+ y = 0;
+
+ painter.drawImage(x,y, titleImage);
+ y = title_height;
+ /* now nine gues panels */
+ for (i = 0; i < 9; i ++) {
+ painter.drawImage(x, y, panelImage);
+ y += panel_height;
+ }
+
+ painter.flush();
+ canvas()->setBackgroundPixmap(background);
+}
+
+void MindBreakerBoard::checkGuess()
+{
+ int i,j;
+ int num_white = 0;
+ int num_black = 0;
+ int copy_answer[4];
+ int copy_guess[4];
+
+ for(i = 0; i < 4; i++) {
+ copy_answer[i] = answer[i];
+ copy_guess[i] = current_guess[i];
+ if (current_guess[i] == 6)
+ return;
+ if (answer[i] == current_guess[i]) {
+ num_black++;
+ copy_answer[i] = 6;
+ copy_guess[i] = 7;
+ }
+ }
+
+ /* now sure that user has completed a 'guess' */
+ for (i = 0; i < 4; i++) {
+ if (copy_guess[i] == 7)
+ continue; // already marked for a black
+ for (j = 0; j < 4; j++) {
+ if(copy_guess[i] == copy_answer[j]) {
+ copy_answer[j] = 6;
+ num_white++;
+ break;
+ }
+ }
+ }
+
+ int x = answerpegx;
+ int y = (board_height - ((current_go + 1) * panel_height)) + answerpegy;
+
+ if (num_black == 4)
+ game_over = TRUE;
+
+ while(num_black > 0) {
+ Peg *p = new Peg(canvas(), 7);
+ p->setPlaced(TRUE);
+ p->setX(x);
+ p->setY(y);
+ p->setZ(1);
+ p->show();
+ num_black--;
+
+ if (x == answerpegx)
+ x = answerpegx + answerpeg_diff;
+ else {
+ x = answerpegx;
+ y += answerpeg_diff;
+ }
+ }
+ while(num_white > 0){
+ Peg *p = new Peg(canvas(), 6);
+ p->setPlaced(TRUE);
+ p->setX(x);
+ p->setY(y);
+ p->setZ(1);
+ p->show();
+ num_white--;
+
+ if (x == answerpegx)
+ x = answerpegx + answerpeg_diff;
+ else {
+ x = answerpegx;
+ y += answerpeg_diff;
+ }
+ }
+ /* move to next go */
+ for(i = 0; i < 4; i++) {
+ past_guesses[4*current_go+i] = current_guess[i];
+ current_guess[i] = 6;
+ }
+
+ current_go++;
+ if((current_go > 8) || game_over) {
+ total_games++;
+ if(!game_over)
+ total_turns += 10;
+ else
+ total_turns += current_go;
+
+ emit scoreChanged(total_turns, total_games);
+ Peg *p = new Peg(canvas(), 9);
+ game_over = TRUE;
+ p->setPlaced(TRUE);
+ p->setX(0);
+ p->setY(0);
+ p->setZ(0);
+ p->show();
+
+ for (i = 0; i < 4; i++) {
+ p = new Peg(canvas(), answer[i], -1);
+ p->setX(first_peg_x_diff + (i * peg_spacing));
+ p->setY(5);
+ p->setZ(3);
+ p->show();
+ }
+ } else {
+ current_highlight->setY(board_height - ((current_go + 1) * panel_height));
+ }
+ canvas()->update();
+}
+
+void MindBreakerBoard::clear()
+{
+ if(!game_over) {
+ total_games++;
+ total_turns += 10;
+ emit scoreChanged(total_turns, total_games);
+ }
+ int i;
+ /* reset the game board */
+ game_over = FALSE;
+ /* clear the answer, clear the guess */
+ for (i = 0; i < 4; i++) {
+ answer[i] = rand() % 6;
+ current_guess[i] = 6;
+ }
+ current_go = 0;
+
+ QCanvasItemList list = canvas()->allItems();
+ QCanvasItemList::Iterator it = list.begin();
+ for (; it != list.end(); ++it) {
+ if (*it == current_highlight)
+ continue;
+ if (*it)
+ delete *it;
+ }
+
+ current_highlight->setY(board_height - ((current_go + 1) * panel_height));
+ checkScores();
+ drawBackground();
+ canvas()->update();
+}
+
+void MindBreakerBoard::resetScore()
+{
+ /* are u sure */
+
+ if (QMessageBox::information(this, tr( "Reset Statistics" ),
+ tr( "Reset the win ratio?" ),
+ tr( "OK" ), tr( "Cancel" ) ) == 0) {
+ total_turns = 0;
+ total_games = 0;
+ Peg::eggLevel = 0;
+ drawBackground();
+ canvas()->update();
+ emit scoreChanged(total_turns, total_games);
+ }
+}
+
+/* EVENTS */
+
+void MindBreakerBoard::contentsMousePressEvent(QMouseEvent *e)
+{
+ copy_press = FALSE;
+ null_press = FALSE;
+ /* ok, first work out if it is one of the bins that
+ got clicked */
+ if (e->x() > panel_width) {
+ /* its a bin, but which bin */
+ if(e->y() > board_height)
+ return; // missed everything
+ int bin = (e->y() + 2) / (board_height / 6);
+
+ /* make new peg... set it moving */
+ moving_pos = e->pos();
+ moving = new Peg(canvas(), bin, current_go);
+ moving->setX(e->x() - (peg_size >> 1));
+ moving->setY(e->y() - (peg_size >> 1));
+ moving->setZ(5);
+ moving->show();
+ canvas()->update();
+ return;
+ }
+
+ QCanvasItemList l = canvas()->collisions(e->pos());
+ for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) {
+ if ( (*it)->rtti() == pegRTTI ) {
+ Peg *item = (Peg *)(*it);
+ if (!item->hit(e->pos()))
+ continue;
+ if (item->type() > 5) {
+ null_press = TRUE;
+ null_point = e->pos();
+ continue; /* not a color peg */
+ }
+ if (item->placed()) {
+ /* copy */
+ if(item->pegGo() == -1)
+ return;
+ if(item->pegGo() == current_go) {
+ copy_press = TRUE;
+ copy_peg = item;
+ }
+ moving = new Peg(canvas(),
+ item->type(), current_go);
+ moving->setX(e->x() - (peg_size >> 1));
+ moving->setY(e->y() - (peg_size >> 1));
+ moving->setZ(5);
+ moving->show();
+ moving_pos = QPoint(e->x(), e->y());
+ canvas()->update();
+ return;
+ }
+ moving = (Peg *)*it;
+ moving_pos = e->pos();
+ canvas()->update();
+ return;
+ }
+ }
+ null_press = TRUE;
+ null_point = e->pos();
+ moving = 0;
+}
+
+void MindBreakerBoard::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ if (moving ) {
+ moving->moveBy(e->pos().x() - moving_pos.x(),
+ e->pos().y() - moving_pos.y());
+ moving_pos = e->pos();
+ canvas()->update();
+ return;
+ }
+}
+
+void MindBreakerBoard::contentsMouseReleaseEvent(QMouseEvent* e)
+{
+ /* time to put down the peg */
+ if(moving) {
+ if(copy_press) {
+ /* check if collided with original. if so, delete both */
+ copy_press = FALSE;
+ QCanvasItemList l = canvas()->collisions(e->pos());
+ for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) {
+ if (*it == copy_peg)
+ copy_press = TRUE;
+ }
+ if (copy_press) {
+ current_guess[copy_peg->pegPos()] = 6;
+ delete copy_peg;
+ delete moving;
+ copy_press = FALSE;
+ moving = 0;
+ copy_peg = 0;
+ canvas()->update();
+ return;
+ }
+ }
+
+ /* first work out if in y */
+ if (e->y() > (board_height - (current_go * panel_height))) {
+ delete moving;
+ moving = 0;
+ canvas()->update();
+ return;
+ }
+ if (e->y() < (board_height - ((current_go + 1) * panel_height))) {
+ delete moving;
+ moving = 0;
+ canvas()->update();
+ return;
+ }
+ /* ok, a valid go, but which peg */
+ int x_bar = first_peg_x_diff - (peg_size >> 1);
+ x_bar += peg_spacing;
+ int pos = 0;
+ if (e->x() > x_bar)
+ pos = 1;
+ x_bar += peg_spacing;
+ if (e->x() > x_bar)
+ pos = 2;
+ x_bar += peg_spacing;
+ if (e->x() > x_bar)
+ pos = 3;
+ x_bar += peg_spacing;
+
+ if (e->x() > x_bar) {
+ /* invalid x */
+ delete moving;
+ moving = 0;
+ canvas()->update();
+ return;
+ }
+
+ int x = first_peg_x_diff + (pos * peg_spacing);
+ int y = board_height - ((current_go + 1) * panel_height)
+ + first_peg_y_diff;
+ moving->setPegPos(pos);
+ moving->setX(x);
+ moving->setY(y);
+ moving->setZ(2);
+
+ /* remove all other pegs from this position */
+ QCanvasItemList l = canvas()->collisions(QPoint(x,y));
+ for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) {
+ if ( (*it)->rtti() == pegRTTI ) {
+ Peg *item = (Peg *)(*it);
+ if ((item != moving) && (item != current_highlight))
+ delete item;
+ }
+ }
+ current_guess[pos] = ((Peg *)moving)->type();
+
+ ((Peg *)moving)->setPlaced(true);
+ canvas()->update();
+ return;
+ }
+ moving = 0;
+ null_point -= e->pos();
+ if(null_point.manhattanLength() < 6) {
+ if (game_over)
+ clear();
+ else
+ checkGuess();
+ }
+}
+
+void MindBreakerBoard::resizeEvent(QResizeEvent *e)
+{
+ QSize s = e->size();
+ int fw = style().defaultFrameWidth();
+ s.setWidth(s.width() - fw);
+ s.setHeight(s.height() - fw);
+
+ /* min size is 200 x 260 */
+ if (s.width() < board_width)
+ s.setWidth(board_width);
+
+ if (s.height() < board_height)
+ s.setHeight(board_height);
+
+ canvas()->resize(s.width() - fw, s.height() - fw);
+ drawBackground();
+}
+
+
+/* Easter egg function... beat the clock */
+void MindBreakerBoard::checkScores()
+{
+ double games = total_games;
+ double turns = total_turns;
+ double g = games / 10.0;
+ Peg::eggLevel = 0;
+
+ double break_even = 5.0;
+ if (g < 1.0)
+ return;
+ double avg = turns / games;
+ g--;
+ while (break_even >= 0.0) {
+ if (avg >= (break_even + g))
+ return;
+ // score a peg.
+ break_even -= 1.0;
+ Peg::eggLevel = int(5.0 - break_even);
+ }
+}
diff --git a/noncore/games/mindbreaker/mindbreaker.h b/noncore/games/mindbreaker/mindbreaker.h
new file mode 100644
index 0000000..fca649a
--- a/dev/null
+++ b/noncore/games/mindbreaker/mindbreaker.h
@@ -0,0 +1,122 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef MINDBREAKER_H
+#define MINDBREAKER_H
+
+#include <qwidget.h>
+#include <qmainwindow.h>
+#include <qimage.h>
+#include <qvector.h>
+#include <qcanvas.h>
+#include <qlabel.h>
+
+static const int panel_height = 26;
+static const int panel_width = 180;
+
+static const int title_height = 25;
+static const int title_width = 180;
+
+static const int bin_margin = 10;
+static const int peg_size = 20;
+static const int answerpeg_size = 13;
+
+static const int first_peg_x_diff = 21;
+static const int first_peg_y_diff = ((panel_height - peg_size) >> 1);
+static const int peg_spacing = 30;
+
+static const int answerpegx = 152;
+static const int answerpegy = 2;
+static const int answerpeg_diff = 9;
+
+static const int board_height = (title_height + (panel_height * 9));
+static const int board_width = (panel_width + (bin_margin * 2) + peg_size);
+
+class Peg;
+class QToolButton;
+
+class MindBreakerBoard : public QCanvasView // QWidget
+{
+ Q_OBJECT
+public:
+ MindBreakerBoard(QCanvas &c, QWidget *parent=0, const char *name=0, int wFlags=0 );
+ ~MindBreakerBoard();
+
+ void getScore(int *, int *);
+signals:
+ void scoreChanged(int, int);
+
+public slots:
+ void clear();
+ void resetScore();
+
+protected:
+ void contentsMousePressEvent(QMouseEvent *);
+ void contentsMouseMoveEvent(QMouseEvent *);
+ void contentsMouseReleaseEvent(QMouseEvent *);
+ void resizeEvent(QResizeEvent *);
+
+private:
+ void drawBackground();
+ void checkGuess();
+ void checkScores();
+ void placeGuessPeg(int pos, int pegId);
+
+ QImage panelImage;
+ QImage titleImage;
+
+ Peg *moving;
+ Peg *current_highlight;
+ QPoint moving_pos;
+
+ // the game stuff
+ int answer[4];
+ int current_guess[4];
+ int past_guesses[4*9];
+ int current_go;
+
+ int null_press;
+ QPoint null_point;
+ bool copy_press;
+ Peg *copy_peg;
+ bool game_over;
+
+ int total_turns;
+ int total_games;
+};
+
+class MindBreaker : public QMainWindow // QWidget
+{
+ Q_OBJECT
+public:
+ MindBreaker(QWidget *parent=0, const char *name=0, int wFlags=0 );
+
+public slots:
+ void setScore(int, int);
+
+private:
+ QCanvas canvas;
+ MindBreakerBoard *board;
+ QToolButton *score;
+
+};
+
+
+#endif
diff --git a/noncore/games/mindbreaker/mindbreaker.pro b/noncore/games/mindbreaker/mindbreaker.pro
new file mode 100644
index 0000000..12944d1
--- a/dev/null
+++ b/noncore/games/mindbreaker/mindbreaker.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = mindbreaker.h
+SOURCES = main.cpp \
+ mindbreaker.cpp
+TARGET = mindbreaker
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/mindbreaker.ts
diff --git a/noncore/games/mindbreaker/qpe-mindbreaker.control b/noncore/games/mindbreaker/qpe-mindbreaker.control
new file mode 100644
index 0000000..3bad93d
--- a/dev/null
+++ b/noncore/games/mindbreaker/qpe-mindbreaker.control
@@ -0,0 +1,9 @@
+Files: bin/mindbreaker apps/Games/mindbreaker.desktop pics/mindbreaker
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Game: crack the coloured code
+ A game for the Qtopia environment.