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