summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore 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 @@
1/* Yo Emacs, this is -*- C++ -*- */
2/*
3 * ksame 0.4 - simple Game
4 * Copyright (C) 1997,1998 Marcus Kreutzberger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#include <stdio.h>
23
24#include <qwidget.h>
25#include <qpushbutton.h>
26#include <qpixmap.h>
27#include <qvbox.h>
28#include <qpopupmenu.h>
29
30#include <kapplication.h>
31#include <kiconloader.h>
32#include <kdialogbase.h>
33#include <kscoredialog.h>
34#include <kstatusbar.h>
35#include <knuminput.h>
36#include <klocale.h>
37#include <knotifyclient.h>
38#include <kfiledialog.h>
39#include <kmessagebox.h>
40#include <kmenubar.h>
41#include <kconfig.h>
42#include <kstdaction.h>
43#include <kaction.h>
44#include <kdebug.h>
45#include <kkeydialog.h>
46
47#include "KSameWidget.h"
48#include "StoneWidget.h"
49#include "version.h"
50
51static int default_colors=3;
52
53 #define Board KScoreDialog::Custom1
54
55KSameWidget::KSameWidget() : KMainWindow(0)
56{
57 setCaption("");
58 KStdAction::openNew(this, SLOT(m_new()), actionCollection(), "game_new");
59 restart = new KAction(i18n("&Restart This Board"), CTRL+Key_R, this,
60 SLOT(m_restart()), actionCollection(), "game_restart");
61 // KStdAction::open(this, SLOT(m_load()), actionCollection(), "game_load");
62 // KStdAction::save(this, SLOT(m_save()), actionCollection(), "game_save");
63 new KAction(i18n("S&how Highscore"), CTRL+Key_H, this,
64 SLOT(m_showhs()), actionCollection(), "game_highscores");
65 KStdAction::quit(this, SLOT(m_quit()), actionCollection(), "game_quit");
66 KStdAction::keyBindings( this, SLOT( slotConfigureKeys() ), actionCollection() );
67 undo = KStdAction::undo(this, SLOT(m_undo()),
68 actionCollection(), "edit_undo");
69
70 random = new KToggleAction(i18n("&Random Board"), 0, this,
71 SLOT(m_tglboard()), actionCollection(),
72 "random_board");
73
74 status=statusBar();
75 status->insertItem(i18n("Colors: XX"),1,1);
76 status->insertItem(i18n("Board: XXXXXX"),2,1);
77 status->insertItem(i18n("Marked: XXXXXX"),3,1);
78 status->insertItem(i18n("Score: XXXXXX"),4,1);
79
80 stone = new StoneWidget(this,15,10);
81
82 connect( stone, SIGNAL(s_gameover()), this, SLOT(gameover()));
83
84 connect( stone, SIGNAL(s_colors(int)), this, SLOT(setColors(int)));
85 connect( stone, SIGNAL(s_board(int)), this, SLOT(setBoard(int)));
86 connect( stone, SIGNAL(s_marked(int)), this, SLOT(setMarked(int)));
87 connect( stone, SIGNAL(s_score(int)), this, SLOT(setScore(int)));
88 connect( stone, SIGNAL(s_remove(int,int)), this, SLOT(stonesRemoved(int,int)));
89
90 connect(stone, SIGNAL(s_sizechanged()), this, SLOT(sizeChanged()));
91
92 sizeChanged();
93 setCentralWidget(stone);
94
95 createGUI();
96
97 random->setChecked(true);
98 setScore(0);
99
100 if (!kapp->isRestored()) newGame(kapp->random(),default_colors);
101 kdDebug() << "test" << endl;
102}
103
104KSameWidget::~KSameWidget() {
105}
106
107void KSameWidget::slotConfigureKeys()
108{
109 KKeyDialog::configure( actionCollection(), this );
110}
111
112void KSameWidget::readProperties(KConfig *conf) {
113 Q_ASSERT(conf);
114 stone->readProperties(conf);
115}
116
117void KSameWidget::saveProperties(KConfig *conf) {
118 Q_ASSERT(conf);
119 stone->saveProperties(conf);
120 conf->sync();
121}
122
123void KSameWidget::sizeChanged() {
124 stone->setFixedSize(stone->sizeHint());
125}
126
127void KSameWidget::newGame(unsigned int board,int colors) {
128 while (board>=1000000) board-=1000000;
129 // kdDebug() << "newgame board " << board << " colors " << colors << endl;
130 stone->newGame(board,colors);
131 setScore(0);
132}
133
134bool KSameWidget::confirmAbort() {
135 return stone->isGameover() ||
136 stone->isOriginalBoard() ||
137 (KMessageBox::questionYesNo(this, i18n("Do you want to resign?"),
138 i18n("New Game")) == KMessageBox::Yes);
139}
140
141void KSameWidget::m_new() {
142 if (random->isChecked()) {
143 if (confirmAbort())
144 newGame(kapp->random(),default_colors);
145 } else {
146 KDialogBase dlg(this, "boardchooser", true,
147 i18n("Select Board"),
148 KDialogBase::Ok | KDialogBase::Cancel,
149 KDialogBase::Ok);
150
151 QVBox *page = dlg.makeVBoxMainWidget();
152
153 KIntNumInput bno(0, page);
154 bno.setRange(0, 1000000, 1);
155 bno.setLabel(i18n("Select a board:"));
156 bno.setFocus();
157 bno.setFixedSize(bno.sizeHint());
158 bno.setValue(stone->board());
159
160 if (dlg.exec()) newGame(bno.value(),default_colors);
161 }
162}
163
164void KSameWidget::m_restart() {
165 if (confirmAbort())
166 newGame(stone->board(),default_colors);
167}
168
169void KSameWidget::m_load() {
170 kdDebug() << "menu load not supported" << endl;
171}
172
173void KSameWidget::m_save() {
174 kdDebug() << "menu save not supported" << endl;
175}
176
177void KSameWidget::m_undo() {
178 Q_ASSERT(stone);
179 stone->undo();
180}
181
182
183void KSameWidget::m_showhs() {
184 Q_ASSERT(stone);
185 stone->unmark();
186 KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score, this);
187 d.addField(Board, i18n("Board"), "Board");
188 d.exec();
189}
190
191void KSameWidget::m_quit() {
192 Q_ASSERT(stone);
193 stone->unmark();
194 kapp->quit();
195 delete this;
196}
197
198void KSameWidget::m_tglboard() {
199 kdDebug() << "toggled" << endl;
200}
201
202
203void KSameWidget::setColors(int colors) {
204 status->changeItem(i18n("%1 Colors").arg(colors),1);
205}
206
207void KSameWidget::setBoard(int board) {
208 status->changeItem(i18n("Board: %1").arg(board, 6), 2);
209}
210
211void KSameWidget::setMarked(int m) {
212 status->changeItem(i18n("Marked: %1").arg(m, 6),3);
213}
214
215void KSameWidget::stonesRemoved(int,int) {
216 KNotifyClient::event("stones removed",
217 i18n("%1 stones removed.").arg(stone->marked()));
218}
219
220void KSameWidget::setScore(int score) {
221 status->changeItem(i18n("Score: %1").arg(score, 6),4);
222 undo->setEnabled(stone->undoPossible());
223 restart->setEnabled(!stone->isOriginalBoard());
224}
225
226void KSameWidget::gameover() {
227 kdDebug() << "GameOver" << endl;
228 if (stone->hasBonus()) {
229 KNotifyClient::event("game won",
230 i18n("You even removed the last stone, great job! "
231 "This gave you a score of %1 in total.").arg(stone->score()));
232 } else {
233 KNotifyClient::event("game over",
234 i18n("There are no more removeable stones. "
235 "You got a score of %1 in total.").arg(stone->score()));
236 }
237 stone->unmark();
238 KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score, this);
239 d.addField(Board, i18n("Board"), "Board");
240
241 KScoreDialog::FieldInfo scoreInfo;
242 scoreInfo[Board].setNum(stone->board());
243
244 if (d.addScore(stone->score(), scoreInfo))
245 d.exec();
246}
247
248#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 @@
1/* Yo Emacs, this is -*- C++ -*- */
2/*
3 * ksame 0.4 - simple Game
4 * Copyright (C) 1997,1998 Marcus Kreutzberger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#ifndef _KSAMEWIDGET
23#define _KSAMEWIDGET
24
25#include "StoneWidget.h"
26#include <kmainwindow.h>
27
28class KToggleAction;
29
30class KSameWidget: public KMainWindow {
31 Q_OBJECT
32public:
33 KSameWidget();
34 ~KSameWidget();
35
36private:
37 StoneWidget *stone;
38 KStatusBar *status;
39 KToggleAction *random;
40 KAction *restart;
41 KAction *undo;
42
43 int multispin_item;
44
45
46protected:
47 void newGame(unsigned int board,int colors);
48
49 virtual void saveProperties(KConfig *conf);
50 virtual void readProperties(KConfig *conf);
51
52 bool confirmAbort();
53
54 public slots:
55 void sizeChanged();
56
57 /* File Menu */
58 void m_new();
59 void m_restart();
60 void m_load();
61 void m_save();
62 void m_showhs();
63 void m_quit();
64 void m_undo();
65
66 /* Options Menu */
67 void m_tglboard();
68
69 void gameover();
70 void setColors(int colors);
71 void setBoard(int board);
72 void setScore(int score);
73 void setMarked(int m);
74 void stonesRemoved(int,int);
75 void slotConfigureKeys();
76
77};
78
79
80
81#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 @@
1-Scale the Image to be 50% of the original one
2-Add pics/zsame
3-Add .pro file
4-Add .applnk file
5-UnComment kdDebug
6-New MainWidget
7-Remove HighScore and KNotify Events
8-Adjust to Stylus Interface
9
10--TODO:
11 -Recognize on the fly changes ( monitor Desktop Widget )
12
13
14 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 @@
1/*
2 * ksame 0.4 - simple Game
3 * Copyright (C) 1997,1998 Marcus Kreutzberger
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21#include "StoneField.h"
22#include <assert.h>
23
24StoneFieldState::StoneFieldState(const StoneField &stonefield)
25{
26 field=new unsigned char[stonefield.maxstone];
27 for (int i=0;i<stonefield.maxstone;i++)
28 field[i]=stonefield.field[i].color;
29
30 colors=stonefield.colors;
31 board=stonefield.board;
32 score=stonefield.score;
33 gameover=stonefield.gameover;
34}
35
36StoneFieldState::~StoneFieldState() {
37 delete[] field;
38}
39
40void
41StoneFieldState::restore(StoneField &stonefield) const {
42 for (int i=0;i<stonefield.maxstone;i++) {
43 stonefield.field[i].color=field[i];
44 stonefield.field[i].changed=true;
45 stonefield.field[i].marked=false;
46 }
47
48 stonefield.colors=colors;
49 stonefield.board=board;
50 stonefield.score=score;
51 stonefield.marked=0;
52 stonefield.gameover=gameover;
53}
54
55StoneField::StoneField(int width, int height,
56 int colors, unsigned int board,
57 bool undoenabled)
58{
59// Q_ASSERT(width>0);
60// Q_ASSERT(height>0);
61
62 if (undoenabled) undolist=new QList<StoneFieldState>;
63 else undolist=0;
64
65 sizex=width;
66 sizey=height;
67 maxstone=sizex*sizey;
68 field=new Stone[maxstone];
69 newGame(board,colors);
70 m_gotBonus= false;
71}
72
73StoneField::~StoneField() {
74 delete[] field;
75 delete undolist;
76// kdDebug() << "~StoneField\n" << endl;
77}
78
79int
80StoneField::width() const {
81 return sizex;
82}
83
84int
85StoneField::height() const {
86 return sizey;
87}
88
89void
90StoneField::newGame(unsigned int board,int colors) {
91// kdDebug() << "StoneField::newgame board "
92// << board << " colors " << colors << endl;
93 if (colors<1) colors=3;
94 if (colors>7) colors=7;
95 this->colors=colors;
96 this->board=board;
97 reset();
98}
99
100void
101StoneField::reset() {
102 random.setSeed(board);
103
104 Stone *stone=field;
105 for (int i=0;i<maxstone;i++,stone++) {
106 stone->color=1+random.getLong(colors);
107 stone->marked=false;
108 stone->changed=true;
109 }
110
111 gameover=-1;
112 score=0;
113 marked=0;
114
115 if (undolist) {
116 undolist->setAutoDelete(true);
117 undolist->clear();
118 }
119
120
121 int c[7];
122 int j;
123 for (j=0;j<7;j++) c[j]=0;
124
125 for (j=0,stone=field;j<maxstone;j++,stone++) {
126 c[stone->color]++;
127 }
128// kdDebug() << "red " << c[1] << endl;
129// kdDebug() << "blue " << c[2] << endl;
130// kdDebug() << "yellow " << c[3] << endl;
131// kdDebug() << "green " << c[4] << endl;
132
133}
134
135int
136StoneField::map(int x,int y) {
137 assert (!(x<0||y<0||x>=sizex||y>=sizey));
138 return x+y*sizex;
139}
140
141int
142StoneField::mark(int x,int y,bool force) {
143 int index=map(x,y);
144
145 if (index<0) {
146 unmark();
147 return 0;
148 }
149
150 if (field[index].marked) return -1;
151 unmark();
152
153 mark(index,field[index].color);
154
155 if (marked==1&&!force) {
156 field[index].marked=false;
157 marked=0;
158 }
159 return marked;
160}
161
162void
163StoneField::mark(int index,unsigned char color) {
164 if ( index<0 || index>=maxstone ) return;
165
166 Stone &stone=field[index];
167
168 if (stone.marked) return;
169
170 if (!stone.color || stone.color!=color) return;
171
172 stone.changed=true;
173 stone.marked=true;
174 marked++;
175
176 // mark left
177 if ((index%sizex)!=0) mark(index-1,color);
178 // mark right
179 if (((index+1)%sizex)!=0) mark(index+1,color);
180 // mark upward
181 if (index>=sizex) mark(index-sizex,color);
182 // mark downward
183 if (index<(sizex-1)*sizey) mark(index+sizex,color);
184}
185
186void
187StoneField::unmark() {
188 if (!marked) return;
189
190 Stone *stone=field;
191 for (int i=0;i<maxstone;i++,stone++) {
192 stone->marked=false;
193 stone->changed=true;
194 }
195 marked=0;
196}
197
198int
199StoneField::remove(int x,int y,bool force) {
200 int index=map(x,y);
201
202 if (index<0) return 0;
203
204 if (!field[index].marked) {
205 mark(x,y,force);
206 }
207
208 if (!marked) return 0;
209
210 // remove a single stone??
211 if (marked==1&&!force) return 0;
212
213 // add current field to undolist
214 if (undolist)
215 undolist->append(new StoneFieldState(*this));
216
217 // increase score
218 if (marked>2)
219 score+=(marked-2)*(marked-2);
220
221 // remove marked stones
222 Stone *stone=field;
223 for (int i=0;i<maxstone;i++,stone++) {
224 if (stone->marked) {
225 stone->color=0;
226 stone->changed=true;
227 stone->marked=false;
228 }
229 }
230 int removed=marked;
231 marked=0;
232
233 for (int col=0;col<sizex;col++) {
234 int i1=col+maxstone-sizex;
235 while ( i1>=0 && field[i1].color ) i1-=sizex;
236 int i2=i1;
237 while (i2>=0) {
238 while ( i2>=0 && !field[i2].color ) i2-=sizex;
239 while ( i2>=0 && field[i2].color ) {
240 field[i1].color=field[i2].color;
241 field[i1].changed=true;
242 field[i2].color=0;
243 field[i2].changed=true;
244 i1-=sizex;
245 i2-=sizex;
246 }
247 }
248 }
249
250 // find the last column that has something
251 int lastcol = sizex;
252 while (lastcol > 0 && !field[map(lastcol-1, sizey-1)].color) {
253 lastcol--;
254 }
255
256 for (int col=0;col<lastcol-1;) {
257 bool empty = true;
258 for (int row = 0; row < sizey; row++)
259 if (field[map(col, row)].color) {
260 empty = false;
261 break;
262 }
263 if (!empty) {
264 col++;
265 continue;
266 }
267 int nextfullcol = col + 1;
268 while (nextfullcol < sizex &&
269 !field[map(nextfullcol, sizey - 1)].color)
270 nextfullcol++;
271
272 if (nextfullcol > sizex - 1)
273 break; // we're ready
274
275 for (int row=0; row < sizey; row++) {
276 int source = map(nextfullcol, row);
277 int dest = map(col, row);
278 field[dest].color=field[source].color;
279 field[dest].changed=true;
280 field[source].color=0;
281 field[source].changed=true;
282 }
283 }
284
285 // add a bonus, if field is empty
286 if (!field[map(0, sizey-1)].color) {
287 score+=1000;
288 m_gotBonus= true;
289 }
290
291 // gameover is undefined
292 gameover=-1;
293 return removed;
294}
295
296bool StoneField::undoPossible() const {
297 return !(!undolist||undolist->isEmpty());
298}
299
300int
301StoneField::undo(int count) {
302 if (!undoPossible())
303 return 0;
304 if (count <= 0)
305 return 0;
306 int undocount=1;
307 StoneFieldState *state=0;
308 undolist->setAutoDelete(true);
309 while (--count>0) {
310 if (undolist->count()==1) break;
311 undolist->removeLast();
312 undocount++;
313 }
314 state=undolist->getLast();
315// Q_ASSERT(state);
316 state->restore(*this);
317 undolist->removeLast();
318 return undocount;
319}
320
321bool
322StoneField::isGameover() const {
323 register int i=maxstone-1;;
324 register unsigned char color;
325
326 if (gameover>=0) return (bool)gameover;
327 // kdDebug() << "-->gameover" << endl;
328
329 while (i>=0) {
330 // kdDebug() << i << " " << field[i].color << endl;
331 // ignore empty fields
332 while ( i>=0 && field[i].color==0 ) i--;
333 // Wenn Stein gefunden,
334 // dann die Nachbarn auf gleiche Farbe pruefen.
335 while ( i>=0 && (color=field[i].color) ) {
336 // check left
337 if ( (i%sizex)!=0 && field[i-1].color==color)
338 goto check_gameover;
339 // check upward
340 if ( i>=sizex && field[i-sizex].color==color)
341 goto check_gameover;
342 i--;
343 }
344 }
345 check_gameover:
346 gameover=(i<0);
347 // kdDebug() << "<--gameover" << endl;
348 return (bool)gameover;
349}
350
351bool StoneField::gotBonus() const {
352 return m_gotBonus;
353}
354
355int
356StoneField::getBoard() const {
357 return board;
358}
359
360int
361StoneField::getScore() const {
362 return score;
363}
364
365int
366StoneField::getColors() const {
367 return colors;
368}
369
370int
371StoneField::getMarked() const {
372 return marked;
373}
374
375int
376StoneField::getFieldSize() const {
377 return maxstone;
378}
379
380struct Stone *
381StoneField::getField() const {
382 return field;
383}
384
385
386
387
388
389
390
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 @@
1/* Yo Emacs, this is -*- C++ -*- */
2/*
3 * ksame 0.4 - simple Game
4 * Copyright (C) 1997,1998 Marcus Kreutzberger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#ifndef _STONEFIELD
23#define _STONEFIELD
24
25#include <krandomsequence.h>
26#include <qlist.h>
27
28struct Stone {
29 unsigned char color;
30 bool changed;
31 bool marked;
32};
33
34class StoneField;
35class StoneWidget;
36
37class StoneFieldState {
38private:
39 unsigned char *field;
40
41 int colors;
42 unsigned int board;
43 unsigned int score;
44 int gameover;
45
46public:
47 StoneFieldState(const StoneField &stonefield);
48 ~StoneFieldState();
49 void restore(StoneField &stonefield) const;
50};
51
52
53class StoneField {
54 friend class StoneFieldState;
55 friend class StoneWidget;
56private:
57
58 int sizex;
59 int sizey;
60 int maxstone;
61
62 struct Stone *field;
63
64 int colors;
65 unsigned int board;
66 unsigned int score;
67 mutable int gameover;
68 bool m_gotBonus;
69 int marked;
70
71 KRandomSequence random;
72 QList<StoneFieldState> *undolist;
73public:
74 StoneField(int width=15,int height=10,
75 int colors=3,unsigned int board=0,
76 bool undoenabled=true);
77 ~StoneField();
78
79 int width() const;
80 int height() const;
81
82 void newGame(unsigned int board,int colors);
83
84 void reset();
85
86
87 int mark(int x,int y,bool force=false);
88 void unmark();
89
90 int remove(int x,int y,bool force=false);
91
92 int undo(int count=1);
93
94 bool isGameover() const;
95 bool gotBonus() const;
96 bool undoPossible() const;
97 int getBoard() const;
98 int getScore() const;
99 int getColors() const;
100 int getMarked() const;
101
102protected:
103 int getFieldSize() const;
104 struct Stone *getField() const;
105
106 int map(int x,int y);
107 void mark(int index,unsigned char color);
108};
109
110#endif
111
112
113
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 @@
1/*
2 * ksame 0.4 - simple Game
3 * Copyright (C) 1997,1998 Marcus Kreutzberger
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23
24#include <qpainter.h>
25#include <qpixmap.h>
26#include <qbitmap.h>
27#include <qimage.h>
28#include <qcursor.h>
29
30
31#include <qpe/resource.h>
32
33#include <time.h>
34#include <assert.h>
35
36#include "StoneWidget.h"
37
38
39
40struct StoneSlice {
41 QPixmap stone;
42};
43
44
45StoneWidget::StoneWidget( QWidget *parent, int x, int y )
46 : QWidget(parent,"StoneWidget"), stonefield(x,y)
47{
48// setBackgroundPixmap(QPixmap(locate("wallpaper", "Time-For-Lunch-2.jpg")));
49// QPixmap stonemap(locate("appdata", "stones.png"));
50
51 QPixmap stonemap = Resource::loadPixmap("zsame/stones" );
52 assert(!stonemap.isNull());
53
54 slice=0;
55 maxslices=30;
56 maxcolors=4;
57
58 sizex=x;
59 sizey=y;
60
61 stone_width=stonemap.width()/(maxslices+1);
62 stone_height=stonemap.height()/maxcolors;
63
64 map = new StoneSlice*[maxcolors];
65 QBitmap mask;
66 for (int c = 0; c < maxcolors; c++) {
67 map[c] = new StoneSlice[maxslices];
68
69 for (int s = 0; s < maxslices; s++) {
70 map[c][s].stone.resize(stone_width, stone_height);
71 assert(!map[c][s].stone.isNull());
72 bitBlt(&map[c][s].stone, 0, 0,
73 &stonemap, stone_width * s,
74 c*stone_height,
75 stone_width,stone_height,CopyROP,false);
76 QImage im = map[c][s].stone.convertToImage();
77 mask = im.createHeuristicMask();
78 map[c][s].stone.setMask(mask);
79 }
80 }
81
82 field_height=stone_height*sizey;
83 field_width=stone_width*sizex;
84
85 setMouseTracking(true);
86
87 // QColor c(115,115,115);
88 // setBackgroundColor(c);
89
90 // emit s_sizechanged();
91 startTimer( 100 );
92 history.setAutoDelete(true);
93}
94
95StoneWidget::~StoneWidget() {
96 for (int c = 0; c < maxcolors; c++) {
97 delete [] map[c];
98 }
99 delete [] map;
100
101 setMouseTracking(false);
102 killTimers();
103}
104
105unsigned int
106StoneWidget::board() {
107 return stonefield.getBoard();
108}
109
110int
111StoneWidget::score() {
112 return stonefield.getScore();
113}
114
115int
116StoneWidget::marked() {
117 return stonefield.getMarked();
118}
119
120QSize
121StoneWidget::size() {
122 return QSize(sizex,sizey);
123}
124
125int
126StoneWidget::colors() {
127 return stonefield.getColors();
128}
129
130QSize
131StoneWidget::sizeHint () const {
132 return QSize(field_width,field_height);
133}
134
135void
136StoneWidget::newGame(unsigned int board,int colors) {
137 stonefield.newGame(board,colors);
138 history.clear();
139 modified= false;
140 emit s_newgame();
141 emit s_colors(stonefield.getColors());
142 emit s_board(stonefield.getBoard());
143}
144
145void
146StoneWidget::reset() {
147 stonefield.reset();
148 history.clear();
149 emit s_newgame();
150}
151
152void
153StoneWidget::unmark() {
154 stonefield.unmark();
155 emit s_marked(0);
156}
157
158bool StoneWidget::undoPossible() const {
159 if (stonefield.isGameover()) return false;
160 return stonefield.undoPossible();
161}
162
163int
164StoneWidget::undo(int count) {
165 if (stonefield.isGameover()) return 0;
166
167 int ret_val=stonefield.undo(count);
168
169 QPoint p=mapFromGlobal(cursor().pos());
170 int x=p.x();
171 int y=p.y();
172 if (x<0||y<0||x>=field_width||y>=field_height) {
173 emit s_score(stonefield.getMarked());
174 return ret_val;
175 }
176
177 int marked=stonefield.mark(x/stone_width,y/stone_height);
178 emit s_marked(marked);
179 slice=0;
180 emit s_score(stonefield.getScore());
181 modified= (stonefield.getScore()>0);
182 return ret_val;
183}
184
185bool StoneWidget::isGameover() {
186 return stonefield.isGameover();
187}
188
189bool StoneWidget::hasBonus() {
190 return stonefield.gotBonus(); // don't ask me why the names differ... ;-| [hlm]
191}
192
193bool StoneWidget::isOriginalBoard() {
194 return !modified;
195}
196
197void StoneWidget::readProperties(Config *) {
198/* Q_ASSERT(conf);
199
200 history.clear();
201
202 if (!conf->hasKey("Board")||
203 !conf->hasKey("Colors")||
204 !conf->hasKey("Stones")) {
205 return;
206 }
207 newGame(conf->readNumEntry("Board"),conf->readNumEntry("Colors"));
208
209 QStrList list;
210 conf->readListEntry("Stones",list);
211
212 for (const char *item=list.first();item;item=list.next()) {
213 int x=-1,y=-1;
214 if (sscanf(item,"%02X%02X",&x,&y)!=2) break;
215 history.append(new QPoint(x,y));
216 stonefield.remove(x,y);
217 }
218*/
219}
220
221
222void
223StoneWidget::saveProperties(Config *) {
224/*
225 Q_ASSERT(conf);
226
227 QStrList list(true);
228 QString tmp;
229
230 for (QPoint *item=history.first();item;item=history.next()) {
231 tmp.sprintf("%02X%02X",item->x(),item->y());
232 list.append(tmp.ascii());
233 }
234
235 conf->writeEntry("Stones",list);
236 conf->writeEntry("Board",stonefield.getBoard());
237 conf->writeEntry("Colors",stonefield.getColors());
238*/
239}
240
241void
242StoneWidget::timerEvent( QTimerEvent * ) {
243 QPoint p=mapFromGlobal(cursor().pos());
244 int x=p.x();
245 int y=p.y();
246 if (x<0||y<0||x>=field_width||y>=field_height)
247 stonefield.unmark();
248 slice=(slice+1)%maxslices;
249 paintEvent(0);
250}
251
252void
253StoneWidget::paintEvent( QPaintEvent *e ) {
254
255 Stone *stone=stonefield.getField();
256
257 for (int y=0;y<sizey;y++) {
258 int cy = y * stone_height;
259
260 for (int x=0;x<sizex;x++) {
261 int cx = stone_width * x;
262
263 bool redraw=stone->marked||stone->changed;
264
265 if (!redraw&&e) {
266 QRect r(cx,cy,stone_width,stone_height);
267 redraw=r.intersects(e->rect());
268 }
269 if (redraw) {
270 stone->changed=false;
271 if (stone->color) {
272
273 int tslice = stone->marked?slice:0;
274 bitBlt(this,cx,cy,
275 &map[stone->color-1][tslice].stone,
276 0, 0,
277 stone_width,stone_height,CopyROP,FALSE);
278
279 } else {
280 erase(cx, cy, stone_width, stone_height);
281 }
282 }
283 stone++; // naechster Stein.
284 }
285 }
286}
287
288void
289StoneWidget::mousePressEvent ( QMouseEvent *e) {
290
291 if (stonefield.isGameover()) return;
292
293 int x=e->pos().x();
294 int y=e->pos().y();
295 if (x<0||y<0||x>=field_width||y>=field_height) return;
296
297 int sx=x/stone_width;
298 int sy=y/stone_height;
299
300 int mar =stonefield.mark(sx, sy);
301
302 if ( mar != -1 ) {
303 myMoveEvent(e);
304 return;
305 }
306
307
308 if (stonefield.remove(sx, sy)) {
309 history.append(new QPoint(sx, sy));
310
311 emit s_remove(sx, sy);
312
313 stonefield.mark(sx,sy);
314 emit s_marked(stonefield.getMarked());
315 modified= true;
316
317 emit s_score(stonefield.getScore());
318 if (stonefield.isGameover()) emit s_gameover();
319 }
320}
321
322void
323StoneWidget::myMoveEvent ( QMouseEvent *e)
324{
325 return;
326
327 if (stonefield.isGameover()) {
328 stonefield.unmark();
329 emit s_marked(0);
330 return;
331 }
332
333 int x=e->pos().x();
334 int y=e->pos().y();
335 if (x<0||y<0||x>=field_width||y>=field_height) return;
336
337 int marked=stonefield.mark(x/stone_width,y/stone_height);
338 if (marked>=0) {
339 emit s_marked(marked);
340 slice=0;
341 }
342}
343
344
345
346
347
348
349
350
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 @@
1/* Yo Emacs, this is -*- C++ -*- */
2/*
3 * ksame 0.4 - simple Game
4 * Copyright (C) 1997,1998 Marcus Kreutzberger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#ifndef _STONEWIDGET
23#define _STONEWIDGET
24
25#include <qpixmap.h>
26#include <qwidget.h>
27
28#include <qpe/config.h>
29
30#include "StoneField.h"
31
32struct StoneSlice;
33
34class StoneWidget : public QWidget {
35 Q_OBJECT
36
37 int modified;
38 // int marked; // # of marked stones
39
40 int stones_x, stones_y;
41 int sizex, sizey;
42 int field_width, field_height;
43
44 QList<QPoint> history;
45 StoneField stonefield;
46
47 // picture number of stonemovie
48 int slice;
49
50 StoneSlice **map;
51
52public:
53 StoneWidget( QWidget *parent=0, int x=10,int y=10);
54 ~StoneWidget();
55
56 unsigned int board();
57 int score();
58 int marked();
59 QSize size();
60 int colors();
61 virtual QSize sizeHint() const;
62
63 bool undoPossible() const;
64
65 void newGame(unsigned int board, int colors);
66 void reset();
67 void unmark();
68 int undo(int count=1);
69
70 // test for game end
71 bool isGameover();
72 // if isGameover(): finished with bonus?
73 bool hasBonus();
74 // test for unchanged start position
75 bool isOriginalBoard();
76
77 virtual void readProperties(Config *conf);
78 virtual void saveProperties(Config *conf);
79
80protected:
81
82 void timerEvent( QTimerEvent *e );
83 void paintEvent( QPaintEvent *e );
84 void mousePressEvent ( QMouseEvent *e);
85 void myMoveEvent ( QMouseEvent *e);
86
87 // properties of the stone picture
88 int stone_width,stone_height; // size of one stone
89 int maxcolors; // number of different stones (Y direction)
90 int maxslices; // number of pictures per movie (X direction)
91
92signals:
93 // A new game begins
94 void s_newgame();
95
96 void s_colors(int colors);
97 void s_board(int board);
98 void s_score(int score);
99 void s_marked(int m);
100
101 void s_gameover();
102
103 // The stone (x,y) was clicked(removed),
104 // all neighbor stones disappear without further signals
105 void s_remove(int x,int y);
106
107 void s_sizechanged();
108};
109
110#endif
111
112
113
114
115
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 @@
1/* Yo Emacs, this is -*- C++ -*- */
2/*
3 * ksame 0.4 - simple Game
4 * Copyright (C) 1997,1998 Marcus Kreutzberger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#include <stdio.h>
23
24#include <qwidget.h>
25#include <qpushbutton.h>
26#include <qpixmap.h>
27#include <qvbox.h>
28#include <qpopupmenu.h>
29#include <qtoolbar.h>
30#include <qmenubar.h>
31
32#include <qapplication.h>
33#include <qaction.h>
34#include <qmessagebox.h>
35
36#include <qpe/resource.h>
37#include <opie/oapplicationfactory.h>
38#include <kapplication.h>
39
40
41#include "ZSameWidget.h"
42#include "StoneWidget.h"
43#include "version.h"
44
45static int default_colors=3;
46
47#define i18n tr
48
49
50OPIE_EXPORT_APP( OApplicationFactory<ZSameWidget> )
51
52
53
54ZSameWidget::ZSameWidget( QWidget* parent, const char* name, WFlags fl )
55 : QMainWindow( parent, name, fl )
56{
57 setCaption(tr("ZSame"));
58
59 setToolBarsMovable( false );
60 QToolBar* con = new QToolBar( this );
61 con->setHorizontalStretchable( true );
62 QMenuBar* mb = new QMenuBar( con );
63 QToolBar* tb = new QToolBar( this );
64
65 QPopupMenu* fileMenu = new QPopupMenu( this );
66
67 QAction* a = new QAction(tr("New Game"), Resource::loadIconSet("new") ,
68 QString::null, 0, this, "new_icon");
69 a->addTo( fileMenu );
70 a->addTo( tb );
71 connect(a, SIGNAL(activated()), this, SLOT(m_new()));
72
73 a = new QAction(tr("Restart This Board"), Resource::loadIconSet("redo"),
74 QString::null, 0, this, "restart_board" );
75 a->addTo( fileMenu );
76 connect( a, SIGNAL(activated()), this, SLOT(m_restart()));
77 restart = a;
78
79 a = new QAction( tr("Undo"), Resource::loadIconSet("undo"),
80 QString::null, 0, this, "undo_action" );
81 a->addTo( fileMenu );
82 a->addTo( tb );
83 connect( a, SIGNAL(activated()), this, SLOT(m_undo()));
84
85 a = new QAction(tr("Quit"), Resource::loadIconSet("quit_icon"),
86 QString::null, 0, this, "quit_action");
87 a->addTo( fileMenu );
88 a->addTo( tb );
89 connect(a, SIGNAL(activated()), this, SLOT(m_quit()));
90
91 mb->insertItem(tr("Game" ), fileMenu );
92
93 int foo[2];
94 desktop_widget(foo);
95 stone = new StoneWidget(this,foo[0],foo[1]);
96
97 connect( stone, SIGNAL(s_gameover()), this, SLOT(gameover()));
98
99 connect( stone, SIGNAL(s_colors(int)), this, SLOT(setColors(int)));
100 connect( stone, SIGNAL(s_board(int)), this, SLOT(setBoard(int)));
101 connect( stone, SIGNAL(s_marked(int)), this, SLOT(setMarked(int)));
102 connect( stone, SIGNAL(s_score(int)), this, SLOT(setScore(int)));
103 connect( stone, SIGNAL(s_remove(int,int)), this, SLOT(stonesRemoved(int,int)));
104
105 connect(stone, SIGNAL(s_sizechanged()), this, SLOT(sizeChanged()));
106
107 sizeChanged();
108 setCentralWidget(stone);
109
110
111 setScore(0);
112}
113
114ZSameWidget::~ZSameWidget() {
115
116}
117
118void ZSameWidget::readProperties(Config *conf) {
119/*
120 Q_ASSERT(conf);
121 stone->readProperties(conf);
122*/
123}
124
125void ZSameWidget::saveProperties(Config *conf) {
126/*
127 Q_ASSERT(conf);
128 stone->saveProperties(conf);
129 conf->sync();
130*/
131}
132
133void ZSameWidget::sizeChanged() {
134 //stone->setFixedSize(stone->sizeHint());
135}
136
137void ZSameWidget::newGame(unsigned int board,int colors) {
138 while (board>=1000000) board-=1000000;
139 // kdDebug() << "newgame board " << board << " colors " << colors << endl;
140 stone->newGame(board,colors);
141 setScore(0);
142}
143
144bool ZSameWidget::confirmAbort() {
145 return stone->isGameover() ||
146 stone->isOriginalBoard() ||
147 (QMessageBox::warning(this, i18n("Resign"), i18n("<qt>Do you want to resign?</qt>"),
148 QMessageBox::Yes,
149 QMessageBox::No|QMessageBox::Default|QMessageBox::Escape, 0) == QMessageBox::Yes );
150}
151
152void ZSameWidget::m_new() {
153 if (confirmAbort())
154 newGame(_random(),default_colors);
155
156}
157
158void ZSameWidget::m_restart() {
159 if (confirmAbort())
160 newGame(stone->board(),default_colors);
161}
162
163void ZSameWidget::m_load() {
164// kdDebug() << "menu load not supported" << endl;
165}
166
167void ZSameWidget::m_save() {
168// kdDebug() << "menu save not supported" << endl;
169}
170
171void ZSameWidget::m_undo() {
172 //Q_ASSERT(stone);
173 stone->undo();
174}
175
176
177void ZSameWidget::m_showhs() {
178/* Q_ASSERT(stone);
179 stone->unmark();
180 KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score, this);
181 d.addField(Board, i18n("Board"), "Board");
182 d.exec();
183*/
184}
185
186void ZSameWidget::m_quit() {
187// Q_ASSERT(stone);
188 stone->unmark();
189 qApp->quit();
190// delete this;
191}
192
193void ZSameWidget::m_tglboard() {
194 //kdDebug() << "toggled" << endl;
195}
196
197
198void ZSameWidget::setColors(int colors) {
199 //status->changeItem(i18n("%1 Colors").arg(colors),1);
200}
201
202void ZSameWidget::setBoard(int board) {
203 //status->changeItem(i18n("Board: %1").arg(board, 6), 2);
204}
205
206void ZSameWidget::setMarked(int m) {
207// status->changeItem(i18n("Marked: %1").arg(m, 6),3);
208}
209
210void ZSameWidget::stonesRemoved(int,int) {
211 //KNotifyClient::event("stones removed",
212 // i18n("%1 stones removed.").arg(stone->marked()));
213}
214
215void ZSameWidget::setScore(int score) {
216// status->changeItem(i18n("Score: %1").arg(score, 6),4);
217// undo->setEnabled(stone->undoPossible());
218// restart->setEnabled(!stone->isOriginalBoard());
219}
220
221void ZSameWidget::gameover() {
222// kdDebug() << "GameOver" << endl;
223 if (stone->hasBonus()) {
224 QMessageBox::information(this,i18n("Game won"),
225 i18n("<qt>You even removed the last stone, great job! "
226 "This gave you a score of %1 in total.</qt>").arg(stone->score()));
227 } else {
228 QMessageBox::information(this,i18n("Game over"),
229 i18n("<qt>There are no more removeable stones. "
230 "You got a score of %1 in total.</qt>").arg(stone->score()));
231 }
232 stone->unmark();
233}
234
235void ZSameWidget::desktop_widget(int *f)const{
236
237 QWidget* wid = QApplication::desktop();
238 /* width > height landscape mode */
239 if ( wid->width() > wid->height() ) {
240 f[0]=15;
241 f[1]=9;
242 }
243 /* normal */
244 else{
245 f[0]=12;
246 f[1]=13;
247 }
248}
249
250
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 @@
1#ifndef ZSAME_WIDGET_H
2#define ZSAME_WIDGET_H
3
4#include "StoneWidget.h"
5#include <qmainwindow.h>
6
7class Config;
8class QAction;
9class ZSameWidget : public QMainWindow {
10 Q_OBJECT
11public:
12 static QString appName() { return QString::fromLatin1("zsame"); }
13 ZSameWidget(QWidget* parent, const char* name, WFlags fl );
14 ~ZSameWidget();
15
16private:
17 void desktop_widget(int *f)const;
18 StoneWidget *stone;
19 QAction *restart;
20 QAction *undo;
21
22 int multispin_item;
23
24protected:
25 void newGame( unsigned int board,int colors);
26
27 virtual void saveProperties(Config *conf);
28 virtual void readProperties(Config *conf);
29
30 bool confirmAbort();
31
32public slots:
33 void sizeChanged();
34
35/* File Menu */
36 void m_new();
37 void m_restart();
38 void m_load();
39 void m_save();
40 void m_showhs();
41 void m_quit();
42 void m_undo();
43
44/* Options Menu */
45 void m_tglboard();
46
47 void gameover();
48 void setColors(int colors);
49 void setBoard(int board);
50 void setScore(int score);
51 void setMarked(int m);
52 void stonesRemoved(int,int);
53};
54
55
56#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 @@
1 config ZSAME
2 boolean "opie-zsame (a SameGame clone)"
3 default "y"
4 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 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <time.h>
8
9static int _random() {
10 static int init = false;
11 if (!init) {
12 unsigned int seed;
13 init = true;
14 int fd = ::open("/dev/urandom", O_RDONLY);
15 if( fd<=0 || ::read(fd, &seed, sizeof(seed)) != sizeof(seed) ) {
16 srand(getpid());
17 seed = rand()+time(0);
18 }
19 if(fd>=0) close( fd );
20 srand(seed);
21 }
22 return rand();
23}
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 @@
1/*
2 This file is part of the KDE libraries
3 Copyright (c) 1999 Sean Harmer <sh@astro.keele.ac.uk>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include <qlist.h>
22#include <string.h>
23
24#include "kapplication.h"
25#include "krandomsequence.h"
26
27const int KRandomSequence::m_nShuffleTableSize = 32;
28
29//////////////////////////////////////////////////////////////////////////////
30 //Construction / Destruction
31//////////////////////////////////////////////////////////////////////////////
32
33KRandomSequence::KRandomSequence( long lngSeed1 )
34{
35 // Seed the generator
36 setSeed( lngSeed1 );
37
38
39 // Set the size of the shuffle table
40 m_ShuffleArray = new long [m_nShuffleTableSize];
41}
42
43KRandomSequence::~KRandomSequence()
44{
45 delete [] m_ShuffleArray;
46}
47
48KRandomSequence::KRandomSequence(const KRandomSequence &a)
49{
50 // Set the size of the shuffle table
51 m_ShuffleArray = new long [m_nShuffleTableSize];
52 *this = a;
53}
54
55KRandomSequence &
56KRandomSequence::operator=(const KRandomSequence &a)
57{
58 m_lngSeed1 = a.m_lngSeed1;
59 m_lngSeed2 = a.m_lngSeed2;
60 m_lngShufflePos = a.m_lngShufflePos;
61 memcpy(m_ShuffleArray, a.m_ShuffleArray, sizeof(long)*m_nShuffleTableSize);
62 return *this;
63}
64
65
66//////////////////////////////////////////////////////////////////////////////
67 //Member Functions
68//////////////////////////////////////////////////////////////////////////////
69
70void KRandomSequence::setSeed( long lngSeed1 )
71{
72 // Convert the positive seed number to a negative one so that the Draw()
73 // function can intialise itself the first time it is called. We just have
74 // to make sure that the seed used != 0 as zero perpetuates itself in a
75 // sequence of random numbers.
76 if ( lngSeed1 < 0 )
77 {
78 m_lngSeed1 = -1;
79 }
80 else if (lngSeed1 == 0)
81 {
82 m_lngSeed1 = -((_random() & ~1)+1);
83 }
84 else
85 {
86 m_lngSeed1 = -lngSeed1;
87 }
88}
89
90static const long sMod1 = 2147483563;
91static const long sMod2 = 2147483399;
92
93void KRandomSequence::Draw()
94{
95 static const long sMM1 = sMod1 - 1;
96 static const long sA1 = 40014;
97 static const long sA2 = 40692;
98 static const long sQ1 = 53668;
99 static const long sQ2 = 52774;
100 static const long sR1 = 12211;
101 static const long sR2 = 3791;
102 static const long sDiv = 1 + sMM1 / m_nShuffleTableSize;
103
104 // Long period (>2 * 10^18) random number generator of L'Ecuyer with
105 // Bayes-Durham shuffle and added safeguards. Returns a uniform random
106 // deviate between 0.0 and 1.0 (exclusive of the endpoint values). Call
107 // with a negative number to initialize; thereafter, do not alter idum
108 // between successive deviates in a sequence. RNMX should approximate
109 // the largest floating point value that is less than 1.
110
111 int j; // Index for the shuffle table
112 long k;
113
114 // Initialise
115 if ( m_lngSeed1 <= 0 )
116 {
117 m_lngSeed2 = m_lngSeed1;
118
119 // Load the shuffle table after 8 warm-ups
120 for ( j = m_nShuffleTableSize + 7; j >= 0; j-- )
121 {
122 k = m_lngSeed1 / sQ1;
123 m_lngSeed1 = sA1 * ( m_lngSeed1 - k*sQ1) - k*sR1;
124 if ( m_lngSeed1 < 0 )
125 {
126 m_lngSeed1 += sMod1;
127 }
128
129 if ( j < m_nShuffleTableSize )
130 {
131 m_ShuffleArray[j] = m_lngSeed1;
132 }
133 }
134
135 m_lngShufflePos = m_ShuffleArray[0];
136 }
137
138 // Start here when not initializing
139
140 // Compute m_lngSeed1 = ( lngIA1*m_lngSeed1 ) % lngIM1 without overflows
141 // by Schrage's method
142 k = m_lngSeed1 / sQ1;
143 m_lngSeed1 = sA1 * ( m_lngSeed1 - k*sQ1 ) - k*sR1;
144 if ( m_lngSeed1 < 0 )
145 {
146 m_lngSeed1 += sMod1;
147 }
148
149 // Compute m_lngSeed2 = ( lngIA2*m_lngSeed2 ) % lngIM2 without overflows
150 // by Schrage's method
151 k = m_lngSeed2 / sQ2;
152 m_lngSeed2 = sA2 * ( m_lngSeed2 - k*sQ2 ) - k*sR2;
153 if ( m_lngSeed2 < 0 )
154 {
155 m_lngSeed2 += sMod2;
156 }
157
158 j = m_lngShufflePos / sDiv;
159 m_lngShufflePos = m_ShuffleArray[j] - m_lngSeed2;
160 m_ShuffleArray[j] = m_lngSeed1;
161
162 if ( m_lngShufflePos < 1 )
163 {
164 m_lngShufflePos += sMM1;
165 }
166}
167
168void
169KRandomSequence::modulate(int i)
170{
171 m_lngSeed2 -= i;
172 if ( m_lngSeed2 < 0 )
173 {
174 m_lngShufflePos += sMod2;
175 }
176 Draw();
177 m_lngSeed1 -= i;
178 if ( m_lngSeed1 < 0 )
179 {
180 m_lngSeed1 += sMod1;
181 }
182 Draw();
183}
184
185double
186KRandomSequence::getDouble()
187{
188 static const double finalAmp = 1.0 / double( sMod1 );
189 static const double epsilon = 1.2E-7;
190 static const double maxRand = 1.0 - epsilon;
191 double temp;
192 Draw();
193 // Return a value that is not one of the endpoints
194 if ( ( temp = finalAmp * m_lngShufflePos ) > maxRand )
195 {
196 // We don't want to return 1.0
197 return maxRand;
198 }
199 else
200 {
201 return temp;
202 }
203}
204
205unsigned long
206KRandomSequence::getLong(unsigned long max)
207{
208 Draw();
209
210 return max ? (((unsigned long) m_lngShufflePos) % max) : 0;
211}
212
213bool
214KRandomSequence::getBool()
215{
216 Draw();
217
218 return (((unsigned long) m_lngShufflePos) & 1);
219}
220
221class KRandomSequenceList : public QGList
222{
223 friend class KRandomSequence;
224public:
225 KRandomSequenceList() : QGList() { }
226 virtual void deleteItem( QCollection::Item ) {}
227};
228
229void
230KRandomSequence::randomize(QGList *_list)
231{
232 KRandomSequenceList *list = (KRandomSequenceList *)_list;
233 KRandomSequenceList l;
234 while(list->count())
235 l.append(list->takeFirst());
236
237 list->append(l.takeFirst()); // Start with 1
238 while(l.count())
239 list->insertAt(getLong(list->count()+1), l.takeFirst());
240}
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 @@
1/* This file is part of the KDE libraries
2 Copyright (c) 1999 Sean Harmer <sh@astro.keele.ac.uk>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18#ifndef K_RANDOM_SEQUENCE_H
19#define K_RANDOM_SEQUENCE_H
20
21class KRandomSequencePrivate;
22class QGList;
23/**
24 * A class to create a pseudo-random sequence
25 *
26 * Given a seed number, this class will produce a sequence of
27 * pseudo-random numbers. This would typically be used in
28 * applications like games.
29 *
30 * In general, you should instantiate a KRandomSequence object and
31 * pass along your seed number in the constructor. From then on,
32 * simply call getDouble or getLong to obtain the next
33 * number in the sequence.
34 *
35 * @author Sean Harmer <sh@astro.keele.ac.uk>
36 */
37class KRandomSequence
38{
39public:
40 /**
41 * Creates a pseudo-random sequence based on the seed lngSeed.
42 *
43 * A Pseudo-random sequence is different for each seed but can be
44 * reproduced by starting the sequence with the same seed.
45 *
46 * If you need a single value which needs to be unpredictable,
47 * you need to use kapp->random() instead.
48 *
49 * @param lngSeed Seed to initialize the sequence with.
50 * If lngSeed is 0, the sequence is initialized with a value from
51 * KApplication::random().
52 */
53 KRandomSequence( long lngSeed = 0 );
54
55 /**
56 * Standard destructor
57 */
58 virtual ~KRandomSequence();
59
60 /**
61 * Copy constructor
62 */
63 KRandomSequence(const KRandomSequence &a);
64
65 /**
66 * Assignment
67 */
68 KRandomSequence &operator=(const KRandomSequence &a);
69
70 /**
71 * Restart the sequence based on lngSeed.
72 * @param lngSeed Seed to initialize the sequence with.
73 * If lngSeed is 0, the sequence is initialized with a value from
74 * KApplication::random().
75 */
76 void setSeed( long lngSeed = 1 );
77
78 /**
79 * Get the next number from the pseudo-random sequence.
80 *
81 * @return a pseudo-random double value between [0,1[
82 */
83 double getDouble();
84
85 /**
86 * Get the next number from the pseudo-random sequence.
87 *
88 * @return a pseudo-random integer value between [0, max[
89 * with 0 <= max < 1.000.000
90 */
91 unsigned long getLong(unsigned long max);
92
93 /**
94 * Get a boolean from the pseudo-random sequence.
95 *
96 * @return a boolean which is either true or false
97 */
98 bool getBool();
99
100 /**
101 * Put a list in random order.
102 *
103 * @param list the list whose order will be modified
104 */
105 void randomize(QGList *list);
106
107 /**
108 * Modulate the random sequence.
109 *
110 * If S(i) is the sequence of numbers that will follow
111 * given the current state after calling modulate(i),
112 * then S(i) != S(j) for i != j and
113 * S(i) == S(j) for i == j.
114 *
115 * This can be useful in game situation where "undo" restores
116 * the state of the random sequence. If the game modulates the
117 * random sequence with the move chosen by the player, the
118 * random sequence will be identical whenever the player "redo"-s
119 * his or hers original move, but different when the player
120 * chooses another move.
121 *
122 * With this scenario "undo" can no longer be used to repeat a
123 * certain move over and over again until the computer reacts
124 * with a favorable response or to predict the response for a
125 * certain move based on the response to another move.
126 * @param i the sequence identified
127 */
128 void modulate(int i);
129
130private:
131 void Draw(); // Generate the random number
132 long m_lngSeed1;
133 long m_lngSeed2;
134 long m_lngShufflePos;
135
136 static const int m_nShuffleTableSize;
137 long *m_ShuffleArray;
138
139 KRandomSequencePrivate *d;
140};
141
142#endif
143
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 @@
1 #define KSAME_VERSION"0.5-Embedded"
2
3
4
5
6
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 @@
1CONFIG += qt warn_on quick-app
2
3
4TARGET = zsame
5
6HEADERS = StoneField.h StoneWidget.h ZSameWidget.h dropin/krandomsequence.h
7SOURCES = StoneField.cpp StoneWidget.cpp ZSameWidget.cpp dropin/krandomsequence.cpp
8
9
10INCLUDEPATH += $(OPIEDIR)/include dropin
11DEPENDPATH += $(OPIEDIR)/include
12
13
14# we now also include opie
15LIBS += -lqpe
16
17include ( $(OPIEDIR)/include.pro )