|
|
1.1 root 1: static char sccsid[] = " main.c 4.2 82/11/22 ";
2:
3: #include <stdio.h>
4: #include "back.h"
5:
6: #define MVPAUSE 5 /* time to sleep when stuck */
7: #define MAXUSERS 35 /* maximum number of users */
8:
9: char *instr[]; /* text of instructions */
10: char *message[]; /* update message */
11: char ospeed; /* tty output speed */
12:
13: char *helpm[] = { /* help message */
14: "Enter a space or newline to roll, or",
15: " R to reprint the board\tD to double",
16: " S to save the game\tQ to quit",
17: 0
18: };
19:
20: char *contin[] = { /* pause message */
21: "(Type a newline to continue.)",
22: "",
23: 0
24: };
25:
26: static char user1a[] =
27: "Sorry, you cannot play backgammon when there are more than ";
28: static char user1b[] =
29: " users\non the system.";
30: static char user2a[] =
31: "\nThere are now more than ";
32: static char user2b[] =
33: " users on the system, so you cannot play\nanother game. ";
34: static char rules[] = "\nDo you want the rules of the game?";
35: static char noteach[] = "Teachgammon not available!\n\007";
36: static char need[] = "Do you need instructions for this program?";
37: static char askcol[] =
38: "Enter 'r' to play red, 'w' to play white, 'b' to play both:";
39: static char rollr[] = "Red rolls a ";
40: static char rollw[] = ". White rolls a ";
41: static char rstart[] = ". Red starts.\n";
42: static char wstart[] = ". White starts.\n";
43: static char toobad1[] = "Too bad, ";
44: static char unable[] = " is unable to use that roll.\n";
45: static char toobad2[] = ". Too bad, ";
46: static char cantmv[] = " can't move.\n";
47: static char bgammon[] = "Backgammon! ";
48: static char gammon[] = "Gammon! ";
49: static char again[] = ".\nWould you like to play again?";
50: static char svpromt[] = "Would you like to save this game?";
51:
52: static char password[] = "losfurng";
53: static char pbuf[10];
54:
55: main (argc,argv)
56: int argc;
57: char **argv;
58:
59: {
60: register int i; /* non-descript index */
61: register int l; /* non-descript index */
62: register char c; /* non-descript character storage */
63: long t; /* time for random num generator */
64:
65: /* initialization */
66: bflag = 2; /* default no board */
67: signal (2,getout); /* trap interrupts */
68: if (gtty (0,&tty) == -1) /* get old tty mode */
69: errexit ("backgammon(gtty)");
70: old = tty.sg_flags;
71: #ifdef V7
72: raw = ((noech = old & ~ECHO) | CBREAK); /* set up modes */
73: #else
74: raw = ((noech = old & ~ECHO) | RAW); /* set up modes */
75: #endif
76: ospeed = old.sg_ospeed; /* for termlib */
77:
78: /* check user count */
79: # ifdef CORY
80: if (ucount() > MAXUSERS) {
81: writel (user1a);
82: wrint (MAXUSERS);
83: writel (user1b);
84: getout();
85: }
86: # endif
87:
88: /* get terminal
89: * capabilities, and
90: * decide if it can
91: * cursor address */
92: tflag = getcaps (getenv ("TERM"));
93: /* use whole screen
94: * for text */
95: if (tflag)
96: begscr = 0;
97: t = time(0);
98: srandom(t); /* 'random' seed */
99:
100: #ifdef V7
101: while (*++argv != 0) /* process arguments */
102: #else
103: while (*++argv != -1) /* process arguments */
104: #endif
105: getarg (&argv);
106: args[acnt] = '\0';
107: if (tflag) { /* clear screen */
108: noech &= ~(CRMOD|XTABS);
109: raw &= ~(CRMOD|XTABS);
110: clear();
111: }
112: fixtty (raw); /* go into raw mode */
113:
114: /* check if restored
115: * game and save flag
116: * for later */
117: if (rfl = rflag) {
118: text (message); /* print message */
119: text (contin);
120: wrboard(); /* print board */
121: /* if new game, pretend
122: * to be a non-restored
123: * game */
124: if (cturn == 0)
125: rflag = 0;
126: } else {
127: rscore = wscore = 0; /* zero score */
128: text (message); /* update message
129: * without pausing */
130:
131: if (aflag) { /* print rules */
132: writel (rules);
133: if (yorn(0)) {
134:
135: fixtty (old); /* restore tty */
136: execl (TEACH,"backgammon",args,0);
137:
138: tflag = 0; /* error! */
139: writel (noteach);
140: exit();
141: } else { /* if not rules, then
142: * instructions */
143: writel (need);
144: if (yorn(0)) { /* print instructions */
145: clear();
146: text (instr);
147: }
148: }
149: }
150:
151: init(); /* initialize board */
152:
153: if (pnum == 2) { /* ask for color(s) */
154: writec ('\n');
155: writel (askcol);
156: while (pnum == 2) {
157: c = readc();
158: switch (c) {
159:
160: case 'R': /* red */
161: pnum = -1;
162: break;
163:
164: case 'W': /* white */
165: pnum = 1;
166: break;
167:
168: case 'B': /* both */
169: pnum = 0;
170: break;
171:
172: case 'P':
173: if (iroll)
174: break;
175: if (tflag)
176: curmove (curr,0);
177: else
178: writec ('\n');
179: writel ("Password:");
180: signal (14,getout);
181: cflag = 1;
182: alarm (10);
183: for (i = 0; i < 10; i++) {
184: pbuf[i] = readc();
185: if (pbuf[i] == '\n')
186: break;
187: }
188: if (i == 10)
189: while (readc() != '\n');
190: alarm (0);
191: cflag = 0;
192: if (i < 10)
193: pbuf[i] = '\0';
194: for (i = 0; i < 9; i++)
195: if (pbuf[i] != password[i])
196: getout();
197: iroll = 1;
198: if (tflag)
199: curmove (curr,0);
200: else
201: writec ('\n');
202: writel (askcol);
203: break;
204:
205: default: /* error */
206: writec ('\007');
207: }
208: }
209: } else if (!aflag)
210: /* pause to read
211: * message */
212: text (contin);
213:
214: wrboard(); /* print board */
215:
216: if (tflag)
217: curmove (18,0);
218: else
219: writec ('\n');
220: }
221: /* limit text to bottom
222: * of screen */
223: if (tflag)
224: begscr = 17;
225:
226: for (;;) { /* begin game! */
227: /* initial roll if
228: * needed */
229: if ((! rflag) || raflag)
230: roll();
231:
232: /* perform ritual of
233: * first roll */
234: if (! rflag) {
235: if (tflag)
236: curmove (17,0);
237: while (D0 == D1) /* no doubles */
238: roll();
239:
240: /* print rolls */
241: writel (rollr);
242: writec (D0+'0');
243: writel (rollw);
244: writec (D1+'0');
245:
246: /* winner goes first */
247: if (D0 > D1) {
248: writel (rstart);
249: cturn = 1;
250: } else {
251: writel (wstart);
252: cturn = -1;
253: }
254: }
255:
256: /* initalize variables
257: * according to whose
258: * turn it is */
259:
260: if (cturn == 1) { /* red */
261: home = 25;
262: bar = 0;
263: inptr = &in[1];
264: inopp = &in[0];
265: offptr = &off[1];
266: offopp = &off[0];
267: Colorptr = &color[1];
268: colorptr = &color[3];
269: colen = 3;
270: } else { /* white */
271: home = 0;
272: bar = 25;
273: inptr = &in[0];
274: inopp = &in[1];
275: offptr = &off[0];
276: offopp = &off[1];
277: Colorptr = &color[0];
278: colorptr = &color[2];
279: colen = 5;
280: }
281:
282: /* do first move
283: * (special case) */
284: if (! (rflag && raflag)) {
285: if (cturn == pnum) /* computer's move */
286: move (0);
287: else { /* player's move */
288: mvlim = movallow();
289: /* reprint roll */
290: if (tflag)
291: curmove (cturn == -1? 18: 19,0);
292: proll();
293: getmove(); /* get player's move */
294: }
295: }
296: if (tflag) {
297: curmove (17,0);
298: cline();
299: begscr = 18;
300: }
301:
302: /* no longer any diff-
303: * erence between normal
304: * game and recovered
305: * game. */
306: rflag = 0;
307:
308: /* move as long as it's
309: * someone's turn */
310: while (cturn == 1 || cturn == -1) {
311:
312: /* board maintainence */
313: if (tflag)
314: refresh(); /* fix board */
315: else
316: /* redo board if -p */
317: if (cturn == bflag || bflag == 0)
318: wrboard();
319:
320: /* do computer's move */
321: if (cturn == pnum) {
322: move (1);
323:
324: /* see if double
325: * refused */
326: if (cturn == -2 || cturn == 2)
327: break;
328:
329: /* check for winning
330: * move */
331: if (*offopp == 15) {
332: cturn *= -2;
333: break;
334: }
335: continue;
336:
337: }
338:
339: /* (player's move) */
340:
341: /* clean screen if
342: * safe */
343: if (tflag && hflag) {
344: curmove (20,0);
345: clend ();
346: hflag = 1;
347: }
348:
349: /* if allowed, give him
350: * a chance to double */
351: if (dlast != cturn && gvalue < 64) {
352: if (tflag)
353: curmove (cturn == -1? 18: 19,0);
354: writel (*Colorptr);
355: c = readc();
356:
357: /* character cases */
358: switch (c) {
359:
360: /* reprint board */
361: case 'R':
362: wrboard();
363: break;
364:
365: /* save game */
366: case 'S':
367: raflag = 1;
368: save (1);
369: break;
370:
371: /* quit */
372: case 'Q':
373: quit();
374: break;
375:
376: /* double */
377: case 'D':
378: dble();
379: break;
380:
381: /* roll */
382: case ' ':
383: case '\n':
384: roll();
385: writel (" rolls ");
386: writec (D0+'0');
387: writec (' ');
388: writec (D1+'0');
389: writel (". ");
390:
391: /* see if he can move */
392: if ( (mvlim = movallow()) == 0) {
393:
394: /* can't move */
395: writel (toobad1);
396: writel (*colorptr);
397: writel (unable);
398: if (tflag) {
399: if (pnum) {
400: buflush();
401: sleep (MVPAUSE);
402: }
403: }
404: nexturn();
405: break;
406: }
407:
408: /* get move */
409: getmove();
410:
411: /* okay to clean
412: * screen */
413: hflag = 1;
414: break;
415:
416: /* invalid character */
417: default:
418:
419: /* print help message */
420: if (tflag)
421: curmove (20,0);
422: else
423: writec ('\n');
424: text (helpm);
425: if (tflag)
426: curmove (cturn == -1? 18: 19,0);
427: else
428: writec ('\n');
429:
430: /* don't erase */
431: hflag = 0;
432: }
433: } else { /* couldn't double */
434:
435: /* print roll */
436: roll();
437: if (tflag)
438: curmove (cturn == -1? 18: 19,0);
439: proll ();
440:
441: /* can he move? */
442: if ((mvlim = movallow()) == 0) {
443:
444: /* he can't */
445: writel (toobad2);
446: writel (*colorptr);
447: writel (cantmv);
448: buflush();
449: sleep (MVPAUSE);
450: nexturn();
451: continue;
452: }
453:
454: /* get move */
455: getmove();
456: }
457: }
458:
459: /* don't worry about who
460: * won if quit */
461: if (cturn == 0)
462: break;
463:
464: /* fix cturn = winner */
465: cturn /= -2;
466:
467: /* final board pos. */
468: if (tflag)
469: refresh();
470:
471: /* backgammon? */
472: mflag = 0;
473: l = bar+7*cturn;
474: for (i = bar; i != l; i += cturn)
475: if (board[i]*cturn) mflag++;
476:
477: /* compute game value */
478: if (tflag)
479: curmove (20,0);
480: if (*offopp == 15) {
481: if (mflag) {
482: writel (bgammon);
483: gvalue *= 3;
484: }
485: else if (*offptr <= 0) {
486: writel (gammon);
487: gvalue *= 2;
488: }
489: }
490:
491: /* report situation */
492: if (cturn == -1) {
493: writel ("Red wins ");
494: rscore += gvalue;
495: } else {
496: writel ("White wins ");
497: wscore += gvalue;
498: }
499: wrint (gvalue);
500: writel (" point");
501: if (gvalue > 1)
502: writec ('s');
503: writel (".\n");
504:
505: /* write score */
506: wrscore();
507:
508: /* check user count */
509: # ifdef CORY
510: if (ucount() > MAXUSERS) {
511: writel (user2a);
512: wrint (MAXUSERS);
513: writel (user2b);
514: rfl = 1;
515: break;
516: }
517: # endif
518:
519: /* see if he wants
520: * another game */
521: writel (again);
522: if ((i = yorn ('S')) == 0)
523: break;
524:
525: init();
526: if (i == 2) {
527: writel (" Save.\n");
528: cturn = 0;
529: save (0);
530: }
531:
532: /* yes, reset game */
533: wrboard();
534: }
535:
536: /* give him a chance to save if game was recovered */
537: if (rfl && cturn) {
538: writel (svpromt);
539: if (yorn (0)) {
540: /* re-initialize for
541: * recovery */
542: init();
543: cturn = 0;
544: save(0);
545: }
546: }
547:
548: /* leave peacefully */
549: getout ();
550: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.