author | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
commit | 15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff) | |
tree | c2fa0399a2c47fda8e2cd0092c73a809d17f68eb /noncore/games/mindbreaker | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
-rw-r--r-- | noncore/games/mindbreaker/.cvsignore | 4 | ||||
-rw-r--r-- | noncore/games/mindbreaker/Makefile.in | 117 | ||||
-rw-r--r-- | noncore/games/mindbreaker/main.cpp | 35 | ||||
-rw-r--r-- | noncore/games/mindbreaker/mindbreaker.cpp | 818 | ||||
-rw-r--r-- | noncore/games/mindbreaker/mindbreaker.h | 122 | ||||
-rw-r--r-- | noncore/games/mindbreaker/mindbreaker.pro | 12 | ||||
-rw-r--r-- | noncore/games/mindbreaker/qpe-mindbreaker.control | 9 |
7 files changed, 1117 insertions, 0 deletions
diff --git a/noncore/games/mindbreaker/.cvsignore b/noncore/games/mindbreaker/.cvsignore new file mode 100644 index 0000000..415ec09 --- a/dev/null +++ b/noncore/games/mindbreaker/.cvsignore | |||
@@ -0,0 +1,4 @@ | |||
1 | Makefile | ||
2 | moc_* | ||
3 | helpdialog.cpp | ||
4 | helpdialog.h | ||
diff --git a/noncore/games/mindbreaker/Makefile.in b/noncore/games/mindbreaker/Makefile.in new file mode 100644 index 0000000..88f6fb1 --- a/dev/null +++ b/noncore/games/mindbreaker/Makefile.in | |||
@@ -0,0 +1,117 @@ | |||
1 | ############################################################################# | ||
2 | |||
3 | ####### Compiler, tools and options | ||
4 | |||
5 | CXX =$(SYSCONF_CXX) $(QT_CXX_MT) | ||
6 | CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) | ||
7 | CC =$(SYSCONF_CC) $(QT_C_MT) | ||
8 | CFLAGS =$(SYSCONF_CFLAGS) | ||
9 | INCPATH =-I$(QPEDIR)/include | ||
10 | LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) | ||
11 | LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP) | ||
12 | MOC =$(SYSCONF_MOC) | ||
13 | UIC =$(SYSCONF_UIC) | ||
14 | |||
15 | ####### Target | ||
16 | |||
17 | DESTDIR = $(QPEDIR)/bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= mindbreaker | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =mindbreaker.h | ||
27 | SOURCES =main.cpp \ | ||
28 | mindbreaker.cpp | ||
29 | OBJECTS =main.o \ | ||
30 | mindbreaker.o | ||
31 | INTERFACES = | ||
32 | UICDECLS = | ||
33 | UICIMPLS = | ||
34 | SRCMOC =moc_mindbreaker.cpp | ||
35 | OBJMOC =moc_mindbreaker.o | ||
36 | |||
37 | |||
38 | ####### Implicit rules | ||
39 | |||
40 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
41 | |||
42 | .cpp.o: | ||
43 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
44 | |||
45 | .cxx.o: | ||
46 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
47 | |||
48 | .cc.o: | ||
49 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
50 | |||
51 | .C.o: | ||
52 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
53 | |||
54 | .c.o: | ||
55 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
56 | |||
57 | ####### Build rules | ||
58 | |||
59 | |||
60 | all: $(DESTDIR)$(TARGET) | ||
61 | |||
62 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
63 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
64 | |||
65 | moc: $(SRCMOC) | ||
66 | |||
67 | tmake: | ||
68 | tmake mindbreaker.pro | ||
69 | |||
70 | clean: | ||
71 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
72 | -rm -f *~ core | ||
73 | -rm -f allmoc.cpp | ||
74 | |||
75 | ####### Extension Modules | ||
76 | |||
77 | listpromodules: | ||
78 | @echo | ||
79 | |||
80 | listallmodules: | ||
81 | @echo | ||
82 | |||
83 | listaddonpromodules: | ||
84 | @echo | ||
85 | |||
86 | listaddonentmodules: | ||
87 | @echo | ||
88 | |||
89 | |||
90 | REQUIRES= | ||
91 | |||
92 | ####### Sub-libraries | ||
93 | |||
94 | |||
95 | ###### Combined headers | ||
96 | |||
97 | |||
98 | |||
99 | ####### Compile | ||
100 | |||
101 | main.o: main.cpp \ | ||
102 | mindbreaker.h \ | ||
103 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
104 | |||
105 | mindbreaker.o: mindbreaker.cpp \ | ||
106 | mindbreaker.h \ | ||
107 | $(QPEDIR)/include/qpe/resource.h \ | ||
108 | $(QPEDIR)/include/qpe/config.h \ | ||
109 | $(QPEDIR)/include/qpe/qpetoolbar.h | ||
110 | |||
111 | moc_mindbreaker.o: moc_mindbreaker.cpp \ | ||
112 | mindbreaker.h | ||
113 | |||
114 | moc_mindbreaker.cpp: mindbreaker.h | ||
115 | $(MOC) mindbreaker.h -o moc_mindbreaker.cpp | ||
116 | |||
117 | |||
diff --git a/noncore/games/mindbreaker/main.cpp b/noncore/games/mindbreaker/main.cpp new file mode 100644 index 0000000..8ba0fde --- a/dev/null +++ b/noncore/games/mindbreaker/main.cpp | |||
@@ -0,0 +1,35 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "mindbreaker.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | int main( int argc, char **argv ) | ||
26 | { | ||
27 | QPEApplication a( argc, argv ); | ||
28 | |||
29 | MindBreaker w(0, "new window"); | ||
30 | w.setCaption("Mind Breaker"); | ||
31 | QPEApplication::setInputMethodHint( &w, QPEApplication::AlwaysOff ); | ||
32 | a.showMainWidget(&w); | ||
33 | |||
34 | return a.exec(); | ||
35 | } | ||
diff --git a/noncore/games/mindbreaker/mindbreaker.cpp b/noncore/games/mindbreaker/mindbreaker.cpp new file mode 100644 index 0000000..b0e4d88 --- a/dev/null +++ b/noncore/games/mindbreaker/mindbreaker.cpp | |||
@@ -0,0 +1,818 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "mindbreaker.h" | ||
22 | |||
23 | #include <qpe/resource.h> | ||
24 | #include <qpe/config.h> | ||
25 | |||
26 | #include <qpainter.h> | ||
27 | #include <qpixmap.h> | ||
28 | #include <qpe/qpetoolbar.h> | ||
29 | #include <qtoolbutton.h> | ||
30 | #include <qpushbutton.h> | ||
31 | #include <qmessagebox.h> | ||
32 | #include <qlabel.h> | ||
33 | #include <qstyle.h> | ||
34 | |||
35 | #include <stdlib.h> | ||
36 | #include <sys/time.h> | ||
37 | #include <unistd.h> | ||
38 | |||
39 | static int pegRTTI = 3393393; | ||
40 | |||
41 | /* helper class, */ | ||
42 | class Peg : public QCanvasRectangle | ||
43 | { | ||
44 | public: | ||
45 | Peg(QCanvas *canvas, int type, int go = -1, int pos = -1); | ||
46 | int rtti() const {return pegRTTI; } | ||
47 | void advance(int phase); | ||
48 | |||
49 | bool hit( const QPoint &) const; | ||
50 | |||
51 | /* a placed peg is one that has been set down on the board correctly and | ||
52 | should not be moved, only copied */ | ||
53 | bool placed() const; | ||
54 | void setPlaced(bool); | ||
55 | |||
56 | int pegGo() const; | ||
57 | int pegPos() const; | ||
58 | void setPegPos(int); | ||
59 | |||
60 | int type() const; | ||
61 | |||
62 | static void buildImages(); | ||
63 | static QImage imageForType(int t); | ||
64 | |||
65 | static int eggLevel; | ||
66 | |||
67 | protected: | ||
68 | void drawShape(QPainter &); | ||
69 | private: | ||
70 | static QVector<QImage> normalPegs; | ||
71 | static QVector<QImage> specialPegs; | ||
72 | |||
73 | bool isplaced; | ||
74 | int pegtype; | ||
75 | int peg_go; | ||
76 | int peg_pos; | ||
77 | |||
78 | int aniStep; | ||
79 | }; | ||
80 | |||
81 | int Peg::eggLevel = 0; | ||
82 | QVector<QImage> Peg::normalPegs; | ||
83 | QVector<QImage> Peg::specialPegs; | ||
84 | |||
85 | void Peg::buildImages() | ||
86 | { | ||
87 | |||
88 | QImage pegs = Resource::loadImage("mindbreaker/pegs"); | ||
89 | int x = 0; | ||
90 | int y = 0; | ||
91 | int i; | ||
92 | eggLevel = 0; | ||
93 | normalPegs.resize(10); | ||
94 | for (i = 0; i < 6; i++) { | ||
95 | normalPegs.insert(i, new QImage(pegs.copy(x, y, peg_size, peg_size))); | ||
96 | x += peg_size; | ||
97 | } | ||
98 | specialPegs.resize(5); | ||
99 | for (i = 0; i < 5; i++) { | ||
100 | specialPegs.insert(i, new QImage(pegs.copy(x,y,peg_size, peg_size))); | ||
101 | x += peg_size; | ||
102 | } | ||
103 | |||
104 | QImage image = Resource::loadImage("mindbreaker/mindbreaker"); | ||
105 | /* copy from master image to functional images */ | ||
106 | x = 0; | ||
107 | y = panel_height; | ||
108 | normalPegs.insert(8, | ||
109 | new QImage(image.copy(x, y, panel_width, panel_height))); | ||
110 | y += panel_height; | ||
111 | y += title_height; | ||
112 | normalPegs.insert(9, | ||
113 | new QImage(image.copy(x, y, title_width, title_height))); | ||
114 | y += title_height; | ||
115 | |||
116 | x = 6 * peg_size; | ||
117 | normalPegs.insert(6, | ||
118 | new QImage(image.copy(x, y, answerpeg_size, answerpeg_size))); | ||
119 | x += answerpeg_size; | ||
120 | normalPegs.insert(7, | ||
121 | new QImage(image.copy(x, y, answerpeg_size, answerpeg_size))); | ||
122 | } | ||
123 | |||
124 | QImage Peg::imageForType(int t) | ||
125 | { | ||
126 | if (eggLevel > t ) { | ||
127 | if( t < 5) { | ||
128 | return *specialPegs[t]; | ||
129 | } else { | ||
130 | return *normalPegs[rand() % 6]; | ||
131 | } | ||
132 | } | ||
133 | return *normalPegs[t]; | ||
134 | } | ||
135 | |||
136 | Peg::Peg(QCanvas *canvas , int t, int g = -1, int p = -1) | ||
137 | : QCanvasRectangle(canvas) | ||
138 | { | ||
139 | setSize(normalPegs[t]->width(), normalPegs[t]->height() ); | ||
140 | pegtype = t; | ||
141 | isplaced = FALSE; | ||
142 | peg_pos = p; | ||
143 | peg_go = g; | ||
144 | aniStep = rand() % 6; | ||
145 | setAnimated(TRUE); | ||
146 | } | ||
147 | |||
148 | void Peg::advance(int phase) { | ||
149 | if (phase == 0) | ||
150 | aniStep = (++aniStep) % 6; | ||
151 | else { | ||
152 | hide(); | ||
153 | show(); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | void Peg::drawShape(QPainter &p ) | ||
158 | { | ||
159 | if ((pegtype == 5) && eggLevel > 5) { | ||
160 | p.drawImage(x(), y(), *normalPegs[aniStep]); | ||
161 | } else | ||
162 | p.drawImage(x(), y(), imageForType(pegtype)); | ||
163 | } | ||
164 | |||
165 | bool Peg::hit( const QPoint &p ) const | ||
166 | { | ||
167 | int ix = p.x() - int(x()); | ||
168 | int iy = p.y() - int(y()); | ||
169 | if (!normalPegs[pegtype]->valid(ix, iy)) | ||
170 | return FALSE; | ||
171 | QRgb pixel = normalPegs[pegtype]->pixel(ix, iy); | ||
172 | return (qAlpha(pixel ) != 0); | ||
173 | } | ||
174 | |||
175 | inline bool Peg::placed() const | ||
176 | { | ||
177 | return isplaced; | ||
178 | } | ||
179 | |||
180 | inline int Peg::pegGo() const | ||
181 | { | ||
182 | return peg_go; | ||
183 | } | ||
184 | |||
185 | inline int Peg::pegPos() const | ||
186 | { | ||
187 | return peg_pos; | ||
188 | } | ||
189 | |||
190 | inline void Peg::setPegPos(int p) | ||
191 | { | ||
192 | peg_pos = p; | ||
193 | } | ||
194 | |||
195 | inline void Peg::setPlaced(bool p) | ||
196 | { | ||
197 | isplaced = p; | ||
198 | } | ||
199 | |||
200 | inline int Peg::type() const | ||
201 | { | ||
202 | return pegtype; | ||
203 | } | ||
204 | |||
205 | /* Load the main image, copy from it the pegs, the board, and the answer image | ||
206 | * and use these to create the tray, answer and board | ||
207 | */ | ||
208 | MindBreaker::MindBreaker( QWidget *parent=0, const char *name=0, int wFlags=0 ) | ||
209 | : QMainWindow(parent, name, wFlags), | ||
210 | canvas(board_height, board_width) | ||
211 | { | ||
212 | MindBreakerBoard *m = new MindBreakerBoard(canvas, this); | ||
213 | setCentralWidget(m); | ||
214 | |||
215 | setToolBarsMovable( FALSE ); | ||
216 | |||
217 | QPEToolBar *tb = new QPEToolBar(this); | ||
218 | tb->setHorizontalStretchable( TRUE ); | ||
219 | |||
220 | QPixmap newicon = Resource::loadPixmap("new"); | ||
221 | new QToolButton(newicon, tr("New Game"), 0, | ||
222 | m, SLOT(clear()), tb, "NewGame"); | ||
223 | |||
224 | score = new QToolButton(tb); | ||
225 | score->setText(""); | ||
226 | score->setMaximumHeight(20); | ||
227 | score->setUsesTextLabel(TRUE); | ||
228 | tb->setStretchableWidget(score); | ||
229 | |||
230 | connect(m, SIGNAL(scoreChanged(int, int)), this, SLOT(setScore(int, int))); | ||
231 | connect(score, SIGNAL(clicked()), m, SLOT(resetScore())); | ||
232 | |||
233 | int a, b; | ||
234 | m->getScore(&a, &b); | ||
235 | setScore(a,b); | ||
236 | } | ||
237 | |||
238 | void MindBreaker::setScore(int turns, int games) | ||
239 | { | ||
240 | double average; | ||
241 | double total_turns = turns; | ||
242 | double total_games = games; | ||
243 | |||
244 | if(total_games > 0) | ||
245 | average = total_turns / total_games; | ||
246 | else | ||
247 | average = 0.0; | ||
248 | |||
249 | score->setText(tr("win avg: %1 turns (%2 games)").arg(average).arg(games)); | ||
250 | } | ||
251 | |||
252 | |||
253 | MindBreakerBoard::MindBreakerBoard( QCanvas &c, QWidget *parent=0, | ||
254 | const char *name=0, int wFlags=0 ) | ||
255 | : QCanvasView(&c, parent, name, wFlags) | ||
256 | { | ||
257 | int i, x, y; | ||
258 | struct timeval tv; | ||
259 | |||
260 | current_go = 0; | ||
261 | gettimeofday(&tv, 0); | ||
262 | |||
263 | srand(tv.tv_usec); | ||
264 | |||
265 | canvas()->setAdvancePeriod(500); | ||
266 | |||
267 | QImage image = Resource::loadImage("mindbreaker/mindbreaker"); | ||
268 | |||
269 | /* copy from master image to functional images */ | ||
270 | x = 0; | ||
271 | y = 0; | ||
272 | panelImage = image.copy(x,y, panel_width, panel_height); | ||
273 | y += panel_height; | ||
274 | y += panel_height; | ||
275 | |||
276 | titleImage = image.copy(x, y, title_width, title_height); | ||
277 | |||
278 | Peg::buildImages(); // must be done BEFORE any pegs are made | ||
279 | |||
280 | current_highlight = new Peg(canvas(), 8); | ||
281 | current_highlight->setPlaced(TRUE); | ||
282 | current_highlight->setX(0); | ||
283 | current_highlight->setY(board_height - ((current_go + 1) * panel_height)); | ||
284 | current_highlight->setZ(0); | ||
285 | current_highlight->show(); | ||
286 | |||
287 | |||
288 | /* set up the game */ | ||
289 | Config c("MindBreaker", Config::User); | ||
290 | c.setGroup("Board"); | ||
291 | game_over = FALSE; | ||
292 | if (c.readNumEntry("Answer0") < 0) { | ||
293 | for (i = 0; i < 4; i++) { | ||
294 | answer[i] = rand() % 6; | ||
295 | current_guess[i] = 6; | ||
296 | } | ||
297 | total_turns = 0; | ||
298 | total_games = 0; | ||
299 | } else { | ||
300 | int j; | ||
301 | c.setGroup("Score"); | ||
302 | total_turns = c.readNumEntry("Turns"); | ||
303 | total_games = c.readNumEntry("Games"); | ||
304 | if(total_turns < 0) | ||
305 | total_turns = 0; | ||
306 | if(total_games < 0) | ||
307 | total_games = 0; | ||
308 | |||
309 | |||
310 | checkScores(); | ||
311 | c.setGroup("Board"); | ||
312 | for(i = 0; i < 4; i++) | ||
313 | answer[i] = c.readNumEntry(QString("Answer%1").arg(i)); | ||
314 | /* read, and parse past guesses */ | ||
315 | current_go = 0; | ||
316 | for(j=0; j < 9; j++) { | ||
317 | current_guess[0] = c.readNumEntry(QString("Go%1p0").arg(j)); | ||
318 | if (current_guess[0] < 0) | ||
319 | break; | ||
320 | placeGuessPeg(0, current_guess[0]); | ||
321 | current_guess[1] = c.readNumEntry(QString("Go%1p1").arg(j)); | ||
322 | placeGuessPeg(1, current_guess[1]); | ||
323 | current_guess[2] = c.readNumEntry(QString("Go%1p2").arg(j)); | ||
324 | placeGuessPeg(2, current_guess[2]); | ||
325 | current_guess[3] = c.readNumEntry(QString("Go%1p3").arg(j)); | ||
326 | placeGuessPeg(3, current_guess[3]); | ||
327 | checkGuess(); | ||
328 | } | ||
329 | for(i = 0; i < 4; i++) { | ||
330 | current_guess[i] = c.readNumEntry(QString("CurrentGo%1").arg(i)); | ||
331 | if (current_guess[i] != 6) | ||
332 | placeGuessPeg(i, current_guess[i]); | ||
333 | } | ||
334 | } | ||
335 | |||
336 | /* draw initial screen */ | ||
337 | drawBackground(); | ||
338 | canvas()->update(); | ||
339 | } | ||
340 | |||
341 | MindBreakerBoard::~MindBreakerBoard() | ||
342 | { | ||
343 | int i, j; | ||
344 | if (game_over) { | ||
345 | current_go = 0; | ||
346 | /* clear the answer, clear the guess */ | ||
347 | for (i = 0; i < 4; i++) { | ||
348 | answer[i] = rand() % 6; | ||
349 | current_guess[i] = 6; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | Config c("MindBreaker", Config::User); | ||
354 | c.setGroup("Board"); | ||
355 | c.clearGroup(); | ||
356 | /* write the board */ | ||
357 | for (i = 0; i < current_go; i++) { | ||
358 | for(j = 0; j < 4; j++) | ||
359 | c.writeEntry(tr("Go%1p%2").arg(i).arg(j), past_guesses[4*i+j]); | ||
360 | } | ||
361 | for(j = 0; j < 4; j++) | ||
362 | c.writeEntry(tr("CurrentGo%1").arg(j), current_guess[j]); | ||
363 | for(j = 0; j < 4; j++) | ||
364 | c.writeEntry(tr("Answer%1").arg(j), answer[j]); | ||
365 | |||
366 | c.setGroup("Score"); | ||
367 | /* write the score */ | ||
368 | |||
369 | c.writeEntry("Turns", total_turns); | ||
370 | c.writeEntry("Games", total_games); | ||
371 | } | ||
372 | |||
373 | void MindBreakerBoard::getScore(int *a, int *b) | ||
374 | { | ||
375 | *a = total_turns; | ||
376 | *b = total_games; | ||
377 | return; | ||
378 | } | ||
379 | |||
380 | void MindBreakerBoard::placeGuessPeg(int pos, int pegId) | ||
381 | { | ||
382 | int x = first_peg_x_diff + (pos * peg_spacing); | ||
383 | int y = board_height - ((current_go + 1) * panel_height) | ||
384 | + first_peg_y_diff; | ||
385 | |||
386 | Peg *peg = new Peg(canvas(), pegId, current_go, pos); | ||
387 | peg->setPegPos(pos); | ||
388 | peg->setPlaced(TRUE); | ||
389 | peg->setX(x); | ||
390 | peg->setY(y); | ||
391 | peg->setZ(2); | ||
392 | peg->show(); | ||
393 | } | ||
394 | |||
395 | void MindBreakerBoard::drawBackground() | ||
396 | { | ||
397 | int i, j, x, y, x_gap, y_gap; | ||
398 | QPixmap background = QPixmap(canvas()->width(), canvas()->height()); | ||
399 | |||
400 | QPainter painter(&background); | ||
401 | |||
402 | painter.fillRect(0, 0, canvas()->width(), canvas()->height(), QColor(0,0,0)); | ||
403 | /* very first thing is to draw the bins, as everything else needs | ||
404 | * to be drawn over them */ | ||
405 | |||
406 | QPen pen(QColor(85, 45, 27), 4); | ||
407 | painter.setPen(pen); | ||
408 | x_gap = canvas()->width() - (panel_width + (2 * bin_margin)); | ||
409 | //x_gap += peg_size >> 1; | ||
410 | if (x_gap < 1) | ||
411 | x_gap = 1; | ||
412 | |||
413 | y_gap = board_height / 6; | ||
414 | y_gap -= (2 * bin_margin); | ||
415 | //y_gap += peg_size >> 1; | ||
416 | if (y_gap < 1) | ||
417 | y_gap = 1; | ||
418 | x = panel_width + bin_margin - (peg_size >> 1); | ||
419 | y = bin_margin - (peg_size >> 1) + 2; | ||
420 | |||
421 | for (i = 0; i < 6; i++) { | ||
422 | for (j = 0; j < 10; j++) { | ||
423 | int rx = x + (rand() % x_gap); | ||
424 | int ry = y + (rand() % y_gap); | ||
425 | painter.drawImage(rx,ry, Peg::imageForType(i)); | ||
426 | } | ||
427 | y += board_height / 6; | ||
428 | } | ||
429 | /* now draw the surrounding boxes */ | ||
430 | x_gap = canvas()->width() - panel_width; | ||
431 | if (x_gap < 1) x_gap = 1; | ||
432 | y_gap = board_height / 6; | ||
433 | x = panel_width; | ||
434 | y = 1; | ||
435 | |||
436 | for (i = 0; i < 6; i++) { | ||
437 | painter.drawRect(x, y, x_gap, y_gap); | ||
438 | y += y_gap; | ||
439 | } | ||
440 | |||
441 | x = 0; | ||
442 | y = 0; | ||
443 | |||
444 | painter.drawImage(x,y, titleImage); | ||
445 | y = title_height; | ||
446 | /* now nine gues panels */ | ||
447 | for (i = 0; i < 9; i ++) { | ||
448 | painter.drawImage(x, y, panelImage); | ||
449 | y += panel_height; | ||
450 | } | ||
451 | |||
452 | painter.flush(); | ||
453 | canvas()->setBackgroundPixmap(background); | ||
454 | } | ||
455 | |||
456 | void MindBreakerBoard::checkGuess() | ||
457 | { | ||
458 | int i,j; | ||
459 | int num_white = 0; | ||
460 | int num_black = 0; | ||
461 | int copy_answer[4]; | ||
462 | int copy_guess[4]; | ||
463 | |||
464 | for(i = 0; i < 4; i++) { | ||
465 | copy_answer[i] = answer[i]; | ||
466 | copy_guess[i] = current_guess[i]; | ||
467 | if (current_guess[i] == 6) | ||
468 | return; | ||
469 | if (answer[i] == current_guess[i]) { | ||
470 | num_black++; | ||
471 | copy_answer[i] = 6; | ||
472 | copy_guess[i] = 7; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | /* now sure that user has completed a 'guess' */ | ||
477 | for (i = 0; i < 4; i++) { | ||
478 | if (copy_guess[i] == 7) | ||
479 | continue; // already marked for a black | ||
480 | for (j = 0; j < 4; j++) { | ||
481 | if(copy_guess[i] == copy_answer[j]) { | ||
482 | copy_answer[j] = 6; | ||
483 | num_white++; | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | } | ||
488 | |||
489 | int x = answerpegx; | ||
490 | int y = (board_height - ((current_go + 1) * panel_height)) + answerpegy; | ||
491 | |||
492 | if (num_black == 4) | ||
493 | game_over = TRUE; | ||
494 | |||
495 | while(num_black > 0) { | ||
496 | Peg *p = new Peg(canvas(), 7); | ||
497 | p->setPlaced(TRUE); | ||
498 | p->setX(x); | ||
499 | p->setY(y); | ||
500 | p->setZ(1); | ||
501 | p->show(); | ||
502 | num_black--; | ||
503 | |||
504 | if (x == answerpegx) | ||
505 | x = answerpegx + answerpeg_diff; | ||
506 | else { | ||
507 | x = answerpegx; | ||
508 | y += answerpeg_diff; | ||
509 | } | ||
510 | } | ||
511 | while(num_white > 0){ | ||
512 | Peg *p = new Peg(canvas(), 6); | ||
513 | p->setPlaced(TRUE); | ||
514 | p->setX(x); | ||
515 | p->setY(y); | ||
516 | p->setZ(1); | ||
517 | p->show(); | ||
518 | num_white--; | ||
519 | |||
520 | if (x == answerpegx) | ||
521 | x = answerpegx + answerpeg_diff; | ||
522 | else { | ||
523 | x = answerpegx; | ||
524 | y += answerpeg_diff; | ||
525 | } | ||
526 | } | ||
527 | /* move to next go */ | ||
528 | for(i = 0; i < 4; i++) { | ||
529 | past_guesses[4*current_go+i] = current_guess[i]; | ||
530 | current_guess[i] = 6; | ||
531 | } | ||
532 | |||
533 | current_go++; | ||
534 | if((current_go > 8) || game_over) { | ||
535 | total_games++; | ||
536 | if(!game_over) | ||
537 | total_turns += 10; | ||
538 | else | ||
539 | total_turns += current_go; | ||
540 | |||
541 | emit scoreChanged(total_turns, total_games); | ||
542 | Peg *p = new Peg(canvas(), 9); | ||
543 | game_over = TRUE; | ||
544 | p->setPlaced(TRUE); | ||
545 | p->setX(0); | ||
546 | p->setY(0); | ||
547 | p->setZ(0); | ||
548 | p->show(); | ||
549 | |||
550 | for (i = 0; i < 4; i++) { | ||
551 | p = new Peg(canvas(), answer[i], -1); | ||
552 | p->setX(first_peg_x_diff + (i * peg_spacing)); | ||
553 | p->setY(5); | ||
554 | p->setZ(3); | ||
555 | p->show(); | ||
556 | } | ||
557 | } else { | ||
558 | current_highlight->setY(board_height - ((current_go + 1) * panel_height)); | ||
559 | } | ||
560 | canvas()->update(); | ||
561 | } | ||
562 | |||
563 | void MindBreakerBoard::clear() | ||
564 | { | ||
565 | if(!game_over) { | ||
566 | total_games++; | ||
567 | total_turns += 10; | ||
568 | emit scoreChanged(total_turns, total_games); | ||
569 | } | ||
570 | int i; | ||
571 | /* reset the game board */ | ||
572 | game_over = FALSE; | ||
573 | /* clear the answer, clear the guess */ | ||
574 | for (i = 0; i < 4; i++) { | ||
575 | answer[i] = rand() % 6; | ||
576 | current_guess[i] = 6; | ||
577 | } | ||
578 | current_go = 0; | ||
579 | |||
580 | QCanvasItemList list = canvas()->allItems(); | ||
581 | QCanvasItemList::Iterator it = list.begin(); | ||
582 | for (; it != list.end(); ++it) { | ||
583 | if (*it == current_highlight) | ||
584 | continue; | ||
585 | if (*it) | ||
586 | delete *it; | ||
587 | } | ||
588 | |||
589 | current_highlight->setY(board_height - ((current_go + 1) * panel_height)); | ||
590 | checkScores(); | ||
591 | drawBackground(); | ||
592 | canvas()->update(); | ||
593 | } | ||
594 | |||
595 | void MindBreakerBoard::resetScore() | ||
596 | { | ||
597 | /* are u sure */ | ||
598 | |||
599 | if (QMessageBox::information(this, tr( "Reset Statistics" ), | ||
600 | tr( "Reset the win ratio?" ), | ||
601 | tr( "OK" ), tr( "Cancel" ) ) == 0) { | ||
602 | total_turns = 0; | ||
603 | total_games = 0; | ||
604 | Peg::eggLevel = 0; | ||
605 | drawBackground(); | ||
606 | canvas()->update(); | ||
607 | emit scoreChanged(total_turns, total_games); | ||
608 | } | ||
609 | } | ||
610 | |||
611 | /* EVENTS */ | ||
612 | |||
613 | void MindBreakerBoard::contentsMousePressEvent(QMouseEvent *e) | ||
614 | { | ||
615 | copy_press = FALSE; | ||
616 | null_press = FALSE; | ||
617 | /* ok, first work out if it is one of the bins that | ||
618 | got clicked */ | ||
619 | if (e->x() > panel_width) { | ||
620 | /* its a bin, but which bin */ | ||
621 | if(e->y() > board_height) | ||
622 | return; // missed everything | ||
623 | int bin = (e->y() + 2) / (board_height / 6); | ||
624 | |||
625 | /* make new peg... set it moving */ | ||
626 | moving_pos = e->pos(); | ||
627 | moving = new Peg(canvas(), bin, current_go); | ||
628 | moving->setX(e->x() - (peg_size >> 1)); | ||
629 | moving->setY(e->y() - (peg_size >> 1)); | ||
630 | moving->setZ(5); | ||
631 | moving->show(); | ||
632 | canvas()->update(); | ||
633 | return; | ||
634 | } | ||
635 | |||
636 | QCanvasItemList l = canvas()->collisions(e->pos()); | ||
637 | for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) { | ||
638 | if ( (*it)->rtti() == pegRTTI ) { | ||
639 | Peg *item = (Peg *)(*it); | ||
640 | if (!item->hit(e->pos())) | ||
641 | continue; | ||
642 | if (item->type() > 5) { | ||
643 | null_press = TRUE; | ||
644 | null_point = e->pos(); | ||
645 | continue; /* not a color peg */ | ||
646 | } | ||
647 | if (item->placed()) { | ||
648 | /* copy */ | ||
649 | if(item->pegGo() == -1) | ||
650 | return; | ||
651 | if(item->pegGo() == current_go) { | ||
652 | copy_press = TRUE; | ||
653 | copy_peg = item; | ||
654 | } | ||
655 | moving = new Peg(canvas(), | ||
656 | item->type(), current_go); | ||
657 | moving->setX(e->x() - (peg_size >> 1)); | ||
658 | moving->setY(e->y() - (peg_size >> 1)); | ||
659 | moving->setZ(5); | ||
660 | moving->show(); | ||
661 | moving_pos = QPoint(e->x(), e->y()); | ||
662 | canvas()->update(); | ||
663 | return; | ||
664 | } | ||
665 | moving = (Peg *)*it; | ||
666 | moving_pos = e->pos(); | ||
667 | canvas()->update(); | ||
668 | return; | ||
669 | } | ||
670 | } | ||
671 | null_press = TRUE; | ||
672 | null_point = e->pos(); | ||
673 | moving = 0; | ||
674 | } | ||
675 | |||
676 | void MindBreakerBoard::contentsMouseMoveEvent(QMouseEvent* e) | ||
677 | { | ||
678 | if (moving ) { | ||
679 | moving->moveBy(e->pos().x() - moving_pos.x(), | ||
680 | e->pos().y() - moving_pos.y()); | ||
681 | moving_pos = e->pos(); | ||
682 | canvas()->update(); | ||
683 | return; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | void MindBreakerBoard::contentsMouseReleaseEvent(QMouseEvent* e) | ||
688 | { | ||
689 | /* time to put down the peg */ | ||
690 | if(moving) { | ||
691 | if(copy_press) { | ||
692 | /* check if collided with original. if so, delete both */ | ||
693 | copy_press = FALSE; | ||
694 | QCanvasItemList l = canvas()->collisions(e->pos()); | ||
695 | for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) { | ||
696 | if (*it == copy_peg) | ||
697 | copy_press = TRUE; | ||
698 | } | ||
699 | if (copy_press) { | ||
700 | current_guess[copy_peg->pegPos()] = 6; | ||
701 | delete copy_peg; | ||
702 | delete moving; | ||
703 | copy_press = FALSE; | ||
704 | moving = 0; | ||
705 | copy_peg = 0; | ||
706 | canvas()->update(); | ||
707 | return; | ||
708 | } | ||
709 | } | ||
710 | |||
711 | /* first work out if in y */ | ||
712 | if (e->y() > (board_height - (current_go * panel_height))) { | ||
713 | delete moving; | ||
714 | moving = 0; | ||
715 | canvas()->update(); | ||
716 | return; | ||
717 | } | ||
718 | if (e->y() < (board_height - ((current_go + 1) * panel_height))) { | ||
719 | delete moving; | ||
720 | moving = 0; | ||
721 | canvas()->update(); | ||
722 | return; | ||
723 | } | ||
724 | /* ok, a valid go, but which peg */ | ||
725 | int x_bar = first_peg_x_diff - (peg_size >> 1); | ||
726 | x_bar += peg_spacing; | ||
727 | int pos = 0; | ||
728 | if (e->x() > x_bar) | ||
729 | pos = 1; | ||
730 | x_bar += peg_spacing; | ||
731 | if (e->x() > x_bar) | ||
732 | pos = 2; | ||
733 | x_bar += peg_spacing; | ||
734 | if (e->x() > x_bar) | ||
735 | pos = 3; | ||
736 | x_bar += peg_spacing; | ||
737 | |||
738 | if (e->x() > x_bar) { | ||
739 | /* invalid x */ | ||
740 | delete moving; | ||
741 | moving = 0; | ||
742 | canvas()->update(); | ||
743 | return; | ||
744 | } | ||
745 | |||
746 | int x = first_peg_x_diff + (pos * peg_spacing); | ||
747 | int y = board_height - ((current_go + 1) * panel_height) | ||
748 | + first_peg_y_diff; | ||
749 | moving->setPegPos(pos); | ||
750 | moving->setX(x); | ||
751 | moving->setY(y); | ||
752 | moving->setZ(2); | ||
753 | |||
754 | /* remove all other pegs from this position */ | ||
755 | QCanvasItemList l = canvas()->collisions(QPoint(x,y)); | ||
756 | for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) { | ||
757 | if ( (*it)->rtti() == pegRTTI ) { | ||
758 | Peg *item = (Peg *)(*it); | ||
759 | if ((item != moving) && (item != current_highlight)) | ||
760 | delete item; | ||
761 | } | ||
762 | } | ||
763 | current_guess[pos] = ((Peg *)moving)->type(); | ||
764 | |||
765 | ((Peg *)moving)->setPlaced(true); | ||
766 | canvas()->update(); | ||
767 | return; | ||
768 | } | ||
769 | moving = 0; | ||
770 | null_point -= e->pos(); | ||
771 | if(null_point.manhattanLength() < 6) { | ||
772 | if (game_over) | ||
773 | clear(); | ||
774 | else | ||
775 | checkGuess(); | ||
776 | } | ||
777 | } | ||
778 | |||
779 | void MindBreakerBoard::resizeEvent(QResizeEvent *e) | ||
780 | { | ||
781 | QSize s = e->size(); | ||
782 | int fw = style().defaultFrameWidth(); | ||
783 | s.setWidth(s.width() - fw); | ||
784 | s.setHeight(s.height() - fw); | ||
785 | |||
786 | /* min size is 200 x 260 */ | ||
787 | if (s.width() < board_width) | ||
788 | s.setWidth(board_width); | ||
789 | |||
790 | if (s.height() < board_height) | ||
791 | s.setHeight(board_height); | ||
792 | |||
793 | canvas()->resize(s.width() - fw, s.height() - fw); | ||
794 | drawBackground(); | ||
795 | } | ||
796 | |||
797 | |||
798 | /* Easter egg function... beat the clock */ | ||
799 | void MindBreakerBoard::checkScores() | ||
800 | { | ||
801 | double games = total_games; | ||
802 | double turns = total_turns; | ||
803 | double g = games / 10.0; | ||
804 | Peg::eggLevel = 0; | ||
805 | |||
806 | double break_even = 5.0; | ||
807 | if (g < 1.0) | ||
808 | return; | ||
809 | double avg = turns / games; | ||
810 | g--; | ||
811 | while (break_even >= 0.0) { | ||
812 | if (avg >= (break_even + g)) | ||
813 | return; | ||
814 | // score a peg. | ||
815 | break_even -= 1.0; | ||
816 | Peg::eggLevel = int(5.0 - break_even); | ||
817 | } | ||
818 | } | ||
diff --git a/noncore/games/mindbreaker/mindbreaker.h b/noncore/games/mindbreaker/mindbreaker.h new file mode 100644 index 0000000..fca649a --- a/dev/null +++ b/noncore/games/mindbreaker/mindbreaker.h | |||
@@ -0,0 +1,122 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #ifndef MINDBREAKER_H | ||
22 | #define MINDBREAKER_H | ||
23 | |||
24 | #include <qwidget.h> | ||
25 | #include <qmainwindow.h> | ||
26 | #include <qimage.h> | ||
27 | #include <qvector.h> | ||
28 | #include <qcanvas.h> | ||
29 | #include <qlabel.h> | ||
30 | |||
31 | static const int panel_height = 26; | ||
32 | static const int panel_width = 180; | ||
33 | |||
34 | static const int title_height = 25; | ||
35 | static const int title_width = 180; | ||
36 | |||
37 | static const int bin_margin = 10; | ||
38 | static const int peg_size = 20; | ||
39 | static const int answerpeg_size = 13; | ||
40 | |||
41 | static const int first_peg_x_diff = 21; | ||
42 | static const int first_peg_y_diff = ((panel_height - peg_size) >> 1); | ||
43 | static const int peg_spacing = 30; | ||
44 | |||
45 | static const int answerpegx = 152; | ||
46 | static const int answerpegy = 2; | ||
47 | static const int answerpeg_diff = 9; | ||
48 | |||
49 | static const int board_height = (title_height + (panel_height * 9)); | ||
50 | static const int board_width = (panel_width + (bin_margin * 2) + peg_size); | ||
51 | |||
52 | class Peg; | ||
53 | class QToolButton; | ||
54 | |||
55 | class MindBreakerBoard : public QCanvasView // QWidget | ||
56 | { | ||
57 | Q_OBJECT | ||
58 | public: | ||
59 | MindBreakerBoard(QCanvas &c, QWidget *parent=0, const char *name=0, int wFlags=0 ); | ||
60 | ~MindBreakerBoard(); | ||
61 | |||
62 | void getScore(int *, int *); | ||
63 | signals: | ||
64 | void scoreChanged(int, int); | ||
65 | |||
66 | public slots: | ||
67 | void clear(); | ||
68 | void resetScore(); | ||
69 | |||
70 | protected: | ||
71 | void contentsMousePressEvent(QMouseEvent *); | ||
72 | void contentsMouseMoveEvent(QMouseEvent *); | ||
73 | void contentsMouseReleaseEvent(QMouseEvent *); | ||
74 | void resizeEvent(QResizeEvent *); | ||
75 | |||
76 | private: | ||
77 | void drawBackground(); | ||
78 | void checkGuess(); | ||
79 | void checkScores(); | ||
80 | void placeGuessPeg(int pos, int pegId); | ||
81 | |||
82 | QImage panelImage; | ||
83 | QImage titleImage; | ||
84 | |||
85 | Peg *moving; | ||
86 | Peg *current_highlight; | ||
87 | QPoint moving_pos; | ||
88 | |||
89 | // the game stuff | ||
90 | int answer[4]; | ||
91 | int current_guess[4]; | ||
92 | int past_guesses[4*9]; | ||
93 | int current_go; | ||
94 | |||
95 | int null_press; | ||
96 | QPoint null_point; | ||
97 | bool copy_press; | ||
98 | Peg *copy_peg; | ||
99 | bool game_over; | ||
100 | |||
101 | int total_turns; | ||
102 | int total_games; | ||
103 | }; | ||
104 | |||
105 | class MindBreaker : public QMainWindow // QWidget | ||
106 | { | ||
107 | Q_OBJECT | ||
108 | public: | ||
109 | MindBreaker(QWidget *parent=0, const char *name=0, int wFlags=0 ); | ||
110 | |||
111 | public slots: | ||
112 | void setScore(int, int); | ||
113 | |||
114 | private: | ||
115 | QCanvas canvas; | ||
116 | MindBreakerBoard *board; | ||
117 | QToolButton *score; | ||
118 | |||
119 | }; | ||
120 | |||
121 | |||
122 | #endif | ||
diff --git a/noncore/games/mindbreaker/mindbreaker.pro b/noncore/games/mindbreaker/mindbreaker.pro new file mode 100644 index 0000000..12944d1 --- a/dev/null +++ b/noncore/games/mindbreaker/mindbreaker.pro | |||
@@ -0,0 +1,12 @@ | |||
1 | TEMPLATE = app | ||
2 | CONFIG += qt warn_on release | ||
3 | DESTDIR = $(QPEDIR)/bin | ||
4 | HEADERS = mindbreaker.h | ||
5 | SOURCES = main.cpp \ | ||
6 | mindbreaker.cpp | ||
7 | TARGET = mindbreaker | ||
8 | INCLUDEPATH += $(QPEDIR)/include | ||
9 | DEPENDPATH += $(QPEDIR)/include | ||
10 | LIBS += -lqpe | ||
11 | |||
12 | TRANSLATIONS = ../i18n/de/mindbreaker.ts | ||
diff --git a/noncore/games/mindbreaker/qpe-mindbreaker.control b/noncore/games/mindbreaker/qpe-mindbreaker.control new file mode 100644 index 0000000..3bad93d --- a/dev/null +++ b/noncore/games/mindbreaker/qpe-mindbreaker.control | |||
@@ -0,0 +1,9 @@ | |||
1 | Files: bin/mindbreaker apps/Games/mindbreaker.desktop pics/mindbreaker | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: Game: crack the coloured code | ||
9 | A game for the Qtopia environment. | ||