-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 @@ | |||
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 | |||
51 | static int default_colors=3; | ||
52 | |||
53 | #define Board KScoreDialog::Custom1 | ||
54 | |||
55 | KSameWidget::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 | |||
104 | KSameWidget::~KSameWidget() { | ||
105 | } | ||
106 | |||
107 | void KSameWidget::slotConfigureKeys() | ||
108 | { | ||
109 | KKeyDialog::configure( actionCollection(), this ); | ||
110 | } | ||
111 | |||
112 | void KSameWidget::readProperties(KConfig *conf) { | ||
113 | Q_ASSERT(conf); | ||
114 | stone->readProperties(conf); | ||
115 | } | ||
116 | |||
117 | void KSameWidget::saveProperties(KConfig *conf) { | ||
118 | Q_ASSERT(conf); | ||
119 | stone->saveProperties(conf); | ||
120 | conf->sync(); | ||
121 | } | ||
122 | |||
123 | void KSameWidget::sizeChanged() { | ||
124 | stone->setFixedSize(stone->sizeHint()); | ||
125 | } | ||
126 | |||
127 | void 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 | |||
134 | bool 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 | |||
141 | void 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 | |||
164 | void KSameWidget::m_restart() { | ||
165 | if (confirmAbort()) | ||
166 | newGame(stone->board(),default_colors); | ||
167 | } | ||
168 | |||
169 | void KSameWidget::m_load() { | ||
170 | kdDebug() << "menu load not supported" << endl; | ||
171 | } | ||
172 | |||
173 | void KSameWidget::m_save() { | ||
174 | kdDebug() << "menu save not supported" << endl; | ||
175 | } | ||
176 | |||
177 | void KSameWidget::m_undo() { | ||
178 | Q_ASSERT(stone); | ||
179 | stone->undo(); | ||
180 | } | ||
181 | |||
182 | |||
183 | void 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 | |||
191 | void KSameWidget::m_quit() { | ||
192 | Q_ASSERT(stone); | ||
193 | stone->unmark(); | ||
194 | kapp->quit(); | ||
195 | delete this; | ||
196 | } | ||
197 | |||
198 | void KSameWidget::m_tglboard() { | ||
199 | kdDebug() << "toggled" << endl; | ||
200 | } | ||
201 | |||
202 | |||
203 | void KSameWidget::setColors(int colors) { | ||
204 | status->changeItem(i18n("%1 Colors").arg(colors),1); | ||
205 | } | ||
206 | |||
207 | void KSameWidget::setBoard(int board) { | ||
208 | status->changeItem(i18n("Board: %1").arg(board, 6), 2); | ||
209 | } | ||
210 | |||
211 | void KSameWidget::setMarked(int m) { | ||
212 | status->changeItem(i18n("Marked: %1").arg(m, 6),3); | ||
213 | } | ||
214 | |||
215 | void KSameWidget::stonesRemoved(int,int) { | ||
216 | KNotifyClient::event("stones removed", | ||
217 | i18n("%1 stones removed.").arg(stone->marked())); | ||
218 | } | ||
219 | |||
220 | void 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 | |||
226 | void 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 | |||
28 | class KToggleAction; | ||
29 | |||
30 | class KSameWidget: public KMainWindow { | ||
31 | Q_OBJECT | ||
32 | public: | ||
33 | KSameWidget(); | ||
34 | ~KSameWidget(); | ||
35 | |||
36 | private: | ||
37 | StoneWidget *stone; | ||
38 | KStatusBar *status; | ||
39 | KToggleAction *random; | ||
40 | KAction *restart; | ||
41 | KAction *undo; | ||
42 | |||
43 | int multispin_item; | ||
44 | |||
45 | |||
46 | protected: | ||
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 | |||
24 | StoneFieldState::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 | |||
36 | StoneFieldState::~StoneFieldState() { | ||
37 | delete[] field; | ||
38 | } | ||
39 | |||
40 | void | ||
41 | StoneFieldState::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 | |||
55 | StoneField::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 | |||
73 | StoneField::~StoneField() { | ||
74 | delete[] field; | ||
75 | delete undolist; | ||
76 | // kdDebug() << "~StoneField\n" << endl; | ||
77 | } | ||
78 | |||
79 | int | ||
80 | StoneField::width() const { | ||
81 | return sizex; | ||
82 | } | ||
83 | |||
84 | int | ||
85 | StoneField::height() const { | ||
86 | return sizey; | ||
87 | } | ||
88 | |||
89 | void | ||
90 | StoneField::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 | |||
100 | void | ||
101 | StoneField::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 | |||
135 | int | ||
136 | StoneField::map(int x,int y) { | ||
137 | assert (!(x<0||y<0||x>=sizex||y>=sizey)); | ||
138 | return x+y*sizex; | ||
139 | } | ||
140 | |||
141 | int | ||
142 | StoneField::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 | |||
162 | void | ||
163 | StoneField::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 | |||
186 | void | ||
187 | StoneField::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 | |||
198 | int | ||
199 | StoneField::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 | |||
296 | bool StoneField::undoPossible() const { | ||
297 | return !(!undolist||undolist->isEmpty()); | ||
298 | } | ||
299 | |||
300 | int | ||
301 | StoneField::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 | |||
321 | bool | ||
322 | StoneField::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 | |||
351 | bool StoneField::gotBonus() const { | ||
352 | return m_gotBonus; | ||
353 | } | ||
354 | |||
355 | int | ||
356 | StoneField::getBoard() const { | ||
357 | return board; | ||
358 | } | ||
359 | |||
360 | int | ||
361 | StoneField::getScore() const { | ||
362 | return score; | ||
363 | } | ||
364 | |||
365 | int | ||
366 | StoneField::getColors() const { | ||
367 | return colors; | ||
368 | } | ||
369 | |||
370 | int | ||
371 | StoneField::getMarked() const { | ||
372 | return marked; | ||
373 | } | ||
374 | |||
375 | int | ||
376 | StoneField::getFieldSize() const { | ||
377 | return maxstone; | ||
378 | } | ||
379 | |||
380 | struct Stone * | ||
381 | StoneField::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 | |||
28 | struct Stone { | ||
29 | unsigned char color; | ||
30 | bool changed; | ||
31 | bool marked; | ||
32 | }; | ||
33 | |||
34 | class StoneField; | ||
35 | class StoneWidget; | ||
36 | |||
37 | class StoneFieldState { | ||
38 | private: | ||
39 | unsigned char *field; | ||
40 | |||
41 | int colors; | ||
42 | unsigned int board; | ||
43 | unsigned int score; | ||
44 | int gameover; | ||
45 | |||
46 | public: | ||
47 | StoneFieldState(const StoneField &stonefield); | ||
48 | ~StoneFieldState(); | ||
49 | void restore(StoneField &stonefield) const; | ||
50 | }; | ||
51 | |||
52 | |||
53 | class StoneField { | ||
54 | friend class StoneFieldState; | ||
55 | friend class StoneWidget; | ||
56 | private: | ||
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; | ||
73 | public: | ||
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 | |||
102 | protected: | ||
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 | |||
40 | struct StoneSlice { | ||
41 | QPixmap stone; | ||
42 | }; | ||
43 | |||
44 | |||
45 | StoneWidget::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 | |||
95 | StoneWidget::~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 | |||
105 | unsigned int | ||
106 | StoneWidget::board() { | ||
107 | return stonefield.getBoard(); | ||
108 | } | ||
109 | |||
110 | int | ||
111 | StoneWidget::score() { | ||
112 | return stonefield.getScore(); | ||
113 | } | ||
114 | |||
115 | int | ||
116 | StoneWidget::marked() { | ||
117 | return stonefield.getMarked(); | ||
118 | } | ||
119 | |||
120 | QSize | ||
121 | StoneWidget::size() { | ||
122 | return QSize(sizex,sizey); | ||
123 | } | ||
124 | |||
125 | int | ||
126 | StoneWidget::colors() { | ||
127 | return stonefield.getColors(); | ||
128 | } | ||
129 | |||
130 | QSize | ||
131 | StoneWidget::sizeHint () const { | ||
132 | return QSize(field_width,field_height); | ||
133 | } | ||
134 | |||
135 | void | ||
136 | StoneWidget::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 | |||
145 | void | ||
146 | StoneWidget::reset() { | ||
147 | stonefield.reset(); | ||
148 | history.clear(); | ||
149 | emit s_newgame(); | ||
150 | } | ||
151 | |||
152 | void | ||
153 | StoneWidget::unmark() { | ||
154 | stonefield.unmark(); | ||
155 | emit s_marked(0); | ||
156 | } | ||
157 | |||
158 | bool StoneWidget::undoPossible() const { | ||
159 | if (stonefield.isGameover()) return false; | ||
160 | return stonefield.undoPossible(); | ||
161 | } | ||
162 | |||
163 | int | ||
164 | StoneWidget::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 | |||
185 | bool StoneWidget::isGameover() { | ||
186 | return stonefield.isGameover(); | ||
187 | } | ||
188 | |||
189 | bool StoneWidget::hasBonus() { | ||
190 | return stonefield.gotBonus(); // don't ask me why the names differ... ;-| [hlm] | ||
191 | } | ||
192 | |||
193 | bool StoneWidget::isOriginalBoard() { | ||
194 | return !modified; | ||
195 | } | ||
196 | |||
197 | void 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 | |||
222 | void | ||
223 | StoneWidget::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 | |||
241 | void | ||
242 | StoneWidget::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 | |||
252 | void | ||
253 | StoneWidget::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 | |||
288 | void | ||
289 | StoneWidget::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 | |||
322 | void | ||
323 | StoneWidget::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 | |||
32 | struct StoneSlice; | ||
33 | |||
34 | class 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 | |||
52 | public: | ||
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 | |||
80 | protected: | ||
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 | |||
92 | signals: | ||
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 | |||
45 | static int default_colors=3; | ||
46 | |||
47 | #define i18n tr | ||
48 | |||
49 | |||
50 | OPIE_EXPORT_APP( OApplicationFactory<ZSameWidget> ) | ||
51 | |||
52 | |||
53 | |||
54 | ZSameWidget::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 | |||
114 | ZSameWidget::~ZSameWidget() { | ||
115 | |||
116 | } | ||
117 | |||
118 | void ZSameWidget::readProperties(Config *conf) { | ||
119 | /* | ||
120 | Q_ASSERT(conf); | ||
121 | stone->readProperties(conf); | ||
122 | */ | ||
123 | } | ||
124 | |||
125 | void ZSameWidget::saveProperties(Config *conf) { | ||
126 | /* | ||
127 | Q_ASSERT(conf); | ||
128 | stone->saveProperties(conf); | ||
129 | conf->sync(); | ||
130 | */ | ||
131 | } | ||
132 | |||
133 | void ZSameWidget::sizeChanged() { | ||
134 | //stone->setFixedSize(stone->sizeHint()); | ||
135 | } | ||
136 | |||
137 | void 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 | |||
144 | bool 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 | |||
152 | void ZSameWidget::m_new() { | ||
153 | if (confirmAbort()) | ||
154 | newGame(_random(),default_colors); | ||
155 | |||
156 | } | ||
157 | |||
158 | void ZSameWidget::m_restart() { | ||
159 | if (confirmAbort()) | ||
160 | newGame(stone->board(),default_colors); | ||
161 | } | ||
162 | |||
163 | void ZSameWidget::m_load() { | ||
164 | // kdDebug() << "menu load not supported" << endl; | ||
165 | } | ||
166 | |||
167 | void ZSameWidget::m_save() { | ||
168 | // kdDebug() << "menu save not supported" << endl; | ||
169 | } | ||
170 | |||
171 | void ZSameWidget::m_undo() { | ||
172 | //Q_ASSERT(stone); | ||
173 | stone->undo(); | ||
174 | } | ||
175 | |||
176 | |||
177 | void 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 | |||
186 | void ZSameWidget::m_quit() { | ||
187 | // Q_ASSERT(stone); | ||
188 | stone->unmark(); | ||
189 | qApp->quit(); | ||
190 | // delete this; | ||
191 | } | ||
192 | |||
193 | void ZSameWidget::m_tglboard() { | ||
194 | //kdDebug() << "toggled" << endl; | ||
195 | } | ||
196 | |||
197 | |||
198 | void ZSameWidget::setColors(int colors) { | ||
199 | //status->changeItem(i18n("%1 Colors").arg(colors),1); | ||
200 | } | ||
201 | |||
202 | void ZSameWidget::setBoard(int board) { | ||
203 | //status->changeItem(i18n("Board: %1").arg(board, 6), 2); | ||
204 | } | ||
205 | |||
206 | void ZSameWidget::setMarked(int m) { | ||
207 | // status->changeItem(i18n("Marked: %1").arg(m, 6),3); | ||
208 | } | ||
209 | |||
210 | void ZSameWidget::stonesRemoved(int,int) { | ||
211 | //KNotifyClient::event("stones removed", | ||
212 | // i18n("%1 stones removed.").arg(stone->marked())); | ||
213 | } | ||
214 | |||
215 | void 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 | |||
221 | void 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 | |||
235 | void 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 | |||
7 | class Config; | ||
8 | class QAction; | ||
9 | class ZSameWidget : public QMainWindow { | ||
10 | Q_OBJECT | ||
11 | public: | ||
12 | static QString appName() { return QString::fromLatin1("zsame"); } | ||
13 | ZSameWidget(QWidget* parent, const char* name, WFlags fl ); | ||
14 | ~ZSameWidget(); | ||
15 | |||
16 | private: | ||
17 | void desktop_widget(int *f)const; | ||
18 | StoneWidget *stone; | ||
19 | QAction *restart; | ||
20 | QAction *undo; | ||
21 | |||
22 | int multispin_item; | ||
23 | |||
24 | protected: | ||
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 | |||
32 | public 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 | |||
9 | static 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 | |||
27 | const int KRandomSequence::m_nShuffleTableSize = 32; | ||
28 | |||
29 | ////////////////////////////////////////////////////////////////////////////// | ||
30 | //Construction / Destruction | ||
31 | ////////////////////////////////////////////////////////////////////////////// | ||
32 | |||
33 | KRandomSequence::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 | |||
43 | KRandomSequence::~KRandomSequence() | ||
44 | { | ||
45 | delete [] m_ShuffleArray; | ||
46 | } | ||
47 | |||
48 | KRandomSequence::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 | |||
55 | KRandomSequence & | ||
56 | KRandomSequence::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 | |||
70 | void 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 | |||
90 | static const long sMod1 = 2147483563; | ||
91 | static const long sMod2 = 2147483399; | ||
92 | |||
93 | void 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 | |||
168 | void | ||
169 | KRandomSequence::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 | |||
185 | double | ||
186 | KRandomSequence::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 | |||
205 | unsigned long | ||
206 | KRandomSequence::getLong(unsigned long max) | ||
207 | { | ||
208 | Draw(); | ||
209 | |||
210 | return max ? (((unsigned long) m_lngShufflePos) % max) : 0; | ||
211 | } | ||
212 | |||
213 | bool | ||
214 | KRandomSequence::getBool() | ||
215 | { | ||
216 | Draw(); | ||
217 | |||
218 | return (((unsigned long) m_lngShufflePos) & 1); | ||
219 | } | ||
220 | |||
221 | class KRandomSequenceList : public QGList | ||
222 | { | ||
223 | friend class KRandomSequence; | ||
224 | public: | ||
225 | KRandomSequenceList() : QGList() { } | ||
226 | virtual void deleteItem( QCollection::Item ) {} | ||
227 | }; | ||
228 | |||
229 | void | ||
230 | KRandomSequence::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 | |||
21 | class KRandomSequencePrivate; | ||
22 | class 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 | */ | ||
37 | class KRandomSequence | ||
38 | { | ||
39 | public: | ||
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 | |||
130 | private: | ||
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 @@ | |||
1 | CONFIG += qt warn_on quick-app | ||
2 | |||
3 | |||
4 | TARGET = zsame | ||
5 | |||
6 | HEADERS = StoneField.h StoneWidget.h ZSameWidget.h dropin/krandomsequence.h | ||
7 | SOURCES = StoneField.cpp StoneWidget.cpp ZSameWidget.cpp dropin/krandomsequence.cpp | ||
8 | |||
9 | |||
10 | INCLUDEPATH += $(OPIEDIR)/include dropin | ||
11 | DEPENDPATH += $(OPIEDIR)/include | ||
12 | |||
13 | |||
14 | # we now also include opie | ||
15 | LIBS += -lqpe | ||
16 | |||
17 | include ( $(OPIEDIR)/include.pro ) | ||