void dble() { int resp; /* response to y/n */ for (;;) { addstr(" doubles."); /* indicate double */ if (cturn == -pnum) { /* see if computer accepts */ if (dblgood()) { /* guess not */ addstr(" Declined.\n"); nexturn(); cturn *= -2; /* indicate loss */ return; } else {/* computer accepts */ addstr(" Accepted.\n"); gvalue *= 2; /* double game value */ dlast = cturn; gwrite(); return; } } /* ask if player accepts */ printw(" Does %s accept?", cturn == 1 ? color[2] : color[3]); /* get response from yorn; a "2" means he said "p" to print board. */ if ((resp = yorn ('r')) == 2) { addstr(" Reprint.\n"); moveplayers(); wrboard(); addstr(*Colorptr); continue; } /* check response */ if (resp) { /* accepted */ gvalue *= 2; dlast = cturn; gwrite(); return; } nexturn(); /* declined */ cturn *= -2; return; } }
int checkmove(int ist) { int curr, curc; int j, n; int c; domove: getyx(stdscr, curr, curc); if (ist == 0) mvprintw(curr, 32, "Move: "); ist = mvl = ncin = 0; for (j = 0; j < 5; j++) p[j] = g[j] = -1; dochar: c = readc(); if (c == 'S') { raflag = 0; save(1); move(cturn == -1 ? 18 : 19, 39); ist = -1; goto domove; } if ((c == KEY_BACKSPACE || c == 0177) && ncin > 0) { getyx(stdscr, curr, curc); move(curr, curc - 1); ncin--; n = rsetbrd(); if (n == 0) { n = -1; refresh(); } if ((ist = n) > 0) goto dochar; getyx(stdscr, curr, curc); move(curr, 39); clrtoeol(); goto domove; } else if (c == KEY_DL && ncin > 0) { getyx(stdscr, curr, curc); move(curr, 39); clrtoeol(); ist = -1; refresh(); goto domove; } if (!isascii(c) || (ncin >= CIN_SIZE - 1)) { beep(); goto domove; } n = dotable(c, ist); if (n >= 0) { cin[ncin++] = c; if (n > 2) if (c != '\n') addch(c); ist = n; if (n) goto dochar; else goto domove; } if (n == -1 && mvl >= mvlim) return(0); if (n == -1 && mvl < mvlim-1) return(-4); if (n == -6) { if (movokay(mvl + 1)) { moveplayers(); movback(mvl + 1); } else move(cturn == -1 ? 18 : 19, ncin + 39); ist = n = rsetbrd(); goto dochar; } if (n != -5) return(n); beep(); goto dochar; }
int main (int argc, char **argv) { int i,l; /* non-descript indices */ char c; /* non-descript character storage */ if (pledge("stdio rpath wpath cpath tty exec", NULL) == -1) err(1, "pledge"); signal(SIGINT, getout); /* trap interrupts */ /* use whole screen for text */ begscr = 0; getarg(argc, argv); initcurses(); /* check if restored game and save flag for later */ if ((rfl = rflag)) { if (pledge("stdio rpath wpath cpath tty", NULL) == -1) err(1, "pledge"); wrboard(); /* print board */ /* if new game, pretend to be a non-restored game */ if (cturn == 0) rflag = 0; } else { rscore = wscore = 0; /* zero score */ if (aflag) { /* print rules */ addstr(rules); if (yorn(0)) { endwin(); execl(TEACH, "teachgammon", (char *)NULL); err(1, "%s", noteach); } else {/* if not rules, then instructions */ addstr(need); if (yorn(0)) { /* print instructions */ clear(); text(instruct); } } } if (pledge("stdio rpath wpath cpath tty", NULL) == -1) err(1, "pledge"); init(); /* initialize board */ if (pnum == 2) {/* ask for color(s) */ printw("\n%s", askcol); while (pnum == 2) { c = readc(); switch (c) { case 'R': /* red */ pnum = -1; break; case 'W': /* white */ pnum = 1; break; case 'B': /* both */ pnum = 0; break; case 'P': /* Control the dice */ iroll = 1; addstr("\nDice controlled!\n"); addstr(askcol); break; default: /* error */ beep(); } } } wrboard(); /* print board */ move(18, 0); } /* limit text to bottom of screen */ begscr = 17; for (;;) { /* begin game! */ /* initial roll if needed */ if ((!rflag) || raflag) roll(); /* perform ritual of first roll */ if (!rflag) { move(17, 0); while (D0 == D1) /* no doubles */ roll(); /* print rolls */ printw("%s%d%s%d", rollr, D0, rollw, D1); /* winner goes first */ if (D0 > D1) { addstr(rstart); cturn = 1; } else { addstr(wstart); cturn = -1; } } /* initialize variables according to whose turn it is */ if (cturn == 1) { /* red */ home = 25; bar = 0; inptr = &in[1]; inopp = &in[0]; offptr = &off[1]; offopp = &off[0]; Colorptr = &color[1]; colorptr = &color[3]; colen = 3; } else { /* white */ home = 0; bar = 25; inptr = &in[0]; inopp = &in[1]; offptr = &off[0]; offopp = &off[1]; Colorptr = &color[0]; colorptr = &color[2]; colen = 5; } /* do first move (special case) */ if (!(rflag && raflag)) { if (cturn == pnum) /* computer's move */ domove(0); else { /* player's move */ mvlim = movallow(); /* reprint roll */ move(cturn == -1 ? 18 : 19, 0); proll(); getmove(); /* get player's move */ } } move(17, 0); clrtoeol(); begscr = 18; /* no longer any difference between normal and recovered game. */ rflag = 0; /* move as long as it's someone's turn */ while (cturn == 1 || cturn == -1) { /* board maintainence */ moveplayers(); /* fix board */ /* do computer's move */ if (cturn == pnum) { domove(1); /* see if double refused */ if (cturn == -2 || cturn == 2) break; /* check for winning move */ if (*offopp == 15) { cturn *= -2; break; } continue; } /* (player's move) */ /* clean screen if safe */ if (hflag) { move(20, 0); clrtobot(); hflag = 1; } /* if allowed, give him a chance to double */ if (dflag && dlast != cturn && gvalue < 64) { move(cturn == -1 ? 18: 19, 0); addstr(*Colorptr); c = readc(); /* character cases */ switch (c) { case 'R': /* reprint board */ wrboard(); break; case 'S': /* save game */ raflag = 1; save(1); break; case 'Q': /* quit */ quit(); break; case 'D': /* double */ dble(); break; case ' ': /* roll */ case '\n': roll(); printw(" rolls %d %d. ", D0, D1); /* see if he can move */ if ((mvlim = movallow()) == 0) { /* can't move */ printw("%s%s%s", toobad1, *colorptr, unable); if (pnum) { moveplayers(); sleep(MVPAUSE); } nexturn(); break; } getmove(); /* okay to clean screen */ hflag = 1; break; default: /* invalid character */ /* print help message */ move(20, 0); text(helpm); move(cturn == -1 ? 18 : 19, 0); /* don't erase */ hflag = 0; } } else {/* couldn't double */ /* print roll */ roll(); move(cturn == -1 ? 18: 19, 0); proll(); /* can he move? */ if ((mvlim = movallow()) == 0) { /* he can't */ printw("%s%s%s", toobad2, *colorptr, cantmv); moveplayers(); sleep(MVPAUSE); nexturn(); continue; } getmove(); } } /* don't worry about who won if quit */ if (cturn == 0) break; /* fix cturn = winner */ cturn /= -2; /* final board pos. */ moveplayers(); /* backgammon? */ mflag = 0; l = bar + 7 * cturn; for (i = bar; i != l; i += cturn) if (board[i] * cturn) mflag++; /* compute game value */ move(20, 0); if (*offopp == 15) { if (mflag) { addstr(bgammon); gvalue *= 3; } else if (*offptr <= 0) { addstr(gammon); gvalue *= 2; } } /* report situation */ if (cturn == -1) { addstr("Red wins "); rscore += gvalue; } else { addstr("White wins "); wscore += gvalue; } printw("%d point%s.\n", gvalue, (gvalue > 1) ? "s":""); /* write score */ wrscore(); /* see if he wants another game */ addstr(again); if ((i = yorn('S')) == 0) break; init(); if (i == 2) { addstr(" Save.\n"); cturn = 0; save(0); } /* yes, reset game */ wrboard(); } /* give him a chance to save if game was recovered */ if (rfl && cturn) { addstr(svpromt); if (yorn(0)) { /* re-initialize for recovery */ init(); cturn = 0; save(0); } } /* leave peacefully */ getout(0); /* NOT REACHED */ }
void tutor(void) { int i, j, k; int wrongans; wrongans = 0; i = 0; begscr = 18; cturn = -1; home = 0; bar = 25; inptr = &in[0]; inopp = &in[1]; offptr = &off[0]; offopp = &off[1]; Colorptr = &color[0]; colorptr = &color[2]; colen = 5; wrboard(); while (1) { if (!brdeq(test[i].brd, board)) { wrongans++; move(18, 0); if (wrongans >= 3) { wrongans = 0; text(*test[i].ans); memcpy(board,test[i].brd,26*sizeof(int)); /* and have to fix *inptr, *offptr; player is red (+ve) */ k = 0; for (j = 19; j < 26; j++) k += (board[j] > 0 ? board[j] : 0); *inopp = k; for (j = 0; j < 19; j++) k += (board[j] > 0 ? board[j] : 0); *offopp = k - 30; /* -15 at start */ moveplayers(); clrest(); } else { addstr(better); nexturn(); movback(mvlim); moveplayers(); clrest(); getyx(stdscr, j, k); if (j == 19) { proll(); addch('\t'); } else move(j > 19 ? j - 2 : j + 4, 25); getmove(); if (cturn == 0) leave(); continue; } } else wrongans = 0; move(18, 0); text(*test[i].com); move(19, 0); if (i == maxmoves) break; D0 = test[i].roll1; D1 = test[i].roll2; d0 = 0; mvlim = 0; for (j = 0; j < 4; j++) { if (test[i].mp[j] == test[i].mg[j]) break; p[j] = test[i].mp[j]; g[j] = test[i].mg[j]; mvlim++; } if (mvlim) for (j = 0; j < mvlim; j++) if (makmove(j)) addstr("AARGH!!!\n"); moveplayers(); nexturn(); D0 = test[i].new1; D1 = test[i].new2; d0 = 0; i++; mvlim = movallow(); if (mvlim) { clrest(); proll(); addch('\t'); getmove(); moveplayers(); if (cturn == 0) leave(); } } leave(); }