|
|
1.1 root 1: /*
2: /* PACMAN - written by Dave Nixon, AGS Computers Inc., July, 1981.
3: /*
4: /* Terminal handling for video games taken from aliens
5: /* the original version of aliens is from
6: /* Fall 1979 Cambridge Jude Miller
7: /*
8: /* Score keeping modified and general terminal handling (termcap routines
9: /* from UCB's ex) added by Rob Coben, BTL, June, 1980.
10: /*
11: /* If MSG is defined, the program uses the inter-process message facility
12: /* of UNIX/TS Augmented to optimize reading the tty while updating the
13: /* screen. Otherwise, the child process (reading the tty) writes
14: /* a temporary communications file, which the parent (updating the screen)
15: /* is constantly seeking to the beginning of and re-reading. (UGH!)
16: /* If your system has a non-blocking read (read-without-wait), it should
17: /* be implemented, and the child process could be dispensed with entirely.
18: */
19: #include <stdio.h>
20: #include "pacdefs.h"
21:
22: /*
23: * global variables
24: */
25:
26: extern char
27: *vs_cm;
28:
29: extern int
30: putch();
31:
32: extern char
33: *tgoto();
34:
35: extern char
36: message[];
37:
38: extern char
39: initbrd[BRDY][BRDX],
40: display[BRDY][BRDX];
41:
42: extern unsigned
43: pscore;
44:
45: extern struct pac
46: monst[];
47:
48: int pacsymb = PACMAN,
49: rounds, /* time keeping mechanism */
50: killflg,
51: delay,
52: potion,
53: goldcnt, /* no. of gold pieces remaining */
54: potioncnt;
55:
56: struct pac
57: pac;
58:
59: struct pac
60: pacstart =
61: {
62: PSTARTX,
63: PSTARTY,
64: DNULL,
65: SLOW,
66: FALSE
67: };
68:
69: struct pac
70: *pacptr = &pac;
71:
72: main()
73: {
74: register int tmp; /* temp variables */
75: register int pac_cnt;
76: register int monstcnt; /* monster number */
77: struct pac *mptr;
78: char gcnt[10];
79:
80: init(); /* global init */
81: for (pac_cnt = MAXPAC; pac_cnt > 0; pac_cnt--)
82: {
83: redraw:
84: clr();
85: SPLOT(0, 45, "SCORE: ");
86: SPLOT(21, 45, "gold left = ");
87: (void) sprintf(gcnt, "%6d", goldcnt);
88: SPLOT(21, 57, gcnt);
89: if (potion == TRUE)
90: {
91: SPLOT(3, 45, "COUNTDOWN: ");
92: };
93: pacsymb = PACMAN;
94: killflg = FALSE;
95: (void) sprintf(message, "delay = %6d", delay);
96: SPLOT(22, 45, message);
97: /*
98: * PLOT maze
99: */
100: for (tmp = 0; tmp < BRDY; tmp++)
101: {
102: SPLOT(tmp, 0, &(display[tmp][0]));
103: };
104: /* initialize a pacman */
105: pac = pacstart;
106: PLOT(pacptr->ypos, pacptr->xpos, pacsymb);
107: /* display remaining pacmen */
108: for (tmp = 0; tmp < pac_cnt - 1; tmp++)
109: {
110: PLOT(23, (MAXPAC * tmp), PACMAN);
111: };
112: /*
113: * Init. monsters
114: */
115: for (mptr = &monst[0], monstcnt = 0; monstcnt < MAXMONSTER; mptr++, monstcnt++)
116: {
117: mptr->xpos = MSTARTX + (2 * monstcnt);
118: mptr->ypos = MSTARTY;
119: mptr->speed = SLOW;
120: mptr->dirn = DNULL;
121: mptr->danger = FALSE;
122: mptr->stat = START;
123: PLOT(mptr->ypos, mptr->xpos, MONSTER);
124: };
125: rounds = 0; /* timing mechanism */
126:
127: /* main game loop */
128: do
129: {
130: if (rounds++ % MSTARTINTVL == 0)
131: {
132: startmonst();
133: };
134: pacman();
135: if (killflg == TURKEY)
136: break;
137: for (monstcnt = 0; monstcnt < (MAXMONSTER / 2); monstcnt++)
138: {
139: monster(monstcnt); /* next monster */
140: };
141: if (killflg == TURKEY)
142: break;
143: if (pacptr->speed == FAST)
144: {
145: pacman();
146: if (killflg == TURKEY)
147: break;
148: };
149: for (monstcnt = (MAXMONSTER / 2); monstcnt < MAXMONSTER; monstcnt++)
150: {
151: monster(monstcnt); /* next monster */
152: };
153: if (killflg == TURKEY)
154: break;
155: if (potion == TRUE)
156: {
157: (void) sprintf(message, "%2d%c", potioncnt,
158: ((potioncnt == 10) ? BEEP : ' '));
159: SPLOT(3, 60, message);
160: if (--potioncnt <= 0)
161: {
162: SPLOT(3, 45, " ");
163: potion = FALSE;
164: pacptr->speed = SLOW;
165: pacptr->danger = FALSE;
166: for (monstcnt = 0; monstcnt < MAXMONSTER; monstcnt++)
167: {
168: monst[monstcnt].danger = TRUE;
169: };
170: };
171: };
172: update(); /* score display etc */
173: if (goldcnt <= 0)
174: {
175: reinit();
176: goto redraw;
177: };
178: } while (killflg != TURKEY);
179: SPLOT(5, 45, "YOU ARE BEING EATEN");
180: SPLOT(6, 45, "THIS TAKES ABOUT 2 SECONDS");
181: sleep(2);
182: };
183: SPLOT(8, 45, "THE MONSTERS ALWAYS TRIUMPH");
184: SPLOT(9, 45, "IN THE END!");
185: over();
186: }
187:
188: pacman()
189: {
190: register int sqtype;
191: register int mcnt;
192: register int tmpx, tmpy;
193: int deltat;
194: struct pac *mptr;
195:
196: /* pause; wait for the player to hit a key */
197: for (deltat = delay; deltat > 0; deltat--);
198:
199: /* get instructions from player, but don't wait */
200: poll(0);
201:
202: /* remember current pacman position */
203: tmpx = pacptr->xpos;
204: tmpy = pacptr->ypos;
205:
206: /* "eat" any gold */
207: /* update display array to reflect what is on terminal */
208: display[tmpy][tmpx] = VACANT;
209:
210: /* what next? */
211: switch (pacptr->dirn)
212: {
213: case DUP:
214: pacsymb = PUP;
215: switch (sqtype = display[tmpy + UPINT][tmpx])
216: {
217: case GOLD:
218: case VACANT:
219: case CHOICE:
220: case POTION:
221: case TREASURE:
222:
223: /* erase where the pacman went */
224: PLOT(tmpy, tmpx, VACANT);
225: pacptr->ypos += UPINT;
226: break;
227:
228: default:
229: pacptr->dirn = DNULL;
230: break;
231: };
232: break;
233: case DDOWN:
234: pacsymb = PDOWN;
235: switch (sqtype = display[tmpy + DOWNINT][tmpx])
236: {
237: case GOLD:
238: case VACANT:
239: case CHOICE:
240: case POTION:
241: case TREASURE:
242:
243: /* erase where the pacman went */
244: PLOT(tmpy, tmpx, VACANT);
245: pacptr->ypos += DOWNINT;
246: break;
247:
248: default:
249: pacptr->dirn = DNULL;
250: break;
251: };
252: break;
253: case DLEFT:
254: if(tmpx == 0)
255: {
256: /* erase where the pacman went */
257: PLOT(tmpy, tmpx, VACANT);
258: pacptr->xpos = XWRAP;
259: sqtype = VACANT;
260: break;
261: };
262: pacsymb = PLEFT;
263: switch (sqtype = display[tmpy][tmpx + LEFTINT])
264: {
265: case GOLD:
266: case VACANT:
267: case CHOICE:
268: case POTION:
269: case TREASURE:
270:
271: /* erase where the pacman went */
272: PLOT(tmpy, tmpx, VACANT);
273: pacptr->xpos += LEFTINT;
274: break;
275:
276: default:
277: pacptr->dirn = DNULL;
278: break;
279: };
280: break;
281: case DRIGHT:
282: if(tmpx == XWRAP)
283: {
284: /* erase where the pacman went */
285: PLOT(tmpy, tmpx, VACANT);
286: pacptr->xpos = 0;
287: sqtype = VACANT;
288: break;
289: };
290: pacsymb = PRIGHT;
291: switch (sqtype = display[tmpy][tmpx + RIGHTINT])
292: {
293: case GOLD:
294: case VACANT:
295: case CHOICE:
296: case POTION:
297: case TREASURE:
298:
299: /* erase where the pacman went */
300: PLOT(tmpy, tmpx, VACANT);
301: pacptr->xpos += RIGHTINT;
302: break;
303:
304: default:
305: pacptr->dirn = DNULL;
306: break;
307: };
308: break;
309: };
310:
311: /* did the pacman get any points or eat a potion? */
312: switch (sqtype)
313: {
314: case CHOICE:
315: case GOLD:
316: pscore++;
317: goldcnt--;
318: break;
319:
320: case TREASURE:
321: pscore += TREASVAL;
322: break;
323:
324: case POTION:
325: SPLOT(3, 45, "COUNTDOWN: ");
326: potion = TRUE;
327: potioncnt = POTINTVL;
328: pacptr->speed = FAST;
329: pacptr->danger = TRUE;
330:
331: /* slow down monsters and make them harmless */
332: mptr = &monst[0];
333: for (mcnt = 0; mcnt < MAXMONSTER; mcnt++)
334: {
335: if (mptr->stat == RUN)
336: {
337: mptr->speed = SLOW;
338: mptr->danger = FALSE;
339: };
340: mptr++;
341: };
342: break;
343: };
344:
345: /* did the pacman run into a monster? */
346: for (mptr = &monst[0], mcnt = 0; mcnt < MAXMONSTER; mptr++, mcnt++)
347: {
348: if ((mptr->xpos == pacptr->xpos) &&
349: (mptr->ypos == pacptr->ypos))
350: {
351:
352: killflg = dokill(mcnt);
353: }
354: else
355: {
356: killflg = FALSE;
357: };
358: };
359: if (killflg != TURKEY)
360: {
361: PLOT(pacptr->ypos, pacptr->xpos, pacsymb);
362: };
363: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.