summaryrefslogtreecommitdiff
authorzecke <zecke>2004-02-17 15:55:24 (UTC)
committer zecke <zecke>2004-02-17 15:55:24 (UTC)
commit1207607ebbc59841718b79508fc222cb4eee9fde (patch) (side-by-side diff)
tree60c292a98621385006fbacca82dd11326765c0ab
parent2ec4085cc290a212c7bec8bdf7a2475f3ee6e069 (diff)
downloadopie-1207607ebbc59841718b79508fc222cb4eee9fde.zip
opie-1207607ebbc59841718b79508fc222cb4eee9fde.tar.gz
opie-1207607ebbc59841718b79508fc222cb4eee9fde.tar.bz2
Add the source of zsame
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/games/zsame/KSameWidget.cpp248
-rw-r--r--noncore/games/zsame/KSameWidget.h81
-rw-r--r--noncore/games/zsame/PortChanges14
-rw-r--r--noncore/games/zsame/StoneField.cpp390
-rw-r--r--noncore/games/zsame/StoneField.h113
-rw-r--r--noncore/games/zsame/StoneWidget.cpp350
-rw-r--r--noncore/games/zsame/StoneWidget.h115
-rw-r--r--noncore/games/zsame/ZSameWidget.cpp250
-rw-r--r--noncore/games/zsame/ZSameWidget.h56
-rw-r--r--noncore/games/zsame/config.in4
-rw-r--r--noncore/games/zsame/dropin/kapplication.h23
-rw-r--r--noncore/games/zsame/dropin/krandomsequence.cpp240
-rw-r--r--noncore/games/zsame/dropin/krandomsequence.h143
-rw-r--r--noncore/games/zsame/version.h6
-rw-r--r--noncore/games/zsame/zsame.pro17
15 files changed, 2050 insertions, 0 deletions
diff --git a/noncore/games/zsame/KSameWidget.cpp b/noncore/games/zsame/KSameWidget.cpp
new file mode 100644
index 0000000..0db2385
--- a/dev/null
+++ b/noncore/games/zsame/KSameWidget.cpp
@@ -0,0 +1,248 @@
+/* Yo Emacs, this is -*- C++ -*- */
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <stdio.h>
+
+#include <qwidget.h>
+#include <qpushbutton.h>
+#include <qpixmap.h>
+#include <qvbox.h>
+#include <qpopupmenu.h>
+
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kdialogbase.h>
+#include <kscoredialog.h>
+#include <kstatusbar.h>
+#include <knuminput.h>
+#include <klocale.h>
+#include <knotifyclient.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <kmenubar.h>
+#include <kconfig.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kdebug.h>
+#include <kkeydialog.h>
+
+#include "KSameWidget.h"
+#include "StoneWidget.h"
+#include "version.h"
+
+static int default_colors=3;
+
+#define Board KScoreDialog::Custom1
+
+KSameWidget::KSameWidget() : KMainWindow(0)
+{
+ setCaption("");
+ KStdAction::openNew(this, SLOT(m_new()), actionCollection(), "game_new");
+ restart = new KAction(i18n("&Restart This Board"), CTRL+Key_R, this,
+ SLOT(m_restart()), actionCollection(), "game_restart");
+ // KStdAction::open(this, SLOT(m_load()), actionCollection(), "game_load");
+ // KStdAction::save(this, SLOT(m_save()), actionCollection(), "game_save");
+ new KAction(i18n("S&how Highscore"), CTRL+Key_H, this,
+ SLOT(m_showhs()), actionCollection(), "game_highscores");
+ KStdAction::quit(this, SLOT(m_quit()), actionCollection(), "game_quit");
+ KStdAction::keyBindings( this, SLOT( slotConfigureKeys() ), actionCollection() );
+ undo = KStdAction::undo(this, SLOT(m_undo()),
+ actionCollection(), "edit_undo");
+
+ random = new KToggleAction(i18n("&Random Board"), 0, this,
+ SLOT(m_tglboard()), actionCollection(),
+ "random_board");
+
+ status=statusBar();
+ status->insertItem(i18n("Colors: XX"),1,1);
+ status->insertItem(i18n("Board: XXXXXX"),2,1);
+ status->insertItem(i18n("Marked: XXXXXX"),3,1);
+ status->insertItem(i18n("Score: XXXXXX"),4,1);
+
+ stone = new StoneWidget(this,15,10);
+
+ connect( stone, SIGNAL(s_gameover()), this, SLOT(gameover()));
+
+ connect( stone, SIGNAL(s_colors(int)), this, SLOT(setColors(int)));
+ connect( stone, SIGNAL(s_board(int)), this, SLOT(setBoard(int)));
+ connect( stone, SIGNAL(s_marked(int)), this, SLOT(setMarked(int)));
+ connect( stone, SIGNAL(s_score(int)), this, SLOT(setScore(int)));
+ connect( stone, SIGNAL(s_remove(int,int)), this, SLOT(stonesRemoved(int,int)));
+
+ connect(stone, SIGNAL(s_sizechanged()), this, SLOT(sizeChanged()));
+
+ sizeChanged();
+ setCentralWidget(stone);
+
+ createGUI();
+
+ random->setChecked(true);
+ setScore(0);
+
+ if (!kapp->isRestored()) newGame(kapp->random(),default_colors);
+ kdDebug() << "test" << endl;
+}
+
+KSameWidget::~KSameWidget() {
+}
+
+void KSameWidget::slotConfigureKeys()
+{
+ KKeyDialog::configure( actionCollection(), this );
+}
+
+void KSameWidget::readProperties(KConfig *conf) {
+ Q_ASSERT(conf);
+ stone->readProperties(conf);
+}
+
+void KSameWidget::saveProperties(KConfig *conf) {
+ Q_ASSERT(conf);
+ stone->saveProperties(conf);
+ conf->sync();
+}
+
+void KSameWidget::sizeChanged() {
+ stone->setFixedSize(stone->sizeHint());
+}
+
+void KSameWidget::newGame(unsigned int board,int colors) {
+ while (board>=1000000) board-=1000000;
+ // kdDebug() << "newgame board " << board << " colors " << colors << endl;
+ stone->newGame(board,colors);
+ setScore(0);
+}
+
+bool KSameWidget::confirmAbort() {
+ return stone->isGameover() ||
+ stone->isOriginalBoard() ||
+ (KMessageBox::questionYesNo(this, i18n("Do you want to resign?"),
+ i18n("New Game")) == KMessageBox::Yes);
+}
+
+void KSameWidget::m_new() {
+ if (random->isChecked()) {
+ if (confirmAbort())
+ newGame(kapp->random(),default_colors);
+ } else {
+ KDialogBase dlg(this, "boardchooser", true,
+ i18n("Select Board"),
+ KDialogBase::Ok | KDialogBase::Cancel,
+ KDialogBase::Ok);
+
+ QVBox *page = dlg.makeVBoxMainWidget();
+
+ KIntNumInput bno(0, page);
+ bno.setRange(0, 1000000, 1);
+ bno.setLabel(i18n("Select a board:"));
+ bno.setFocus();
+ bno.setFixedSize(bno.sizeHint());
+ bno.setValue(stone->board());
+
+ if (dlg.exec()) newGame(bno.value(),default_colors);
+ }
+}
+
+void KSameWidget::m_restart() {
+ if (confirmAbort())
+ newGame(stone->board(),default_colors);
+}
+
+void KSameWidget::m_load() {
+ kdDebug() << "menu load not supported" << endl;
+}
+
+void KSameWidget::m_save() {
+ kdDebug() << "menu save not supported" << endl;
+}
+
+void KSameWidget::m_undo() {
+ Q_ASSERT(stone);
+ stone->undo();
+}
+
+
+void KSameWidget::m_showhs() {
+ Q_ASSERT(stone);
+ stone->unmark();
+ KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score, this);
+ d.addField(Board, i18n("Board"), "Board");
+ d.exec();
+}
+
+void KSameWidget::m_quit() {
+ Q_ASSERT(stone);
+ stone->unmark();
+ kapp->quit();
+ delete this;
+}
+
+void KSameWidget::m_tglboard() {
+ kdDebug() << "toggled" << endl;
+}
+
+
+void KSameWidget::setColors(int colors) {
+ status->changeItem(i18n("%1 Colors").arg(colors),1);
+}
+
+void KSameWidget::setBoard(int board) {
+ status->changeItem(i18n("Board: %1").arg(board, 6), 2);
+}
+
+void KSameWidget::setMarked(int m) {
+ status->changeItem(i18n("Marked: %1").arg(m, 6),3);
+}
+
+void KSameWidget::stonesRemoved(int,int) {
+ KNotifyClient::event("stones removed",
+ i18n("%1 stones removed.").arg(stone->marked()));
+}
+
+void KSameWidget::setScore(int score) {
+ status->changeItem(i18n("Score: %1").arg(score, 6),4);
+ undo->setEnabled(stone->undoPossible());
+ restart->setEnabled(!stone->isOriginalBoard());
+}
+
+void KSameWidget::gameover() {
+ kdDebug() << "GameOver" << endl;
+ if (stone->hasBonus()) {
+ KNotifyClient::event("game won",
+ i18n("You even removed the last stone, great job! "
+ "This gave you a score of %1 in total.").arg(stone->score()));
+ } else {
+ KNotifyClient::event("game over",
+ i18n("There are no more removeable stones. "
+ "You got a score of %1 in total.").arg(stone->score()));
+ }
+ stone->unmark();
+ KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score, this);
+ d.addField(Board, i18n("Board"), "Board");
+
+ KScoreDialog::FieldInfo scoreInfo;
+ scoreInfo[Board].setNum(stone->board());
+
+ if (d.addScore(stone->score(), scoreInfo))
+ d.exec();
+}
+
+#include "KSameWidget.moc"
diff --git a/noncore/games/zsame/KSameWidget.h b/noncore/games/zsame/KSameWidget.h
new file mode 100644
index 0000000..7887d46
--- a/dev/null
+++ b/noncore/games/zsame/KSameWidget.h
@@ -0,0 +1,81 @@
+/* Yo Emacs, this is -*- C++ -*- */
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _KSAMEWIDGET
+#define _KSAMEWIDGET
+
+#include "StoneWidget.h"
+#include <kmainwindow.h>
+
+class KToggleAction;
+
+class KSameWidget: public KMainWindow {
+ Q_OBJECT
+public:
+ KSameWidget();
+ ~KSameWidget();
+
+private:
+ StoneWidget *stone;
+ KStatusBar *status;
+ KToggleAction *random;
+ KAction *restart;
+ KAction *undo;
+
+ int multispin_item;
+
+
+protected:
+ void newGame(unsigned int board,int colors);
+
+ virtual void saveProperties(KConfig *conf);
+ virtual void readProperties(KConfig *conf);
+
+ bool confirmAbort();
+
+ public slots:
+ void sizeChanged();
+
+ /* File Menu */
+ void m_new();
+ void m_restart();
+ void m_load();
+ void m_save();
+ void m_showhs();
+ void m_quit();
+ void m_undo();
+
+ /* Options Menu */
+ void m_tglboard();
+
+ void gameover();
+ void setColors(int colors);
+ void setBoard(int board);
+ void setScore(int score);
+ void setMarked(int m);
+ void stonesRemoved(int,int);
+ void slotConfigureKeys();
+
+};
+
+
+
+#endif
diff --git a/noncore/games/zsame/PortChanges b/noncore/games/zsame/PortChanges
new file mode 100644
index 0000000..875ee34
--- a/dev/null
+++ b/noncore/games/zsame/PortChanges
@@ -0,0 +1,14 @@
+-Scale the Image to be 50% of the original one
+-Add pics/zsame
+-Add .pro file
+-Add .applnk file
+-UnComment kdDebug
+-New MainWidget
+-Remove HighScore and KNotify Events
+-Adjust to Stylus Interface
+
+--TODO:
+ -Recognize on the fly changes ( monitor Desktop Widget )
+
+
+ zecke@handhelds.org \ No newline at end of file
diff --git a/noncore/games/zsame/StoneField.cpp b/noncore/games/zsame/StoneField.cpp
new file mode 100644
index 0000000..49d8eca
--- a/dev/null
+++ b/noncore/games/zsame/StoneField.cpp
@@ -0,0 +1,390 @@
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "StoneField.h"
+#include <assert.h>
+
+StoneFieldState::StoneFieldState(const StoneField &stonefield)
+{
+ field=new unsigned char[stonefield.maxstone];
+ for (int i=0;i<stonefield.maxstone;i++)
+ field[i]=stonefield.field[i].color;
+
+ colors=stonefield.colors;
+ board=stonefield.board;
+ score=stonefield.score;
+ gameover=stonefield.gameover;
+}
+
+StoneFieldState::~StoneFieldState() {
+ delete[] field;
+}
+
+void
+StoneFieldState::restore(StoneField &stonefield) const {
+ for (int i=0;i<stonefield.maxstone;i++) {
+ stonefield.field[i].color=field[i];
+ stonefield.field[i].changed=true;
+ stonefield.field[i].marked=false;
+ }
+
+ stonefield.colors=colors;
+ stonefield.board=board;
+ stonefield.score=score;
+ stonefield.marked=0;
+ stonefield.gameover=gameover;
+}
+
+StoneField::StoneField(int width, int height,
+ int colors, unsigned int board,
+ bool undoenabled)
+{
+// Q_ASSERT(width>0);
+// Q_ASSERT(height>0);
+
+ if (undoenabled) undolist=new QList<StoneFieldState>;
+ else undolist=0;
+
+ sizex=width;
+ sizey=height;
+ maxstone=sizex*sizey;
+ field=new Stone[maxstone];
+ newGame(board,colors);
+ m_gotBonus= false;
+}
+
+StoneField::~StoneField() {
+ delete[] field;
+ delete undolist;
+// kdDebug() << "~StoneField\n" << endl;
+}
+
+int
+StoneField::width() const {
+ return sizex;
+}
+
+int
+StoneField::height() const {
+ return sizey;
+}
+
+void
+StoneField::newGame(unsigned int board,int colors) {
+// kdDebug() << "StoneField::newgame board "
+// << board << " colors " << colors << endl;
+ if (colors<1) colors=3;
+ if (colors>7) colors=7;
+ this->colors=colors;
+ this->board=board;
+ reset();
+}
+
+void
+StoneField::reset() {
+ random.setSeed(board);
+
+ Stone *stone=field;
+ for (int i=0;i<maxstone;i++,stone++) {
+ stone->color=1+random.getLong(colors);
+ stone->marked=false;
+ stone->changed=true;
+ }
+
+ gameover=-1;
+ score=0;
+ marked=0;
+
+ if (undolist) {
+ undolist->setAutoDelete(true);
+ undolist->clear();
+ }
+
+
+ int c[7];
+ int j;
+ for (j=0;j<7;j++) c[j]=0;
+
+ for (j=0,stone=field;j<maxstone;j++,stone++) {
+ c[stone->color]++;
+ }
+// kdDebug() << "red " << c[1] << endl;
+// kdDebug() << "blue " << c[2] << endl;
+// kdDebug() << "yellow " << c[3] << endl;
+// kdDebug() << "green " << c[4] << endl;
+
+}
+
+int
+StoneField::map(int x,int y) {
+ assert (!(x<0||y<0||x>=sizex||y>=sizey));
+ return x+y*sizex;
+}
+
+int
+StoneField::mark(int x,int y,bool force) {
+ int index=map(x,y);
+
+ if (index<0) {
+ unmark();
+ return 0;
+ }
+
+ if (field[index].marked) return -1;
+ unmark();
+
+ mark(index,field[index].color);
+
+ if (marked==1&&!force) {
+ field[index].marked=false;
+ marked=0;
+ }
+ return marked;
+}
+
+void
+StoneField::mark(int index,unsigned char color) {
+ if ( index<0 || index>=maxstone ) return;
+
+ Stone &stone=field[index];
+
+ if (stone.marked) return;
+
+ if (!stone.color || stone.color!=color) return;
+
+ stone.changed=true;
+ stone.marked=true;
+ marked++;
+
+ // mark left
+ if ((index%sizex)!=0) mark(index-1,color);
+ // mark right
+ if (((index+1)%sizex)!=0) mark(index+1,color);
+ // mark upward
+ if (index>=sizex) mark(index-sizex,color);
+ // mark downward
+ if (index<(sizex-1)*sizey) mark(index+sizex,color);
+}
+
+void
+StoneField::unmark() {
+ if (!marked) return;
+
+ Stone *stone=field;
+ for (int i=0;i<maxstone;i++,stone++) {
+ stone->marked=false;
+ stone->changed=true;
+ }
+ marked=0;
+}
+
+int
+StoneField::remove(int x,int y,bool force) {
+ int index=map(x,y);
+
+ if (index<0) return 0;
+
+ if (!field[index].marked) {
+ mark(x,y,force);
+ }
+
+ if (!marked) return 0;
+
+ // remove a single stone??
+ if (marked==1&&!force) return 0;
+
+ // add current field to undolist
+ if (undolist)
+ undolist->append(new StoneFieldState(*this));
+
+ // increase score
+ if (marked>2)
+ score+=(marked-2)*(marked-2);
+
+ // remove marked stones
+ Stone *stone=field;
+ for (int i=0;i<maxstone;i++,stone++) {
+ if (stone->marked) {
+ stone->color=0;
+ stone->changed=true;
+ stone->marked=false;
+ }
+ }
+ int removed=marked;
+ marked=0;
+
+ for (int col=0;col<sizex;col++) {
+ int i1=col+maxstone-sizex;
+ while ( i1>=0 && field[i1].color ) i1-=sizex;
+ int i2=i1;
+ while (i2>=0) {
+ while ( i2>=0 && !field[i2].color ) i2-=sizex;
+ while ( i2>=0 && field[i2].color ) {
+ field[i1].color=field[i2].color;
+ field[i1].changed=true;
+ field[i2].color=0;
+ field[i2].changed=true;
+ i1-=sizex;
+ i2-=sizex;
+ }
+ }
+ }
+
+ // find the last column that has something
+ int lastcol = sizex;
+ while (lastcol > 0 && !field[map(lastcol-1, sizey-1)].color) {
+ lastcol--;
+ }
+
+ for (int col=0;col<lastcol-1;) {
+ bool empty = true;
+ for (int row = 0; row < sizey; row++)
+ if (field[map(col, row)].color) {
+ empty = false;
+ break;
+ }
+ if (!empty) {
+ col++;
+ continue;
+ }
+ int nextfullcol = col + 1;
+ while (nextfullcol < sizex &&
+ !field[map(nextfullcol, sizey - 1)].color)
+ nextfullcol++;
+
+ if (nextfullcol > sizex - 1)
+ break; // we're ready
+
+ for (int row=0; row < sizey; row++) {
+ int source = map(nextfullcol, row);
+ int dest = map(col, row);
+ field[dest].color=field[source].color;
+ field[dest].changed=true;
+ field[source].color=0;
+ field[source].changed=true;
+ }
+ }
+
+ // add a bonus, if field is empty
+ if (!field[map(0, sizey-1)].color) {
+ score+=1000;
+ m_gotBonus= true;
+ }
+
+ // gameover is undefined
+ gameover=-1;
+ return removed;
+}
+
+bool StoneField::undoPossible() const {
+ return !(!undolist||undolist->isEmpty());
+}
+
+int
+StoneField::undo(int count) {
+ if (!undoPossible())
+ return 0;
+ if (count <= 0)
+ return 0;
+ int undocount=1;
+ StoneFieldState *state=0;
+ undolist->setAutoDelete(true);
+ while (--count>0) {
+ if (undolist->count()==1) break;
+ undolist->removeLast();
+ undocount++;
+ }
+ state=undolist->getLast();
+// Q_ASSERT(state);
+ state->restore(*this);
+ undolist->removeLast();
+ return undocount;
+}
+
+bool
+StoneField::isGameover() const {
+ register int i=maxstone-1;;
+ register unsigned char color;
+
+ if (gameover>=0) return (bool)gameover;
+ // kdDebug() << "-->gameover" << endl;
+
+ while (i>=0) {
+ // kdDebug() << i << " " << field[i].color << endl;
+ // ignore empty fields
+ while ( i>=0 && field[i].color==0 ) i--;
+ // Wenn Stein gefunden,
+ // dann die Nachbarn auf gleiche Farbe pruefen.
+ while ( i>=0 && (color=field[i].color) ) {
+ // check left
+ if ( (i%sizex)!=0 && field[i-1].color==color)
+ goto check_gameover;
+ // check upward
+ if ( i>=sizex && field[i-sizex].color==color)
+ goto check_gameover;
+ i--;
+ }
+ }
+ check_gameover:
+ gameover=(i<0);
+ // kdDebug() << "<--gameover" << endl;
+ return (bool)gameover;
+}
+
+bool StoneField::gotBonus() const {
+ return m_gotBonus;
+}
+
+int
+StoneField::getBoard() const {
+ return board;
+}
+
+int
+StoneField::getScore() const {
+ return score;
+}
+
+int
+StoneField::getColors() const {
+ return colors;
+}
+
+int
+StoneField::getMarked() const {
+ return marked;
+}
+
+int
+StoneField::getFieldSize() const {
+ return maxstone;
+}
+
+struct Stone *
+StoneField::getField() const {
+ return field;
+}
+
+
+
+
+
+
+
diff --git a/noncore/games/zsame/StoneField.h b/noncore/games/zsame/StoneField.h
new file mode 100644
index 0000000..80be73a
--- a/dev/null
+++ b/noncore/games/zsame/StoneField.h
@@ -0,0 +1,113 @@
+/* Yo Emacs, this is -*- C++ -*- */
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _STONEFIELD
+#define _STONEFIELD
+
+#include <krandomsequence.h>
+#include <qlist.h>
+
+struct Stone {
+ unsigned char color;
+ bool changed;
+ bool marked;
+};
+
+class StoneField;
+class StoneWidget;
+
+class StoneFieldState {
+private:
+ unsigned char *field;
+
+ int colors;
+ unsigned int board;
+ unsigned int score;
+ int gameover;
+
+public:
+ StoneFieldState(const StoneField &stonefield);
+ ~StoneFieldState();
+ void restore(StoneField &stonefield) const;
+};
+
+
+class StoneField {
+ friend class StoneFieldState;
+ friend class StoneWidget;
+private:
+
+ int sizex;
+ int sizey;
+ int maxstone;
+
+ struct Stone *field;
+
+ int colors;
+ unsigned int board;
+ unsigned int score;
+ mutable int gameover;
+ bool m_gotBonus;
+ int marked;
+
+ KRandomSequence random;
+ QList<StoneFieldState> *undolist;
+public:
+ StoneField(int width=15,int height=10,
+ int colors=3,unsigned int board=0,
+ bool undoenabled=true);
+ ~StoneField();
+
+ int width() const;
+ int height() const;
+
+ void newGame(unsigned int board,int colors);
+
+ void reset();
+
+
+ int mark(int x,int y,bool force=false);
+ void unmark();
+
+ int remove(int x,int y,bool force=false);
+
+ int undo(int count=1);
+
+ bool isGameover() const;
+ bool gotBonus() const;
+ bool undoPossible() const;
+ int getBoard() const;
+ int getScore() const;
+ int getColors() const;
+ int getMarked() const;
+
+protected:
+ int getFieldSize() const;
+ struct Stone *getField() const;
+
+ int map(int x,int y);
+ void mark(int index,unsigned char color);
+};
+
+#endif
+
+
+
diff --git a/noncore/games/zsame/StoneWidget.cpp b/noncore/games/zsame/StoneWidget.cpp
new file mode 100644
index 0000000..49fa1a4
--- a/dev/null
+++ b/noncore/games/zsame/StoneWidget.cpp
@@ -0,0 +1,350 @@
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qimage.h>
+#include <qcursor.h>
+
+
+#include <qpe/resource.h>
+
+#include <time.h>
+#include <assert.h>
+
+#include "StoneWidget.h"
+
+
+
+struct StoneSlice {
+ QPixmap stone;
+};
+
+
+StoneWidget::StoneWidget( QWidget *parent, int x, int y )
+ : QWidget(parent,"StoneWidget"), stonefield(x,y)
+{
+// setBackgroundPixmap(QPixmap(locate("wallpaper", "Time-For-Lunch-2.jpg")));
+// QPixmap stonemap(locate("appdata", "stones.png"));
+
+ QPixmap stonemap = Resource::loadPixmap("zsame/stones" );
+ assert(!stonemap.isNull());
+
+ slice=0;
+ maxslices=30;
+ maxcolors=4;
+
+ sizex=x;
+ sizey=y;
+
+ stone_width=stonemap.width()/(maxslices+1);
+ stone_height=stonemap.height()/maxcolors;
+
+ map = new StoneSlice*[maxcolors];
+ QBitmap mask;
+ for (int c = 0; c < maxcolors; c++) {
+ map[c] = new StoneSlice[maxslices];
+
+ for (int s = 0; s < maxslices; s++) {
+ map[c][s].stone.resize(stone_width, stone_height);
+ assert(!map[c][s].stone.isNull());
+ bitBlt(&map[c][s].stone, 0, 0,
+ &stonemap, stone_width * s,
+ c*stone_height,
+ stone_width,stone_height,CopyROP,false);
+ QImage im = map[c][s].stone.convertToImage();
+ mask = im.createHeuristicMask();
+ map[c][s].stone.setMask(mask);
+ }
+ }
+
+ field_height=stone_height*sizey;
+ field_width=stone_width*sizex;
+
+ setMouseTracking(true);
+
+ // QColor c(115,115,115);
+ // setBackgroundColor(c);
+
+ // emit s_sizechanged();
+ startTimer( 100 );
+ history.setAutoDelete(true);
+}
+
+StoneWidget::~StoneWidget() {
+ for (int c = 0; c < maxcolors; c++) {
+ delete [] map[c];
+ }
+ delete [] map;
+
+ setMouseTracking(false);
+ killTimers();
+}
+
+unsigned int
+StoneWidget::board() {
+ return stonefield.getBoard();
+}
+
+int
+StoneWidget::score() {
+ return stonefield.getScore();
+}
+
+int
+StoneWidget::marked() {
+ return stonefield.getMarked();
+}
+
+QSize
+StoneWidget::size() {
+ return QSize(sizex,sizey);
+}
+
+int
+StoneWidget::colors() {
+ return stonefield.getColors();
+}
+
+QSize
+StoneWidget::sizeHint () const {
+ return QSize(field_width,field_height);
+}
+
+void
+StoneWidget::newGame(unsigned int board,int colors) {
+ stonefield.newGame(board,colors);
+ history.clear();
+ modified= false;
+ emit s_newgame();
+ emit s_colors(stonefield.getColors());
+ emit s_board(stonefield.getBoard());
+}
+
+void
+StoneWidget::reset() {
+ stonefield.reset();
+ history.clear();
+ emit s_newgame();
+}
+
+void
+StoneWidget::unmark() {
+ stonefield.unmark();
+ emit s_marked(0);
+}
+
+bool StoneWidget::undoPossible() const {
+ if (stonefield.isGameover()) return false;
+ return stonefield.undoPossible();
+}
+
+int
+StoneWidget::undo(int count) {
+ if (stonefield.isGameover()) return 0;
+
+ int ret_val=stonefield.undo(count);
+
+ QPoint p=mapFromGlobal(cursor().pos());
+ int x=p.x();
+ int y=p.y();
+ if (x<0||y<0||x>=field_width||y>=field_height) {
+ emit s_score(stonefield.getMarked());
+ return ret_val;
+ }
+
+ int marked=stonefield.mark(x/stone_width,y/stone_height);
+ emit s_marked(marked);
+ slice=0;
+ emit s_score(stonefield.getScore());
+ modified= (stonefield.getScore()>0);
+ return ret_val;
+}
+
+bool StoneWidget::isGameover() {
+ return stonefield.isGameover();
+}
+
+bool StoneWidget::hasBonus() {
+ return stonefield.gotBonus(); // don't ask me why the names differ... ;-| [hlm]
+}
+
+bool StoneWidget::isOriginalBoard() {
+ return !modified;
+}
+
+void StoneWidget::readProperties(Config *) {
+/* Q_ASSERT(conf);
+
+ history.clear();
+
+ if (!conf->hasKey("Board")||
+ !conf->hasKey("Colors")||
+ !conf->hasKey("Stones")) {
+ return;
+ }
+ newGame(conf->readNumEntry("Board"),conf->readNumEntry("Colors"));
+
+ QStrList list;
+ conf->readListEntry("Stones",list);
+
+ for (const char *item=list.first();item;item=list.next()) {
+ int x=-1,y=-1;
+ if (sscanf(item,"%02X%02X",&x,&y)!=2) break;
+ history.append(new QPoint(x,y));
+ stonefield.remove(x,y);
+ }
+*/
+}
+
+
+void
+StoneWidget::saveProperties(Config *) {
+/*
+ Q_ASSERT(conf);
+
+ QStrList list(true);
+ QString tmp;
+
+ for (QPoint *item=history.first();item;item=history.next()) {
+ tmp.sprintf("%02X%02X",item->x(),item->y());
+ list.append(tmp.ascii());
+ }
+
+ conf->writeEntry("Stones",list);
+ conf->writeEntry("Board",stonefield.getBoard());
+ conf->writeEntry("Colors",stonefield.getColors());
+*/
+}
+
+void
+StoneWidget::timerEvent( QTimerEvent * ) {
+ QPoint p=mapFromGlobal(cursor().pos());
+ int x=p.x();
+ int y=p.y();
+ if (x<0||y<0||x>=field_width||y>=field_height)
+ stonefield.unmark();
+ slice=(slice+1)%maxslices;
+ paintEvent(0);
+}
+
+void
+StoneWidget::paintEvent( QPaintEvent *e ) {
+
+ Stone *stone=stonefield.getField();
+
+ for (int y=0;y<sizey;y++) {
+ int cy = y * stone_height;
+
+ for (int x=0;x<sizex;x++) {
+ int cx = stone_width * x;
+
+ bool redraw=stone->marked||stone->changed;
+
+ if (!redraw&&e) {
+ QRect r(cx,cy,stone_width,stone_height);
+ redraw=r.intersects(e->rect());
+ }
+ if (redraw) {
+ stone->changed=false;
+ if (stone->color) {
+
+ int tslice = stone->marked?slice:0;
+ bitBlt(this,cx,cy,
+ &map[stone->color-1][tslice].stone,
+ 0, 0,
+ stone_width,stone_height,CopyROP,FALSE);
+
+ } else {
+ erase(cx, cy, stone_width, stone_height);
+ }
+ }
+ stone++; // naechster Stein.
+ }
+ }
+}
+
+void
+StoneWidget::mousePressEvent ( QMouseEvent *e) {
+
+ if (stonefield.isGameover()) return;
+
+ int x=e->pos().x();
+ int y=e->pos().y();
+ if (x<0||y<0||x>=field_width||y>=field_height) return;
+
+ int sx=x/stone_width;
+ int sy=y/stone_height;
+
+ int mar =stonefield.mark(sx, sy);
+
+ if ( mar != -1 ) {
+ myMoveEvent(e);
+ return;
+ }
+
+
+ if (stonefield.remove(sx, sy)) {
+ history.append(new QPoint(sx, sy));
+
+ emit s_remove(sx, sy);
+
+ stonefield.mark(sx,sy);
+ emit s_marked(stonefield.getMarked());
+ modified= true;
+
+ emit s_score(stonefield.getScore());
+ if (stonefield.isGameover()) emit s_gameover();
+ }
+}
+
+void
+StoneWidget::myMoveEvent ( QMouseEvent *e)
+{
+ return;
+
+ if (stonefield.isGameover()) {
+ stonefield.unmark();
+ emit s_marked(0);
+ return;
+ }
+
+ int x=e->pos().x();
+ int y=e->pos().y();
+ if (x<0||y<0||x>=field_width||y>=field_height) return;
+
+ int marked=stonefield.mark(x/stone_width,y/stone_height);
+ if (marked>=0) {
+ emit s_marked(marked);
+ slice=0;
+ }
+}
+
+
+
+
+
+
+
+
diff --git a/noncore/games/zsame/StoneWidget.h b/noncore/games/zsame/StoneWidget.h
new file mode 100644
index 0000000..9cd7e10
--- a/dev/null
+++ b/noncore/games/zsame/StoneWidget.h
@@ -0,0 +1,115 @@
+/* Yo Emacs, this is -*- C++ -*- */
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _STONEWIDGET
+#define _STONEWIDGET
+
+#include <qpixmap.h>
+#include <qwidget.h>
+
+#include <qpe/config.h>
+
+#include "StoneField.h"
+
+struct StoneSlice;
+
+class StoneWidget : public QWidget {
+ Q_OBJECT
+
+ int modified;
+ // int marked; // # of marked stones
+
+ int stones_x, stones_y;
+ int sizex, sizey;
+ int field_width, field_height;
+
+ QList<QPoint> history;
+ StoneField stonefield;
+
+ // picture number of stonemovie
+ int slice;
+
+ StoneSlice **map;
+
+public:
+ StoneWidget( QWidget *parent=0, int x=10,int y=10);
+ ~StoneWidget();
+
+ unsigned int board();
+ int score();
+ int marked();
+ QSize size();
+ int colors();
+ virtual QSize sizeHint() const;
+
+ bool undoPossible() const;
+
+ void newGame(unsigned int board, int colors);
+ void reset();
+ void unmark();
+ int undo(int count=1);
+
+ // test for game end
+ bool isGameover();
+ // if isGameover(): finished with bonus?
+ bool hasBonus();
+ // test for unchanged start position
+ bool isOriginalBoard();
+
+ virtual void readProperties(Config *conf);
+ virtual void saveProperties(Config *conf);
+
+protected:
+
+ void timerEvent( QTimerEvent *e );
+ void paintEvent( QPaintEvent *e );
+ void mousePressEvent ( QMouseEvent *e);
+ void myMoveEvent ( QMouseEvent *e);
+
+ // properties of the stone picture
+ int stone_width,stone_height; // size of one stone
+ int maxcolors; // number of different stones (Y direction)
+ int maxslices; // number of pictures per movie (X direction)
+
+signals:
+ // A new game begins
+ void s_newgame();
+
+ void s_colors(int colors);
+ void s_board(int board);
+ void s_score(int score);
+ void s_marked(int m);
+
+ void s_gameover();
+
+ // The stone (x,y) was clicked(removed),
+ // all neighbor stones disappear without further signals
+ void s_remove(int x,int y);
+
+ void s_sizechanged();
+};
+
+#endif
+
+
+
+
+
diff --git a/noncore/games/zsame/ZSameWidget.cpp b/noncore/games/zsame/ZSameWidget.cpp
new file mode 100644
index 0000000..5001b55
--- a/dev/null
+++ b/noncore/games/zsame/ZSameWidget.cpp
@@ -0,0 +1,250 @@
+/* Yo Emacs, this is -*- C++ -*- */
+/*
+ * ksame 0.4 - simple Game
+ * Copyright (C) 1997,1998 Marcus Kreutzberger
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <stdio.h>
+
+#include <qwidget.h>
+#include <qpushbutton.h>
+#include <qpixmap.h>
+#include <qvbox.h>
+#include <qpopupmenu.h>
+#include <qtoolbar.h>
+#include <qmenubar.h>
+
+#include <qapplication.h>
+#include <qaction.h>
+#include <qmessagebox.h>
+
+#include <qpe/resource.h>
+#include <opie/oapplicationfactory.h>
+#include <kapplication.h>
+
+
+#include "ZSameWidget.h"
+#include "StoneWidget.h"
+#include "version.h"
+
+static int default_colors=3;
+
+#define i18n tr
+
+
+OPIE_EXPORT_APP( OApplicationFactory<ZSameWidget> )
+
+
+
+ZSameWidget::ZSameWidget( QWidget* parent, const char* name, WFlags fl )
+ : QMainWindow( parent, name, fl )
+{
+ setCaption(tr("ZSame"));
+
+ setToolBarsMovable( false );
+ QToolBar* con = new QToolBar( this );
+ con->setHorizontalStretchable( true );
+ QMenuBar* mb = new QMenuBar( con );
+ QToolBar* tb = new QToolBar( this );
+
+ QPopupMenu* fileMenu = new QPopupMenu( this );
+
+ QAction* a = new QAction(tr("New Game"), Resource::loadIconSet("new") ,
+ QString::null, 0, this, "new_icon");
+ a->addTo( fileMenu );
+ a->addTo( tb );
+ connect(a, SIGNAL(activated()), this, SLOT(m_new()));
+
+ a = new QAction(tr("Restart This Board"), Resource::loadIconSet("redo"),
+ QString::null, 0, this, "restart_board" );
+ a->addTo( fileMenu );
+ connect( a, SIGNAL(activated()), this, SLOT(m_restart()));
+ restart = a;
+
+ a = new QAction( tr("Undo"), Resource::loadIconSet("undo"),
+ QString::null, 0, this, "undo_action" );
+ a->addTo( fileMenu );
+ a->addTo( tb );
+ connect( a, SIGNAL(activated()), this, SLOT(m_undo()));
+
+ a = new QAction(tr("Quit"), Resource::loadIconSet("quit_icon"),
+ QString::null, 0, this, "quit_action");
+ a->addTo( fileMenu );
+ a->addTo( tb );
+ connect(a, SIGNAL(activated()), this, SLOT(m_quit()));
+
+ mb->insertItem(tr("Game" ), fileMenu );
+
+ int foo[2];
+ desktop_widget(foo);
+ stone = new StoneWidget(this,foo[0],foo[1]);
+
+ connect( stone, SIGNAL(s_gameover()), this, SLOT(gameover()));
+
+ connect( stone, SIGNAL(s_colors(int)), this, SLOT(setColors(int)));
+ connect( stone, SIGNAL(s_board(int)), this, SLOT(setBoard(int)));
+ connect( stone, SIGNAL(s_marked(int)), this, SLOT(setMarked(int)));
+ connect( stone, SIGNAL(s_score(int)), this, SLOT(setScore(int)));
+ connect( stone, SIGNAL(s_remove(int,int)), this, SLOT(stonesRemoved(int,int)));
+
+ connect(stone, SIGNAL(s_sizechanged()), this, SLOT(sizeChanged()));
+
+ sizeChanged();
+ setCentralWidget(stone);
+
+
+ setScore(0);
+}
+
+ZSameWidget::~ZSameWidget() {
+
+}
+
+void ZSameWidget::readProperties(Config *conf) {
+/*
+ Q_ASSERT(conf);
+ stone->readProperties(conf);
+*/
+}
+
+void ZSameWidget::saveProperties(Config *conf) {
+/*
+ Q_ASSERT(conf);
+ stone->saveProperties(conf);
+ conf->sync();
+*/
+}
+
+void ZSameWidget::sizeChanged() {
+// stone->setFixedSize(stone->sizeHint());
+}
+
+void ZSameWidget::newGame(unsigned int board,int colors) {
+ while (board>=1000000) board-=1000000;
+ // kdDebug() << "newgame board " << board << " colors " << colors << endl;
+ stone->newGame(board,colors);
+ setScore(0);
+}
+
+bool ZSameWidget::confirmAbort() {
+ return stone->isGameover() ||
+ stone->isOriginalBoard() ||
+ (QMessageBox::warning(this, i18n("Resign"), i18n("<qt>Do you want to resign?</qt>"),
+ QMessageBox::Yes,
+ QMessageBox::No|QMessageBox::Default|QMessageBox::Escape, 0) == QMessageBox::Yes );
+}
+
+void ZSameWidget::m_new() {
+ if (confirmAbort())
+ newGame(_random(),default_colors);
+
+}
+
+void ZSameWidget::m_restart() {
+ if (confirmAbort())
+ newGame(stone->board(),default_colors);
+}
+
+void ZSameWidget::m_load() {
+// kdDebug() << "menu load not supported" << endl;
+}
+
+void ZSameWidget::m_save() {
+// kdDebug() << "menu save not supported" << endl;
+}
+
+void ZSameWidget::m_undo() {
+// Q_ASSERT(stone);
+ stone->undo();
+}
+
+
+void ZSameWidget::m_showhs() {
+/* Q_ASSERT(stone);
+ stone->unmark();
+ KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score, this);
+ d.addField(Board, i18n("Board"), "Board");
+ d.exec();
+*/
+}
+
+void ZSameWidget::m_quit() {
+// Q_ASSERT(stone);
+ stone->unmark();
+ qApp->quit();
+// delete this;
+}
+
+void ZSameWidget::m_tglboard() {
+// kdDebug() << "toggled" << endl;
+}
+
+
+void ZSameWidget::setColors(int colors) {
+// status->changeItem(i18n("%1 Colors").arg(colors),1);
+}
+
+void ZSameWidget::setBoard(int board) {
+// status->changeItem(i18n("Board: %1").arg(board, 6), 2);
+}
+
+void ZSameWidget::setMarked(int m) {
+// status->changeItem(i18n("Marked: %1").arg(m, 6),3);
+}
+
+void ZSameWidget::stonesRemoved(int,int) {
+// KNotifyClient::event("stones removed",
+// i18n("%1 stones removed.").arg(stone->marked()));
+}
+
+void ZSameWidget::setScore(int score) {
+// status->changeItem(i18n("Score: %1").arg(score, 6),4);
+// undo->setEnabled(stone->undoPossible());
+// restart->setEnabled(!stone->isOriginalBoard());
+}
+
+void ZSameWidget::gameover() {
+// kdDebug() << "GameOver" << endl;
+ if (stone->hasBonus()) {
+ QMessageBox::information(this,i18n("Game won"),
+ i18n("<qt>You even removed the last stone, great job! "
+ "This gave you a score of %1 in total.</qt>").arg(stone->score()));
+ } else {
+ QMessageBox::information(this,i18n("Game over"),
+ i18n("<qt>There are no more removeable stones. "
+ "You got a score of %1 in total.</qt>").arg(stone->score()));
+ }
+ stone->unmark();
+}
+
+void ZSameWidget::desktop_widget(int *f)const{
+
+ QWidget* wid = QApplication::desktop();
+ /* width > height landscape mode */
+ if ( wid->width() > wid->height() ) {
+ f[0]=15;
+ f[1]=9;
+ }
+ /* normal */
+ else{
+ f[0]=12;
+ f[1]=13;
+ }
+}
+
+
diff --git a/noncore/games/zsame/ZSameWidget.h b/noncore/games/zsame/ZSameWidget.h
new file mode 100644
index 0000000..f31cbb7
--- a/dev/null
+++ b/noncore/games/zsame/ZSameWidget.h
@@ -0,0 +1,56 @@
+#ifndef ZSAME_WIDGET_H
+#define ZSAME_WIDGET_H
+
+#include "StoneWidget.h"
+#include <qmainwindow.h>
+
+class Config;
+class QAction;
+class ZSameWidget : public QMainWindow {
+ Q_OBJECT
+public:
+ static QString appName() { return QString::fromLatin1("zsame"); }
+ ZSameWidget(QWidget* parent, const char* name, WFlags fl );
+ ~ZSameWidget();
+
+private:
+ void desktop_widget(int *f)const;
+ StoneWidget *stone;
+ QAction *restart;
+ QAction *undo;
+
+ int multispin_item;
+
+protected:
+ void newGame( unsigned int board,int colors);
+
+ virtual void saveProperties(Config *conf);
+ virtual void readProperties(Config *conf);
+
+ bool confirmAbort();
+
+public slots:
+ void sizeChanged();
+
+/* File Menu */
+ void m_new();
+ void m_restart();
+ void m_load();
+ void m_save();
+ void m_showhs();
+ void m_quit();
+ void m_undo();
+
+/* Options Menu */
+ void m_tglboard();
+
+ void gameover();
+ void setColors(int colors);
+ void setBoard(int board);
+ void setScore(int score);
+ void setMarked(int m);
+ void stonesRemoved(int,int);
+};
+
+
+#endif
diff --git a/noncore/games/zsame/config.in b/noncore/games/zsame/config.in
new file mode 100644
index 0000000..cd3e1a1
--- a/dev/null
+++ b/noncore/games/zsame/config.in
@@ -0,0 +1,4 @@
+ config ZSAME
+ boolean "opie-zsame (a SameGame clone)"
+ default "y"
+ depends ( LIBQPE || LIBQPE-X11 )
diff --git a/noncore/games/zsame/dropin/kapplication.h b/noncore/games/zsame/dropin/kapplication.h
new file mode 100644
index 0000000..f83d08e
--- a/dev/null
+++ b/noncore/games/zsame/dropin/kapplication.h
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+
+static int _random() {
+ static int init = false;
+ if (!init) {
+ unsigned int seed;
+ init = true;
+ int fd = ::open("/dev/urandom", O_RDONLY);
+ if( fd<=0 || ::read(fd, &seed, sizeof(seed)) != sizeof(seed) ) {
+ srand(getpid());
+ seed = rand()+time(0);
+ }
+ if(fd>=0) close( fd );
+ srand(seed);
+ }
+ return rand();
+}
diff --git a/noncore/games/zsame/dropin/krandomsequence.cpp b/noncore/games/zsame/dropin/krandomsequence.cpp
new file mode 100644
index 0000000..d27a1c5
--- a/dev/null
+++ b/noncore/games/zsame/dropin/krandomsequence.cpp
@@ -0,0 +1,240 @@
+/*
+ This file is part of the KDE libraries
+ Copyright (c) 1999 Sean Harmer <sh@astro.keele.ac.uk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <qlist.h>
+#include <string.h>
+
+#include "kapplication.h"
+#include "krandomsequence.h"
+
+const int KRandomSequence::m_nShuffleTableSize = 32;
+
+//////////////////////////////////////////////////////////////////////////////
+// Construction / Destruction
+//////////////////////////////////////////////////////////////////////////////
+
+KRandomSequence::KRandomSequence( long lngSeed1 )
+{
+ // Seed the generator
+ setSeed( lngSeed1 );
+
+
+ // Set the size of the shuffle table
+ m_ShuffleArray = new long [m_nShuffleTableSize];
+}
+
+KRandomSequence::~KRandomSequence()
+{
+ delete [] m_ShuffleArray;
+}
+
+KRandomSequence::KRandomSequence(const KRandomSequence &a)
+{
+ // Set the size of the shuffle table
+ m_ShuffleArray = new long [m_nShuffleTableSize];
+ *this = a;
+}
+
+KRandomSequence &
+KRandomSequence::operator=(const KRandomSequence &a)
+{
+ m_lngSeed1 = a.m_lngSeed1;
+ m_lngSeed2 = a.m_lngSeed2;
+ m_lngShufflePos = a.m_lngShufflePos;
+ memcpy(m_ShuffleArray, a.m_ShuffleArray, sizeof(long)*m_nShuffleTableSize);
+ return *this;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Member Functions
+//////////////////////////////////////////////////////////////////////////////
+
+void KRandomSequence::setSeed( long lngSeed1 )
+{
+ // Convert the positive seed number to a negative one so that the Draw()
+ // function can intialise itself the first time it is called. We just have
+ // to make sure that the seed used != 0 as zero perpetuates itself in a
+ // sequence of random numbers.
+ if ( lngSeed1 < 0 )
+ {
+ m_lngSeed1 = -1;
+ }
+ else if (lngSeed1 == 0)
+ {
+ m_lngSeed1 = -((_random() & ~1)+1);
+ }
+ else
+ {
+ m_lngSeed1 = -lngSeed1;
+ }
+}
+
+static const long sMod1 = 2147483563;
+static const long sMod2 = 2147483399;
+
+void KRandomSequence::Draw()
+{
+ static const long sMM1 = sMod1 - 1;
+ static const long sA1 = 40014;
+ static const long sA2 = 40692;
+ static const long sQ1 = 53668;
+ static const long sQ2 = 52774;
+ static const long sR1 = 12211;
+ static const long sR2 = 3791;
+ static const long sDiv = 1 + sMM1 / m_nShuffleTableSize;
+
+ // Long period (>2 * 10^18) random number generator of L'Ecuyer with
+ // Bayes-Durham shuffle and added safeguards. Returns a uniform random
+ // deviate between 0.0 and 1.0 (exclusive of the endpoint values). Call
+ // with a negative number to initialize; thereafter, do not alter idum
+ // between successive deviates in a sequence. RNMX should approximate
+ // the largest floating point value that is less than 1.
+
+ int j; // Index for the shuffle table
+ long k;
+
+ // Initialise
+ if ( m_lngSeed1 <= 0 )
+ {
+ m_lngSeed2 = m_lngSeed1;
+
+ // Load the shuffle table after 8 warm-ups
+ for ( j = m_nShuffleTableSize + 7; j >= 0; j-- )
+ {
+ k = m_lngSeed1 / sQ1;
+ m_lngSeed1 = sA1 * ( m_lngSeed1 - k*sQ1) - k*sR1;
+ if ( m_lngSeed1 < 0 )
+ {
+ m_lngSeed1 += sMod1;
+ }
+
+ if ( j < m_nShuffleTableSize )
+ {
+ m_ShuffleArray[j] = m_lngSeed1;
+ }
+ }
+
+ m_lngShufflePos = m_ShuffleArray[0];
+ }
+
+ // Start here when not initializing
+
+ // Compute m_lngSeed1 = ( lngIA1*m_lngSeed1 ) % lngIM1 without overflows
+ // by Schrage's method
+ k = m_lngSeed1 / sQ1;
+ m_lngSeed1 = sA1 * ( m_lngSeed1 - k*sQ1 ) - k*sR1;
+ if ( m_lngSeed1 < 0 )
+ {
+ m_lngSeed1 += sMod1;
+ }
+
+ // Compute m_lngSeed2 = ( lngIA2*m_lngSeed2 ) % lngIM2 without overflows
+ // by Schrage's method
+ k = m_lngSeed2 / sQ2;
+ m_lngSeed2 = sA2 * ( m_lngSeed2 - k*sQ2 ) - k*sR2;
+ if ( m_lngSeed2 < 0 )
+ {
+ m_lngSeed2 += sMod2;
+ }
+
+ j = m_lngShufflePos / sDiv;
+ m_lngShufflePos = m_ShuffleArray[j] - m_lngSeed2;
+ m_ShuffleArray[j] = m_lngSeed1;
+
+ if ( m_lngShufflePos < 1 )
+ {
+ m_lngShufflePos += sMM1;
+ }
+}
+
+void
+KRandomSequence::modulate(int i)
+{
+ m_lngSeed2 -= i;
+ if ( m_lngSeed2 < 0 )
+ {
+ m_lngShufflePos += sMod2;
+ }
+ Draw();
+ m_lngSeed1 -= i;
+ if ( m_lngSeed1 < 0 )
+ {
+ m_lngSeed1 += sMod1;
+ }
+ Draw();
+}
+
+double
+KRandomSequence::getDouble()
+{
+ static const double finalAmp = 1.0 / double( sMod1 );
+ static const double epsilon = 1.2E-7;
+ static const double maxRand = 1.0 - epsilon;
+ double temp;
+ Draw();
+ // Return a value that is not one of the endpoints
+ if ( ( temp = finalAmp * m_lngShufflePos ) > maxRand )
+ {
+ // We don't want to return 1.0
+ return maxRand;
+ }
+ else
+ {
+ return temp;
+ }
+}
+
+unsigned long
+KRandomSequence::getLong(unsigned long max)
+{
+ Draw();
+
+ return max ? (((unsigned long) m_lngShufflePos) % max) : 0;
+}
+
+bool
+KRandomSequence::getBool()
+{
+ Draw();
+
+ return (((unsigned long) m_lngShufflePos) & 1);
+}
+
+class KRandomSequenceList : public QGList
+{
+ friend class KRandomSequence;
+public:
+ KRandomSequenceList() : QGList() { }
+ virtual void deleteItem( QCollection::Item ) {}
+};
+
+void
+KRandomSequence::randomize(QGList *_list)
+{
+ KRandomSequenceList *list = (KRandomSequenceList *)_list;
+ KRandomSequenceList l;
+ while(list->count())
+ l.append(list->takeFirst());
+
+ list->append(l.takeFirst()); // Start with 1
+ while(l.count())
+ list->insertAt(getLong(list->count()+1), l.takeFirst());
+}
diff --git a/noncore/games/zsame/dropin/krandomsequence.h b/noncore/games/zsame/dropin/krandomsequence.h
new file mode 100644
index 0000000..402e106
--- a/dev/null
+++ b/noncore/games/zsame/dropin/krandomsequence.h
@@ -0,0 +1,143 @@
+/* This file is part of the KDE libraries
+ Copyright (c) 1999 Sean Harmer <sh@astro.keele.ac.uk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+#ifndef K_RANDOM_SEQUENCE_H
+#define K_RANDOM_SEQUENCE_H
+
+class KRandomSequencePrivate;
+class QGList;
+/**
+ * A class to create a pseudo-random sequence
+ *
+ * Given a seed number, this class will produce a sequence of
+ * pseudo-random numbers. This would typically be used in
+ * applications like games.
+ *
+ * In general, you should instantiate a KRandomSequence object and
+ * pass along your seed number in the constructor. From then on,
+ * simply call getDouble or getLong to obtain the next
+ * number in the sequence.
+ *
+ * @author Sean Harmer <sh@astro.keele.ac.uk>
+ */
+class KRandomSequence
+{
+public:
+ /**
+ * Creates a pseudo-random sequence based on the seed lngSeed.
+ *
+ * A Pseudo-random sequence is different for each seed but can be
+ * reproduced by starting the sequence with the same seed.
+ *
+ * If you need a single value which needs to be unpredictable,
+ * you need to use kapp->random() instead.
+ *
+ * @param lngSeed Seed to initialize the sequence with.
+ * If lngSeed is 0, the sequence is initialized with a value from
+ * KApplication::random().
+ */
+ KRandomSequence( long lngSeed = 0 );
+
+ /**
+ * Standard destructor
+ */
+ virtual ~KRandomSequence();
+
+ /**
+ * Copy constructor
+ */
+ KRandomSequence(const KRandomSequence &a);
+
+ /**
+ * Assignment
+ */
+ KRandomSequence &operator=(const KRandomSequence &a);
+
+ /**
+ * Restart the sequence based on lngSeed.
+ * @param lngSeed Seed to initialize the sequence with.
+ * If lngSeed is 0, the sequence is initialized with a value from
+ * KApplication::random().
+ */
+ void setSeed( long lngSeed = 1 );
+
+ /**
+ * Get the next number from the pseudo-random sequence.
+ *
+ * @return a pseudo-random double value between [0,1[
+ */
+ double getDouble();
+
+ /**
+ * Get the next number from the pseudo-random sequence.
+ *
+ * @return a pseudo-random integer value between [0, max[
+ * with 0 <= max < 1.000.000
+ */
+ unsigned long getLong(unsigned long max);
+
+ /**
+ * Get a boolean from the pseudo-random sequence.
+ *
+ * @return a boolean which is either true or false
+ */
+ bool getBool();
+
+ /**
+ * Put a list in random order.
+ *
+ * @param list the list whose order will be modified
+ */
+ void randomize(QGList *list);
+
+ /**
+ * Modulate the random sequence.
+ *
+ * If S(i) is the sequence of numbers that will follow
+ * given the current state after calling modulate(i),
+ * then S(i) != S(j) for i != j and
+ * S(i) == S(j) for i == j.
+ *
+ * This can be useful in game situation where "undo" restores
+ * the state of the random sequence. If the game modulates the
+ * random sequence with the move chosen by the player, the
+ * random sequence will be identical whenever the player "redo"-s
+ * his or hers original move, but different when the player
+ * chooses another move.
+ *
+ * With this scenario "undo" can no longer be used to repeat a
+ * certain move over and over again until the computer reacts
+ * with a favorable response or to predict the response for a
+ * certain move based on the response to another move.
+ * @param i the sequence identified
+ */
+ void modulate(int i);
+
+private:
+ void Draw(); // Generate the random number
+ long m_lngSeed1;
+ long m_lngSeed2;
+ long m_lngShufflePos;
+
+ static const int m_nShuffleTableSize;
+ long *m_ShuffleArray;
+
+ KRandomSequencePrivate *d;
+};
+
+#endif
+
diff --git a/noncore/games/zsame/version.h b/noncore/games/zsame/version.h
new file mode 100644
index 0000000..22b96fa
--- a/dev/null
+++ b/noncore/games/zsame/version.h
@@ -0,0 +1,6 @@
+#define KSAME_VERSION "0.5-Embedded"
+
+
+
+
+
diff --git a/noncore/games/zsame/zsame.pro b/noncore/games/zsame/zsame.pro
new file mode 100644
index 0000000..17fba91
--- a/dev/null
+++ b/noncore/games/zsame/zsame.pro
@@ -0,0 +1,17 @@
+CONFIG += qt warn_on quick-app
+
+
+TARGET = zsame
+
+HEADERS = StoneField.h StoneWidget.h ZSameWidget.h dropin/krandomsequence.h
+SOURCES = StoneField.cpp StoneWidget.cpp ZSameWidget.cpp dropin/krandomsequence.cpp
+
+
+INCLUDEPATH += $(OPIEDIR)/include dropin
+DEPENDPATH += $(OPIEDIR)/include
+
+
+# we now also include opie
+LIBS += -lqpe
+
+include ( $(OPIEDIR)/include.pro )