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