summaryrefslogtreecommitdiff
path: root/noncore/games/kpacman/board.cpp
authorleseb <leseb>2002-04-15 22:40:28 (UTC)
committer leseb <leseb>2002-04-15 22:40:28 (UTC)
commita91544d04ed391bbdc0c6f95ff8a80d35190788c (patch) (unidiff)
tree85dea85fd8a1cdb6d2d18fef57753d0b5e4bd143 /noncore/games/kpacman/board.cpp
parent6396d8b9fca7f3f50010a13a26e4ee9569abefb3 (diff)
downloadopie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.zip
opie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.tar.gz
opie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.tar.bz2
New directory structure
Diffstat (limited to 'noncore/games/kpacman/board.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/games/kpacman/board.cpp425
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
18Board::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
28void 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
106void 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
128bool Board::inBounds(int pos)
129{
130 return ( pos < 0 || pos > sz-1 ? FALSE : TRUE);
131}
132
133void 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
178void 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
202int 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
219bool Board::isOut(int pos)
220{
221 if (inBounds(pos))
222 return (at(pos) == OUT ? TRUE : FALSE);
223 return TRUE;
224}
225
226bool Board::isEmpty(int pos)
227{
228 if (inBounds(pos))
229 return ((at(pos) & fixBits) == empty ? TRUE : FALSE);
230 return TRUE;
231}
232
233bool Board::isBrick(int pos)
234{
235 if (inBounds(pos))
236 return ((at(pos) & fixBits) == brick ? TRUE : FALSE);
237 return FALSE;
238}
239
240bool Board::isPrison(int pos)
241{
242 if (inBounds(pos))
243 return ((at(pos) & fixBits) == prison ? TRUE : FALSE);
244 return FALSE;
245}
246
247bool Board::isGate(int pos)
248{
249 if (inBounds(pos))
250 return ((at(pos) & fixBits) == gate ? TRUE : FALSE);
251 return FALSE;
252}
253
254bool Board::isTunnel(int pos)
255{
256 if (inBounds(pos))
257 return ((at(pos) & fixBits) == tunnel ? TRUE : FALSE);
258 return FALSE;
259}
260
261bool 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
268bool 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
275bool 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
282bool 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
289bool 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
296bool 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
321bool 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
335int 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
366int 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
382int Board::x(int pos)
383{
384 return pos % BoardWidth;
385}
386
387int Board::y(int pos)
388{
389 return pos/BoardWidth;
390}
391
392int 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
407int Board::points()
408{
409 return numPoints;
410}
411
412int Board::energizers()
413{
414 return numEnergizers;
415}
416
417int Board::monsters()
418{
419 return numMonsters;
420}
421
422int Board::tunnels()
423{
424 return numTunnels;
425}