author | leseb <leseb> | 2002-04-15 22:40:28 (UTC) |
---|---|---|
committer | leseb <leseb> | 2002-04-15 22:40:28 (UTC) |
commit | a91544d04ed391bbdc0c6f95ff8a80d35190788c (patch) (unidiff) | |
tree | 85dea85fd8a1cdb6d2d18fef57753d0b5e4bd143 /noncore/games/kpacman/board.cpp | |
parent | 6396d8b9fca7f3f50010a13a26e4ee9569abefb3 (diff) | |
download | opie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.zip opie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.tar.gz opie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.tar.bz2 |
New directory structure
Diffstat (limited to 'noncore/games/kpacman/board.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/games/kpacman/board.cpp | 425 |
1 files changed, 425 insertions, 0 deletions
diff --git a/noncore/games/kpacman/board.cpp b/noncore/games/kpacman/board.cpp new file mode 100644 index 0000000..849e75b --- a/dev/null +++ b/noncore/games/kpacman/board.cpp | |||
@@ -0,0 +1,425 @@ | |||
1 | |||
2 | #include "portable.h" | ||
3 | |||
4 | #if defined( KDE2_PORT ) | ||
5 | #include <kapp.h> | ||
6 | #include <klocale.h> | ||
7 | #endif | ||
8 | |||
9 | #include <qrect.h> | ||
10 | #include <qregexp.h> | ||
11 | #include <qmessagebox.h> | ||
12 | #include <qfile.h> | ||
13 | #include <qtextstream.h> | ||
14 | |||
15 | #include "board.h" | ||
16 | #include "bitmaps.h" | ||
17 | |||
18 | Board::Board(int size) : QArray<int> (size) | ||
19 | { | ||
20 | sz = size; // set size of board | ||
21 | |||
22 | map = ""; | ||
23 | mapName = ""; // no map loaded so far | ||
24 | |||
25 | init(None); // initialize varibales | ||
26 | } | ||
27 | |||
28 | void Board::init(Image image, QString levelName) | ||
29 | { | ||
30 | prisonEntry = OUT; | ||
31 | prisonExit = OUT; | ||
32 | fruitHome = OUT; | ||
33 | fruitPosition = OUT; | ||
34 | pacmanHome = OUT; | ||
35 | pacmanPosition = OUT; | ||
36 | for (int m = 0; m < 8; m++) { | ||
37 | monsterHome[m] = OUT; | ||
38 | monsterPosition[m] = OUT; | ||
39 | } | ||
40 | for (int e = 0; e < 8; e++) { | ||
41 | energizerPosition[e] = OUT; | ||
42 | } | ||
43 | for (int e = 0; e < 8; e++) { | ||
44 | tunnelPosition[e] = OUT; | ||
45 | } | ||
46 | |||
47 | fill(0); | ||
48 | numPoints = 0; | ||
49 | numEnergizers = 0; | ||
50 | numMonsters = 0; | ||
51 | numTunnels = 0; | ||
52 | |||
53 | if (!levelName.isNull() && !levelName.isEmpty()) | ||
54 | if (mapName == levelName) | ||
55 | image = File; | ||
56 | else { | ||
57 | QFile levelFile(levelName); | ||
58 | if (!levelFile.open(IO_ReadOnly)) { | ||
59 | |||
60 | QString msg = i18n("The levelmap could not be constructed.\n\n" | ||
61 | "The file '@LEVELNAME@' does not exist,\n" | ||
62 | "or could not be opened for reading."); | ||
63 | msg.replace(QRegExp("@LEVELNAME@"), levelName); | ||
64 | // QMessageBox::information(0, i18n("Initialization Error"), msg); | ||
65 | printf("%s\n", msg.data()); | ||
66 | } else { | ||
67 | map.fill(' ', BoardHeight*BoardWidth); | ||
68 | int height = 0; | ||
69 | |||
70 | QTextStream levelStream(&levelFile); | ||
71 | while (!levelStream.eof() && height < BoardHeight) { | ||
72 | QString line = levelStream.readLine(); | ||
73 | |||
74 | if (line.find(QRegExp("^ *;")) == -1) { | ||
75 | |||
76 | line.replace(QRegExp(";.*"), ""); // strip off comments | ||
77 | line.replace(QRegExp("\" *$"), ""); // strip off trailing " | ||
78 | line.replace(QRegExp("^ *\""), ""); // strip off leading " | ||
79 | |||
80 | map.replace(height*BoardWidth, | ||
81 | (line.length() > BoardWidth) ? BoardWidth : line.length(), | ||
82 | line.data()); | ||
83 | |||
84 | height++; | ||
85 | } | ||
86 | } | ||
87 | mapName = levelName; | ||
88 | levelFile.close(); | ||
89 | image = File; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | switch (image) { | ||
94 | case Intro : // setup(demo_bits); | ||
95 | break; | ||
96 | case Demo : setup(demo_bits); | ||
97 | break; | ||
98 | case Level : setup(demo_bits); | ||
99 | break; | ||
100 | case File : setup((uchar *) map.data()); | ||
101 | break; | ||
102 | default : break; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | void Board::setup(const uchar *buf) | ||
107 | { | ||
108 | for ( int index = 0; buf[index] != 0 && index < BoardWidth*BoardHeight; index++ ) { | ||
109 | switch (buf[index]) { | ||
110 | case '*' : set(index, brick); break; | ||
111 | case '+' : set(index, out); break; | ||
112 | case '#' : set(index, prison); break; | ||
113 | case '-' : set(index, gate); break; | ||
114 | case 'E' : set(index, tunnel); break; | ||
115 | case '.' : set(index, Point); break; | ||
116 | case 'o' : set(index, energizer); break; | ||
117 | case 'I' : set(index, prisonentry); break; | ||
118 | case 'O' : set(index, prisonexit); break; | ||
119 | case 'F' : set(index, fruithome); break; | ||
120 | case 'P' : set(index, pacmanhome); break; | ||
121 | default : if (buf[index] >= '0' && buf[index] <= '7') { | ||
122 | set(index, monsterhome, buf[index]-(uchar)'0'); | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | |||
128 | bool Board::inBounds(int pos) | ||
129 | { | ||
130 | return ( pos < 0 || pos > sz-1 ? FALSE : TRUE); | ||
131 | } | ||
132 | |||
133 | void Board::set(int pos, Square sq, int m) | ||
134 | { | ||
135 | if (inBounds(pos)) | ||
136 | switch (sq) { | ||
137 | case out : at(pos) = OUT; break; | ||
138 | case Point : at(pos) |= pointBit; numPoints++; break; | ||
139 | case tunnel : at(pos) = sq; | ||
140 | for (int e = 0; e < numTunnels; e++) { // if tunnel is already on board | ||
141 | if (tunnelPosition[e] == pos) // don't do it again. | ||
142 | pos = OUT; | ||
143 | } | ||
144 | if (pos != OUT) { | ||
145 | tunnelPosition[numTunnels] = pos; | ||
146 | numTunnels++; | ||
147 | } | ||
148 | break; | ||
149 | case energizer : at(pos) |= energizerBit; | ||
150 | for (int e = 0; e < numEnergizers; e++) { | ||
151 | if (energizerPosition[e] == pos) | ||
152 | pos = OUT; | ||
153 | } | ||
154 | if (pos != OUT) { | ||
155 | energizerPosition[numEnergizers] = pos; | ||
156 | numEnergizers++; | ||
157 | } | ||
158 | break; | ||
159 | case fruit : at(pos) |= fruitBit; fruitPosition = pos; break; | ||
160 | case pacman : at(pos) |= pacmanBit; pacmanPosition = pos; break; | ||
161 | case monster : at(pos) |= (monsterBit << m); | ||
162 | monsterPosition[m] = pos; break; | ||
163 | case prisonentry : prisonEntry = pos; at(pos) = empty; break; | ||
164 | case prisonexit : prisonExit = pos; at(pos) = empty; break; | ||
165 | case fruithome : fruitHome = pos; at(pos) = empty; break; | ||
166 | case pacmanhome : pacmanHome = pos; at(pos) = empty; break; | ||
167 | case monsterhome : monsterHome[m] = pos; at(pos) = empty; | ||
168 | if (m == 0 && prisonExit == OUT) | ||
169 | prisonExit = pos; | ||
170 | if (m == 1 && prisonEntry == OUT) | ||
171 | prisonEntry = pos; | ||
172 | numMonsters++; | ||
173 | break; | ||
174 | default : at(pos) = sq; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | void Board::reset(int pos, Square sq, int m) | ||
179 | { | ||
180 | bool found = FALSE; | ||
181 | if (inBounds(pos)) | ||
182 | switch (sq) { | ||
183 | case out : at(pos) = empty; break; | ||
184 | case Point : at(pos) &= ~ pointBit; numPoints--; break; | ||
185 | case energizer : at(pos) &= ~ energizerBit; | ||
186 | for (int e = 0; e < numEnergizers; e++) { // delete the position of the eaten | ||
187 | if (found) // energizer in the position array | ||
188 | energizerPosition[e-1] = energizerPosition[e]; | ||
189 | if (energizerPosition[e] == pos) | ||
190 | found = TRUE; | ||
191 | } | ||
192 | energizerPosition[numEnergizers--] = OUT; | ||
193 | break; | ||
194 | case fruit : at(pos) &= ~ fruitBit; fruitPosition = OUT; break; | ||
195 | case pacman : at(pos) &= ~ pacmanBit; pacmanPosition = OUT; break; | ||
196 | case monster : at(pos) &= ~ (monsterBit << m); | ||
197 | monsterPosition[m] = OUT; break; | ||
198 | default : at(pos) = at(pos) & varBits; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | int Board::position(Square sq, int m) | ||
203 | { | ||
204 | switch(sq) { | ||
205 | case prisonentry : return prisonEntry; | ||
206 | case prisonexit : return prisonExit; | ||
207 | case fruit : return fruitPosition; | ||
208 | case fruithome : return fruitHome; | ||
209 | case pacman : return pacmanPosition; | ||
210 | case pacmanhome : return pacmanHome; | ||
211 | case monster : return monsterPosition[m]; | ||
212 | case monsterhome : return monsterHome[m]; | ||
213 | case energizer : return energizerPosition[m]; | ||
214 | case tunnel : return tunnelPosition[m]; | ||
215 | default : return OUT; | ||
216 | } | ||
217 | } | ||
218 | |||
219 | bool Board::isOut(int pos) | ||
220 | { | ||
221 | if (inBounds(pos)) | ||
222 | return (at(pos) == OUT ? TRUE : FALSE); | ||
223 | return TRUE; | ||
224 | } | ||
225 | |||
226 | bool Board::isEmpty(int pos) | ||
227 | { | ||
228 | if (inBounds(pos)) | ||
229 | return ((at(pos) & fixBits) == empty ? TRUE : FALSE); | ||
230 | return TRUE; | ||
231 | } | ||
232 | |||
233 | bool Board::isBrick(int pos) | ||
234 | { | ||
235 | if (inBounds(pos)) | ||
236 | return ((at(pos) & fixBits) == brick ? TRUE : FALSE); | ||
237 | return FALSE; | ||
238 | } | ||
239 | |||
240 | bool Board::isPrison(int pos) | ||
241 | { | ||
242 | if (inBounds(pos)) | ||
243 | return ((at(pos) & fixBits) == prison ? TRUE : FALSE); | ||
244 | return FALSE; | ||
245 | } | ||
246 | |||
247 | bool Board::isGate(int pos) | ||
248 | { | ||
249 | if (inBounds(pos)) | ||
250 | return ((at(pos) & fixBits) == gate ? TRUE : FALSE); | ||
251 | return FALSE; | ||
252 | } | ||
253 | |||
254 | bool Board::isTunnel(int pos) | ||
255 | { | ||
256 | if (inBounds(pos)) | ||
257 | return ((at(pos) & fixBits) == tunnel ? TRUE : FALSE); | ||
258 | return FALSE; | ||
259 | } | ||
260 | |||
261 | bool Board::isPoint(int pos) | ||
262 | { | ||
263 | if (inBounds(pos) && at(pos) != OUT) | ||
264 | return ((at(pos) & pointBit) != 0 ? TRUE : FALSE); | ||
265 | return FALSE; | ||
266 | } | ||
267 | |||
268 | bool Board::isEnergizer(int pos) | ||
269 | { | ||
270 | if (inBounds(pos) && at(pos) != OUT) | ||
271 | return ((at(pos) & energizerBit) != 0 ? TRUE : FALSE); | ||
272 | return FALSE; | ||
273 | } | ||
274 | |||
275 | bool Board::isFruit(int pos) | ||
276 | { | ||
277 | if (inBounds(pos) && at(pos) != OUT) | ||
278 | return ((at(pos) & fruitBit) != 0 ? TRUE : FALSE); | ||
279 | return FALSE; | ||
280 | } | ||
281 | |||
282 | bool Board::isPacman(int pos) | ||
283 | { | ||
284 | if (inBounds(pos) && at(pos) != OUT) | ||
285 | return ((at(pos) & pacmanBit) != 0 ? TRUE : FALSE); | ||
286 | return FALSE; | ||
287 | } | ||
288 | |||
289 | bool Board::isMonster(int pos) | ||
290 | { | ||
291 | if (inBounds(pos) && at(pos) != OUT) | ||
292 | return ((at(pos) & monsterBits) != 0 ? TRUE : FALSE); | ||
293 | return FALSE; | ||
294 | } | ||
295 | |||
296 | bool Board::isWay(int pos, int dir, Square sq) { | ||
297 | int p1 = move(pos, dir, 2); | ||
298 | if (p1 == OUT) | ||
299 | return (sq == out ? TRUE : FALSE); | ||
300 | int p2, p3; | ||
301 | if (dir == N || dir == S) { | ||
302 | p2 = move(p1, E); | ||
303 | p3 = move(p1, W); | ||
304 | } else { | ||
305 | p2 = move(p1, N); | ||
306 | p3 = move(p1, S); | ||
307 | } | ||
308 | switch (sq) { | ||
309 | case out : return isOut(p1) | isOut(p2) | isOut(p3); | ||
310 | case empty : return isEmpty(p1) & isEmpty(p2) & isEmpty(p3); | ||
311 | case brick : return isBrick(p1) | isBrick(p2) | isBrick(p3); | ||
312 | case prison : return isPrison(p1) | isPrison(p2) | isPrison(p3); | ||
313 | case gate : return isGate(p1) & isGate(p2) & isGate(p3); | ||
314 | case tunnel : return isTunnel(p1) & | ||
315 | (isTunnel(p2) || isEmpty(p2)) & | ||
316 | (isTunnel(p3) || isEmpty(p3)); | ||
317 | default : return FALSE; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | bool Board::isJump(int pos, int dir) { | ||
322 | switch (dir) { | ||
323 | case NW: return pos < BoardWidth || x(pos) == 0; | ||
324 | case N: return pos < BoardWidth; | ||
325 | case NE: return pos < BoardWidth || x(pos) == BoardWidth-1; | ||
326 | case W: return x(pos) == 0; | ||
327 | case E: return x(pos) == BoardWidth-1; | ||
328 | case SW: return pos >= sz-BoardWidth || x(pos) == 0; | ||
329 | case S: return pos >= sz-BoardWidth; | ||
330 | case SE: return pos >= sz-BoardWidth || x(pos) == BoardWidth-1; | ||
331 | } | ||
332 | return FALSE; | ||
333 | } | ||
334 | |||
335 | int Board::move(int pos, int dir, int steps) | ||
336 | { | ||
337 | if (steps < 0) { // move backwards | ||
338 | dir = turn(dir); // turn around and do your steps | ||
339 | steps *= -1; | ||
340 | } | ||
341 | |||
342 | while (steps-- != 0) { // until all steps are gone | ||
343 | switch (dir) { | ||
344 | case NW: pos = pos >= BoardWidth && x(pos) > 0 ? (pos-BoardWidth)-1 : sz-1; | ||
345 | break; | ||
346 | case N: pos = pos >= BoardWidth ? pos-BoardWidth : (sz-BoardWidth)+x(pos); | ||
347 | break; | ||
348 | case NE: pos = pos >= BoardWidth && x(pos) < BoardWidth-1 ? | ||
349 | (pos-BoardWidth)+1 : sz-BoardWidth; | ||
350 | break; | ||
351 | case W: pos = x(pos) > 0 ? pos-1 : pos+(BoardWidth-1); | ||
352 | break; | ||
353 | case E: pos = x(pos) < BoardWidth-1 ? pos+1 : pos-(BoardWidth-1); | ||
354 | break; | ||
355 | case SW: pos = pos < sz-BoardWidth && x(pos) > 0 ? (pos+BoardWidth)-1 : BoardWidth-1; | ||
356 | break; | ||
357 | case S: pos = pos < sz-BoardWidth ? pos+BoardWidth : x(pos); | ||
358 | break; | ||
359 | case SE: pos = pos < sz-BoardWidth && x(pos) < BoardWidth-1 ? (pos+BoardWidth)+1 : 0; | ||
360 | break; | ||
361 | } | ||
362 | } | ||
363 | return pos; // here we are | ||
364 | } | ||
365 | |||
366 | int Board::closeup(int pos, int dir, int target) | ||
367 | { | ||
368 | if (dir == N || dir == S) { | ||
369 | if (x(target) < x(pos)) | ||
370 | return W; | ||
371 | if (x(target) > x(pos)) | ||
372 | return E; | ||
373 | } else { | ||
374 | if (y(target) < y(pos)) | ||
375 | return N; | ||
376 | if (y(target) > y(pos)) | ||
377 | return S; | ||
378 | } | ||
379 | return dir; | ||
380 | } | ||
381 | |||
382 | int Board::x(int pos) | ||
383 | { | ||
384 | return pos % BoardWidth; | ||
385 | } | ||
386 | |||
387 | int Board::y(int pos) | ||
388 | { | ||
389 | return pos/BoardWidth; | ||
390 | } | ||
391 | |||
392 | int Board::turn(int dir) | ||
393 | { | ||
394 | switch (dir) { | ||
395 | case N : return S; | ||
396 | case NE : return SW; | ||
397 | case E : return W; | ||
398 | case SE : return NW; | ||
399 | case S : return N; | ||
400 | case SW : return NE; | ||
401 | case W : return E; | ||
402 | case NW : return SE; | ||
403 | default : return dir; | ||
404 | } | ||
405 | } | ||
406 | |||
407 | int Board::points() | ||
408 | { | ||
409 | return numPoints; | ||
410 | } | ||
411 | |||
412 | int Board::energizers() | ||
413 | { | ||
414 | return numEnergizers; | ||
415 | } | ||
416 | |||
417 | int Board::monsters() | ||
418 | { | ||
419 | return numMonsters; | ||
420 | } | ||
421 | |||
422 | int Board::tunnels() | ||
423 | { | ||
424 | return numTunnels; | ||
425 | } | ||