author | zecke <zecke> | 2004-02-17 15:55:24 (UTC) |
---|---|---|
committer | zecke <zecke> | 2004-02-17 15:55:24 (UTC) |
commit | 1207607ebbc59841718b79508fc222cb4eee9fde (patch) (side-by-side diff) | |
tree | 60c292a98621385006fbacca82dd11326765c0ab | |
parent | 2ec4085cc290a212c7bec8bdf7a2475f3ee6e069 (diff) | |
download | opie-1207607ebbc59841718b79508fc222cb4eee9fde.zip opie-1207607ebbc59841718b79508fc222cb4eee9fde.tar.gz opie-1207607ebbc59841718b79508fc222cb4eee9fde.tar.bz2 |
Add the source of zsame
-rw-r--r-- | noncore/games/zsame/KSameWidget.cpp | 248 | ||||
-rw-r--r-- | noncore/games/zsame/KSameWidget.h | 81 | ||||
-rw-r--r-- | noncore/games/zsame/PortChanges | 14 | ||||
-rw-r--r-- | noncore/games/zsame/StoneField.cpp | 390 | ||||
-rw-r--r-- | noncore/games/zsame/StoneField.h | 113 | ||||
-rw-r--r-- | noncore/games/zsame/StoneWidget.cpp | 350 | ||||
-rw-r--r-- | noncore/games/zsame/StoneWidget.h | 115 | ||||
-rw-r--r-- | noncore/games/zsame/ZSameWidget.cpp | 250 | ||||
-rw-r--r-- | noncore/games/zsame/ZSameWidget.h | 56 | ||||
-rw-r--r-- | noncore/games/zsame/config.in | 4 | ||||
-rw-r--r-- | noncore/games/zsame/dropin/kapplication.h | 23 | ||||
-rw-r--r-- | noncore/games/zsame/dropin/krandomsequence.cpp | 240 | ||||
-rw-r--r-- | noncore/games/zsame/dropin/krandomsequence.h | 143 | ||||
-rw-r--r-- | noncore/games/zsame/version.h | 6 | ||||
-rw-r--r-- | noncore/games/zsame/zsame.pro | 17 |
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 ) |