#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\
The Regents of the University of California. All rights reserved.");
#endif
#ifndef lint
#if 0
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: main.c,v 1.36 2024/08/22 20:46:40 rillig Exp $");
#endif
#endif
#include <time.h>
#include "back.h"
#include "backlocal.h"
#define MVPAUSE 5
extern const char *const instr[];
extern const char *const message[];
static const char *const helpm[] = {
"Enter a space or newline to roll, or",
" R to reprint the board\tD to double",
" S to save the game\tQ to quit",
0
};
static const char *const contin[] = {
"(Type a newline to continue.)",
"",
0
};
static const char rules[] = "\nDo you want the rules of the game?";
static const char noteach[] = "Teachgammon not available!\n\a";
static const char need[] = "Do you need instructions for this program?";
static const char askcol[] =
"Enter 'r' to play red, 'w' to play white, 'b' to play both:";
static const char rollr[] = "Red rolls a ";
static const char rollw[] = ". White rolls a ";
static const char rstart[] = ". Red starts.\n";
static const char wstart[] = ". White starts.\n";
static const char toobad1[] = "Too bad, ";
static const char unable[] = " is unable to use that roll.\n";
static const char toobad2[] = ". Too bad, ";
static const char cantmv[] = " can't move.\n";
static const char bgammon[] = "Backgammon! ";
static const char gammon[] = "Gammon! ";
static const char again[] = ".\nWould you like to play again?";
static const char svpromt[] = "Would you like to save this game?";
static const char password[] = "losfurng";
static char pbuf[10];
int
main(int argc __unused, char **argv)
{
int i;
int l;
char c;
time_t t;
struct move mmstore, *mm;
setgid(getgid());
bflag = 2;
signal(SIGINT, getout);
if (tcgetattr(0, &old) == -1)
errexit("backgammon(gtty)");
noech = old;
noech.c_lflag &= ~ECHO;
raw = noech;
raw.c_lflag &= ~ICANON;
ospeed = cfgetospeed(&old);
tflag = getcaps(getenv("TERM"));
if (tflag)
begscr = 0;
t = time(NULL);
srandom((unsigned)t);
mm = &mmstore;
move_init(mm);
while (*++argv != 0)
getarg(mm, &argv);
args[acnt] = '\0';
if (tflag) {
noech.c_oflag &= ~(ONLCR | OXTABS);
raw.c_oflag &= ~(ONLCR | OXTABS);
clear();
}
fixtty(&raw);
if ((rfl = rflag) != 0) {
wrtext(message);
wrtext(contin);
wrboard();
if (cturn == 0)
rflag = 0;
} else {
rscore = wscore = 0;
wrtext(message);
if (aflag) {
writel(rules);
if (yorn(0)) {
fixtty(&old);
execl(TEACH, "teachgammon", args[0]?args:0,
(char *) 0);
tflag = 0;
writel(noteach);
exit(1);
} else {
writel(need);
if (yorn(0)) {
clear();
wrtext(instr);
}
}
}
init();
if (pnum == 2) {
writec('\n');
writel(askcol);
while (pnum == 2) {
c = readc();
switch (c) {
case 'R':
pnum = -1;
break;
case 'W':
pnum = 1;
break;
case 'B':
pnum = 0;
break;
case 'P':
if (iroll)
break;
if (tflag)
curmove(curr, 0);
else
writec('\n');
writel("Password:");
signal(SIGALRM, getout);
cflag = 1;
alarm(10);
for (i = 0; i < 10; i++) {
pbuf[i] = readc();
if (pbuf[i] == '\n')
break;
}
if (i == 10)
while (readc() != '\n');
alarm(0);
cflag = 0;
if (i < 10)
pbuf[i] = '\0';
for (i = 0; i < 9; i++)
if (pbuf[i] != password[i])
getout(0);
iroll = 1;
if (tflag)
curmove(curr, 0);
else
writec('\n');
writel(askcol);
break;
default:
writec('\007');
}
}
} else
if (!aflag)
wrtext(contin);
wrboard();
if (tflag)
curmove(18, 0);
else
writec('\n');
}
if (tflag)
begscr = 17;
for (;;) {
if ((!rflag) || raflag)
roll(mm);
if (!rflag) {
if (tflag)
curmove(17, 0);
while (mm->D0 == mm->D1)
roll(mm);
writel(rollr);
writec(mm->D0 + '0');
writel(rollw);
writec(mm->D1 + '0');
if (mm->D0 > mm->D1) {
writel(rstart);
cturn = 1;
} else {
writel(wstart);
cturn = -1;
}
}
if (cturn == 1) {
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 {
home = 0;
bar = 25;
inptr = &in[0];
inopp = &in[1];
offptr = &off[0];
offopp = &off[1];
Colorptr = &color[0];
colorptr = &color[2];
colen = 5;
}
if (!(rflag && raflag)) {
if (cturn == pnum)
move(mm, 0);
else {
mm->mvlim = movallow(mm);
if (tflag)
curmove(cturn == -1 ? 18 : 19, 0);
proll(mm);
getmove(mm);
}
}
if (tflag) {
curmove(17, 0);
cline();
begscr = 18;
}
rflag = 0;
while (cturn == 1 || cturn == -1) {
if (tflag)
refresh();
else
if (cturn == bflag || bflag == 0)
wrboard();
if (cturn == pnum) {
move(mm, 1);
if (cturn == -2 || cturn == 2)
break;
if (*offopp == 15) {
cturn *= -2;
break;
}
continue;
}
if (tflag && hflag) {
curmove(20, 0);
clend();
hflag = 1;
}
if (dlast != cturn && gvalue < 64) {
if (tflag)
curmove(cturn == -1 ? 18 : 19, 0);
writel(*Colorptr);
c = readc();
switch (c) {
case 'R':
wrboard();
break;
case 'S':
raflag = 1;
save(mm, 1);
break;
case 'Q':
quit(mm);
break;
case 'D':
dble();
break;
case ' ':
case '\n':
roll(mm);
writel(" rolls ");
writec(mm->D0 + '0');
writec(' ');
writec(mm->D1 + '0');
writel(". ");
if ((mm->mvlim = movallow(mm)) == 0) {
writel(toobad1);
writel(*colorptr);
writel(unable);
if (tflag) {
if (pnum) {
buflush();
sleep(MVPAUSE);
}
}
nexturn();
break;
}
getmove(mm);
hflag = 1;
break;
default:
if (tflag)
curmove(20, 0);
else
writec('\n');
wrtext(helpm);
if (tflag)
curmove(cturn == -1 ?
18 : 19, 0);
else
writec('\n');
hflag = 0;
}
} else {
roll(mm);
if (tflag)
curmove(cturn == -1 ? 18 : 19, 0);
proll(mm);
if ((mm->mvlim = movallow(mm)) == 0) {
writel(toobad2);
writel(*colorptr);
writel(cantmv);
buflush();
sleep(MVPAUSE);
nexturn();
continue;
}
getmove(mm);
}
}
if (cturn == 0)
break;
cturn /= -2;
if (tflag)
refresh();
mflag = 0;
l = bar + 7 * cturn;
for (i = bar; i != l; i += cturn)
if (board[i] && cturn)
mflag++;
if (tflag)
curmove(20, 0);
if (*offopp == 15 && (*offptr == 0 || *offptr == -15)) {
if (mflag) {
writel(bgammon);
gvalue *= 3;
} else {
writel(gammon);
gvalue *= 2;
}
}
if (cturn == -1) {
writel("Red wins ");
rscore += gvalue;
} else {
writel("White wins ");
wscore += gvalue;
}
wrint(gvalue);
writel(" point");
if (gvalue > 1)
writec('s');
writel(".\n");
wrscore();
writel(again);
if ((i = yorn('S')) == 0)
break;
init();
if (i == 2) {
writel(" Save.\n");
cturn = 0;
save(mm, 0);
}
wrboard();
}
if (rfl && cturn) {
writel(svpromt);
if (yorn(0)) {
init();
cturn = 0;
save(mm, 0);
}
}
getout(0);
return (0);
}