schoch@trident.arc.nasa.gov (Steve Schoch) (02/13/91)
Submitted-by: schoch@trident.arc.nasa.gov (Steve Schoch) Posting-number: Volume 11, Issue 57 Archive-name: kriegspiel/part02 #!/bin/sh echo x - init.c sed 's/^X//' >init.c <<'*-*-END-of-init.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: init.c,v 1.1 87/02/12 10:58:25 schoch Exp $"; X#endif X X#include "externs.h" X#include <ctype.h> X Xinitdirlists () X{ X LIST linsert (); X dirlist [PAWN] = (LIST) NIL; X dirlist [KING] = linsert (linsert (linsert (linsert (linsert (linsert X (linsert (linsert ((LIST) NIL, -10), -9), 1), 11), 10), 9), -1), -11); X dirlist [KNIGHT] = linsert (linsert (linsert (linsert (linsert (linsert X (linsert (linsert ((LIST)NIL, -19),-8), 12), 21), 19), 8), -12), -21); X dirlist [BISHOP] = linsert (linsert (linsert (linsert X ((LIST) NIL, -9), 11), 9), -11); X dirlist [ROOK] = linsert (linsert (linsert (linsert X ((LIST) NIL, -10), 1), 10), -1); X dirlist [QUEEN] = linsert (linsert (linsert (linsert (linsert (linsert X (linsert (linsert ((LIST) NIL, -10),-9), 1), 11), 10), 9), -1), -11); X} X Xinitpiecelocs () X{ X piecelocs [BLACK] = linsert (linsert (linsert (linsert (linsert X (linsert (linsert (linsert (linsert (linsert (linsert (linsert X (linsert (linsert (linsert (linsert ((LIST) NIL, 11), 12), 13), 14) X , 15), 16), 17), 18), 21), 22), 23), 24), 25), 26), 27), 28); X piecelocs [WHITE] = linsert (linsert (linsert (linsert (linsert X (linsert (linsert (linsert (linsert (linsert (linsert (linsert X (linsert (linsert (linsert (linsert ((LIST) NIL, 71), 72), 73), 74) X , 75), 76), 77), 78), 81), 82), 83), 84), 85), 86), 87), 88); X kingloc [WHITE] = 85; X kingloc [BLACK] = 15; X} X X X#ifdef XKS X/* This needs to be set up before we call initboard. */ X Xu_char whose[100] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, X 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, X 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, X 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, X 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, X 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, X 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, X 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, X 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, X 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; X#endif X Xinitboard(allpieces) X int allpieces; X{ X int row, col, spot, i, j; X static u_char initwhose [100] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, X 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, X 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, X 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, X 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, X 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, X 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, X 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, X 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, X 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; X X static int initoccupant [100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 5, 3, 4, 6, 2, 4, 3, 5, 0, X 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, X 0, 5, 3, 4, 6, 2, 4, 3, 5, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; X X if (ourcolor == WHITE) X theircolor = BLACK; X else if (ourcolor == BLACK) X theircolor = WHITE; X for (i = 0; i < 100; i++) { X whose [i] = initwhose [i]; X occupant [i] = initoccupant [i]; X if (whose[i] == theircolor) X ghost[i] = occupant[i]; X else X ghost[i] = 0; X virgin[i] = TRUE; X } X X for (i = 0; i < 32; i++) { X captured[i] = 0; X disp_captured[i] = 0; X } X#ifndef XKS X for (row = 0; row <= 7; row++) X for (col = 0; col <= 7; col ++) { X if (reverse) { X i = 7 - row; X j = 7 - col; X } else { X i = row; X j = col; X } X spot = 10 * (row + 1) + (col + 1); X blanksq [spot] = subwin (stdscr, sqheight, sqwidth, X sqheight * i, sqwidth * j); X square [spot] = subwin (stdscr, 1, 1, X (sqheight * i) + (sqheight / 2), X (sqwidth * j) + (sqwidth / 2)); X if (reversescr && (row + col) % 2 == 0) { X wstandout (blanksq [spot]); X wstandout (square [spot]); X } X for (i = 1; i <= sqwidth; i++) X for (j = 1; j <= sqheight; j++) X waddch (blanksq [spot], ' '); X waddch (square [spot], sqcolor [(row + col) % 2]); X } X for (row = 1; row <= 2; row++) X for (col = 1; col <= 8; col++) { X if (reverse) X spot = 10 * row + col; X else X spot = 10 * (9 - row) + col; X waddch (square [spot], symbol [occupant [spot]]); X if (allpieces) X waddch (square [99 - spot], tolower X (symbol [occupant [99 - spot]])); X } X#endif XKS X} *-*-END-of-init.c-*-* echo x - input.c sed 's/^X//' >input.c <<'*-*-END-of-input.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: xinput.c,v 1.8 87/05/19 18:46:30 schoch Exp $"; X#endif X X#include "externs.h" X#include <ctype.h> X#include <strings.h> X#include <sys/signal.h> X Xextern int curpos; Xbool note_on; Xbool realmove; Xunsigned int daemon_bits; X Xstatic struct timeval tv = { 0L, 500000L }; X Xhandle_input() X{ X register int c; X X c = getchar(); X if (c == EOF) /* problem! */ X error("stdin"); X if (daemon_bits & D_ESC) { X if (c = doesc(c)) /* Escape sequence finished */ X daemon_bits &= ~D_ESC; X } else if (c == '\033') { X daemon_bits |= D_ESC; X if (seltimeout == 0) X seltimeout = &tv; X return; X } X if (c == '\014') { X redraw(); X return; X } X X if (note_on) { X if (do_note(c)) { X note_on = 0; X move(square[curpos]->_cury + square[curpos]->_begy, X square[curpos]->_curx + square[curpos]->_begx); X } X return; X } X switch (c) { X case '\033': X break; X X case ' ': X startmove(); X break; X X case '\n': X if (moving) X stopmove(); X else X startmove(); X break; X X case 'h': X case 'j': X case 'k': X case 'l': X case 'H': X case 'J': X case 'K': X case 'L': X case K_UP: X case K_DOWN: X case K_LEFT: X case K_RIGHT: X case K_HOME: X cursormove(c); X break; X X case 'a': X case 'A': X any(); X break; X X case 'm': X case 'M': X send_note("", 1); X break; X X case 'd': X case 'D': X draw(); X break; X X case 'y': X case 'Y': X yes(); X break; X X case 'n': X no(); X break; X X X case 'x': X case 'X': X case 'q': X case 'Q': X xit(); X break; X X case 'r': X case 'R': X if (state == PLAYING) X do_resign(); X else if (state == OVER) X replay(); X break; X X case 's': X case 'S': X stop_replay(); X break; X X case 'f': X case 'F': X replay_faster(); X break; X X case 'w': X case 'W': X replay_slower(); X break; X X case '?': X help(); X break; X X case 0: X break; X X default: X putchar('\007'); X if (moving) X droppiece(); X break; X } X} X Xint frompos = 0; Xbool place_printed; X X/* pick a piece up */ Xstartmove() X{ X X if (state != PLAYING) { X message("The game is over!\n", TOMOVE); X return; X } X if (moving) { /* pick up a different piece */ X redraw_gen(curpos); X redraw_gen(frompos); X moving = 0; X frompos = 0; X } X#ifdef GHOST X if (whose[pos] == OFFBOARD) { X int myx; X X if (ourcolor == WHITE && (y < 64*8+TOPSPACE || y > 64*8+TOPSPACE+64)) X return; X if (ourcolor == BLACK && !reverse && X (y < TOPSPACE-64 || y > TOPSPACE)) X return; X if (ourcolor == BLACK && reverse && X (y < 64*8+TOPSPACE || y > 64*8+TOPSPACE+64)) X return; X if (x < 0 || x > 8*64) X return; X myx = x - 16; X if (myx < 0) X pos = 0; X else X pos = myx / 32; X pos += (ourcolor == WHITE) ? 16 : 0; X if (captured[pos] == 0) { X if (myx % 32 < 16) X pos--; X else X pos++; X if (pos < 0) X return; X if (captured[pos] == 0) X return; X } X moving = 1; X deltax = x - (pos%16)*32; X deltay = y-TOPSPACE; X if (ourcolor == WHITE || reverse) X deltay -= 64*8; X else X deltay += 64; X shadow = pieces_icons[captured[pos]]; X frompos = -pos; X realmove = FALSE; X goto done; X } X#endif X if ((occupant[curpos] == 0 || whose[curpos] != ourcolor)) X return; X if (whose[curpos] == ourcolor) { X if (color != ourcolor) { X message("It's not your turn!\n", TOMOVE); X return; X } else if (drawok[theircolor]) { X message("Respond with 'y' or 'n'\n", TOMOVE); X return; X } else X realmove = TRUE; X } else X realmove = FALSE; /* ghost */ X if (!place_printed) { X message("Type CR to place piece.\n", MESSAGE); X place_printed = 1; X } X moving = 1; X daemon_bits |= D_MOVE; X seltimeout = &tv; X frompos = curpos; X} X X/* put a piece down */ Xstopmove() X{ X if (!moving) X return; X X if (curpos == frompos) { X droppiece(); /* didn't go anywhere */ X return; X } X X /* Check if opponent resigned while we were in the process of moving. */ X if (dead || resign || (drawok[BLACK] && drawok[WHITE])) X return droppiece(); X#ifdef GHOST X if (realmove == FALSE) { /* move a ghost */ X if (frompos <= 0) { X frompos = -frompos; X arr = captured; X if (whose[pos] == OFFBOARD) X return; /* it didn't go anywhere */ X } else X arr = ghost; X if (whose[pos] == ourcolor || ghost[pos]) X return; /* A ghost can't capture. */ X if (arr == ghost) X redraw_pos(frompos); X else { X ox = (frompos % 16) * 32; X if (reverse) X oy = TOPSPACE + ((frompos>15) ? -64 : 64*8); X else X oy = TOPSPACE + ((frompos>15) ? 64*8 : -64); X XPixmapPut(window, 0, 0, ox, oy, 64, 64, shadow, GXandInverted, 1); X } X if (whose[pos] == OFFBOARD) { X ghost_capture(frompos); X ghost[frompos] = 0; X return; X } X ghost[pos] = arr[frompos]; X arr[frompos] = 0; X redraw_ghost(pos); X return; X } X#endif X if (whose[curpos] == OFFBOARD) { /* Can't happen */ X droppiece(); X return; X } X domove(frompos, curpos); X daemon_bits &= ~(D_MOVE|D_ON); X if (daemon_bits == 0) X seltimeout = 0; X droppiece(); X X} X Xdroppiece() X{ X if (moving == 0) X return; X redraw_gen(curpos); X redraw_gen(frompos); X frompos = 0; X moving = 0; X} X Xcursormove(dir) Xint dir; X{ X int newpos = curpos; X unsigned long xy; X short x, y; X int incr = reverse ? -1 : 1; X X switch(dir) { X case 'h': X case K_LEFT: X newpos -= incr; X break; X case 'j': X case K_DOWN: X newpos += incr * 10; X break; X case 'k': X case K_UP: X newpos -= incr * 10; X break; X case 'l': X case K_RIGHT: X newpos += incr; X break; X case 'H': X newpos = curpos / 10 * 10 + (reverse ? 8 : 1); X break; X case 'L': X newpos = curpos / 10 * 10 + (reverse ? 1 : 8); X break; X case 'J': X newpos = curpos % 10 + (reverse ? 10 : 80); X break; X case 'K': X newpos = curpos % 10 + (reverse ? 80 : 10); X break; X case K_HOME: X newpos = kingloc[ourcolor]; X break; X } X if (whose[newpos] == OFFBOARD) { X return; X } X if (curpos == newpos) X return; X if (curpos == frompos) X waddch(square[curpos], ' '); X else X redraw_gen(curpos); X curpos = newpos; X if (moving) X waddch (square [curpos], symbol [occupant [frompos]]); X move(square[curpos]->_cury + square[curpos]->_begy, X square[curpos]->_curx + square[curpos]->_begx); X} X Xinput_pending() X{ X refresh(); X fflush(stdout); X return stdin->_cnt; X} X Xdaemon() X{ X if (daemon_bits & (D_MOVE|D_ON)) { X if (moving) { X if (daemon_bits & D_ON) X waddch (square [curpos], symbol [occupant [frompos]]); X else X waddch(square[curpos], '*'); X daemon_bits ^= D_ON; X seltimeout = &tv; X } else { X daemon_bits &= ~(D_MOVE|D_ON); X } X } X X if (daemon_bits & D_ESC) { /* escape time out */ X resetesc(); X daemon_bits &= ~D_ESC; X } X X if (daemon_bits & D_REPLAY) X make_next_move(); X X if (daemon_bits == 0) X seltimeout = 0; X} X Xsend_note(s, n) Xchar *s; X{ X if (dead) { X message("Your opponent is gone.", MESSAGE); X return; X } X note_on = TRUE; X s++; n--; X start_note(); X} X X/* X * sockopen - gets called when socket is ready to connect/accept. X */ Xvoid Xsockopen(data) Xcaddr_t data; X{ X int i = *(int *)data; X X if (finish_conn(i) < 0) { X FD_CLR(i, &writeset); X FD_CLR(i, &readset); X return; X } X mclear(MESSAGE); X message("type ? for help\n", MESSAGE); X state = PLAYING; X refresh (); X dooptions(); X if (ourcolor == WHITE) { X message("--- WHITE ---", MYCOLOR); X reverse = 0; X } else X message("--- BLACK ---", MYCOLOR); X initboard (FALSE); X initesc(); X curpos = kingloc[ourcolor]; X if (ourcolor == WHITE) X message("Type space to pick up piece.\n", MESSAGE); X move(square[curpos]->_cury + square[curpos]->_begy, X square[curpos]->_curx + square[curpos]->_begx); X X FD_SET(fileno(inp), &readset); X} *-*-END-of-input.c-*-* echo x - legalmove.c sed 's/^X//' >legalmove.c <<'*-*-END-of-legalmove.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: legalmove.c,v 1.3 87/02/12 11:01:54 schoch Exp $"; X#endif X X/* legalmove.c */ X#include "externs.h" X Xlegalmove(pawntries, pawnattempts, checkdirs, from, to, color) X int from, to; X int pawntries, *pawnattempts; X LIST checkdirs; X u_char color; X{ X LIST lmember(), piecemoves(); X int i; X static struct { X int from; X int to; X } pawnstried [3]; X X if (whose [from] != color) X return NOWAY; X else if (occupant [from] == KING && to == from + 2) { X if (!virgin [from] /* castle king side */ X || !virgin [from + 3] X || whose [from + 1] == color X || whose [from + 2] == color) X return NOWAY; X else if (checkdirs X || whose [from + 1] != EMPTY X || whose [from + 2] != EMPTY X || moveintocheck (from, from + 1) X || moveintocheck (from, from + 2)) X return ILLEGAL; X else X return TRUE; X } else if (occupant [from] == KING && to == from - 2) { X if (!virgin [from] /* castle queen side */ X || !virgin [from - 4] X || whose [from - 1] == color X || whose [from - 2] == color X || whose [from - 3] == color) X return NOWAY; X else if (checkdirs X || whose [from - 1] != EMPTY X || whose [from - 2] != EMPTY X || whose [from - 3] != EMPTY X || moveintocheck (from, from - 1) X || moveintocheck (from, from - 2)) X return ILLEGAL; X else X return TRUE; X } else if (!lmember (to, piecemoves (from, TRUE))) X return NOWAY; X else if (option [ANNOUNCEPAWNS] == TRUE X && from % 10 != to % 10 X && occupant [from] == PAWN) { X if (pawntries == 0) X return NOWAY; X for (i = 0; i < *pawnattempts; i++) X if (pawnstried [i].from == from X && pawnstried [i].to == to) X return ILLEGAL; X if (*pawnattempts == 3) X return NOMOREPAWNTRIES; X if (lmember(to, piecemoves(from, FALSE)) && X !moveintocheck(from, to)) X return TRUE; X pawnstried [*pawnattempts].from = from; X pawnstried [(*pawnattempts)++].to = to; X if (*pawnattempts == 1) X message("1 attempt\n", MESSAGE); X else { X char buf[128]; X X sprintf(buf, "%d attempts\n", *pawnattempts); X message(buf, MESSAGE); X } X ptmessage = TRUE; X return ILLEGAL; X } else if (!lmember (to, piecemoves (from, FALSE))) X return ILLEGAL; X else if (moveintocheck (from, to)) X return ILLEGAL; X else X return TRUE; X} *-*-END-of-legalmove.c-*-* echo x - list.c sed 's/^X//' >list.c <<'*-*-END-of-list.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: list.c,v 1.3 87/02/12 11:02:40 schoch Exp $"; X#endif X X/* list.c */ X#include "constants.h" X X#ifndef FALSE X#define FALSE 0 X#define TRUE 1 X#endif X Xstruct IN X{ X int i; X struct IN *n; X}; Xtypedef struct IN *LIST; X XLIST Xlinsert (list, number) X LIST list; X int number; X{ X LIST cell; X X char *malloc (); X cell = (LIST) malloc (sizeof (struct IN)); X cell->i = number; X cell->n = list; X return cell; X} X XLIST Xlmember (number, list) X int number; X LIST list; X{ X while (list != NIL) { X if (list->i == number) X return list; X list = list->n; X } X return FALSE; X} X Xlfront (sublist, list) X LIST sublist, list; /* both must be non-NIL */ X /* Allows easy deletion, when combined with lmember. Violent. */ X{ X int n; X X n = list->i; X list->i = sublist->i; X sublist->i = n; X} *-*-END-of-list.c-*-* echo x - main.c sed 's/^X//' >main.c <<'*-*-END-of-main.c-*-*' X/* Kriegspiel written by David Wolfe based on a program by Bert Enderton X May 5, 1986 X X Network interface modified by Steve Schoch <schoch@ames.arpa> X*/ X X#ifndef lint Xstatic char rcsid[] = "$Header: main.c,v 1.3 87/05/19 17:23:17 schoch Exp $"; X#endif X X/* main.c */ X#include "externs.h" X#include <ctype.h> X#include <signal.h> X#include <strings.h> X Xchar symbol [7] = { '-', 'P', 'K', 'N', 'B', 'R', 'Q' }; Xu_char whose [100]; Xu_char occupant [100]; Xextern char *colorname []; Xint pawndir [2] = { -10, 10 }; X XLIST dirlist [7]; XLIST piecelocs [2]; Xint kingloc [2]; XMOVELIST movelist = (MOVELIST) NULL; Xu_char ourcolor = UNSET; Xu_char theircolor; Xint curpos; Xint lastmovefrom = 0; Xint lastmoveto = 0; Xu_char virgin [100]; Xu_char ghost [100]; Xbool drawok [2] = { FALSE, FALSE}; Xbool resign = FALSE; Xbool dead = FALSE; Xu_char color=WHITE, state=CONNECTING; Xu_char option [NOPTIONS]; XWINDOW *blanksq [89]; XWINDOW *square [89]; XWINDOW *win [23]; XWINDOW *backupscreen; XWINDOW *blankscreen; Xint sqheight; Xint sqwidth; Xchar sqcolor [2]; Xbool vtterm; Xbool dumbterm = FALSE; Xbool reversescr; Xbool reverse = TRUE; Xbool iamserver = UNSET; Xbool xks = FALSE; Xbool ptmessage = FALSE; XFILE *inp, *out; Xlong random(); Xextern int sock; Xfd_set readset, writeset; Xstruct timeval *seltimeout; X Xmain (argc, argv, envp) X int argc; X char **argv, **envp; X{ X int i, j, port = 0, trap_sigint(); X char *p, *malloc (); X long time (); X X signal (SIGINT, SIG_IGN); X signal (SIGPIPE, SIG_IGN); X srandom (time((long *) NULL)); X if (!strcmp (argv [1], "help")) { X execle(PRINT_FILE, PRINT_FILE, X HELP_FILE, 0, envp); X perror ("execle"); X exit (1); X } X if (argc <= 1) { X printf ("Usage: %s [-bwcaprsdh] user\n", argv[0]); X printf ("Or for help: %s help\n", argv[0]); X exit (0); X } X FD_ZERO(&readset); X FD_ZERO(&writeset); X FD_SET(0, &readset); X for (i = 0; i < NOPTIONS; i++) X option [i] = UNSET; X j = 0; X for (i = 1; i < argc - 1; i++) { X j = TRUE; X for (p = argv [i]; *p != '\000'; p++) { X if isupper (*p) X *p = tolower (*p); X if (*p == '-') X j = FALSE; X else if (*p == 'b') X option [COLOR] = BLACK; X else if (*p == 'w') X option [COLOR] = WHITE; X else if (*p == 'c') X option [COLOR] = RANDOM; X else if (*p == 'a') X option [ANNOUNCETAKES] = j; X else if (*p == 'p') X option [ANNOUNCEPAWNS] = j; X else if (*p == 'r') X reverse = FALSE; X else if (*p == 's') X iamserver = j; X else if (*p == 'd') X dumbterm = j; X else if (isdigit (*p)) X port = port * 10 + (*p - '0'); X else if (*p == 'h') { X execle(PRINT_FILE, PRINT_FILE, X HELP_FILE, 0, envp); X perror ("execle"); X exit (1); X } X } X } X initdirlists (); X initpiecelocs (); X initscreen (); X refresh(); X signal (SIGINT, trap_sigint); X p = argv [argc - 1]; X message("Connecting...", MESSAGE); X refresh (); X start_conn(p, port); X while (state == CONNECTING) X connect_loop(); X X seltimeout = 0; X X movecycle(0); X} X Xcleanup(sig) X{ X error(0); X} X Xconnect_loop() X{ X int n; X fd_set readfds, writefds; X extern int rw; X X readfds = readset; X writefds = writeset; X n = select(FD_SETSIZE, &readfds, &writefds, 0, seltimeout); X if (n <= 0 && seltimeout && seltimeout->tv_sec == 0) { X seltimeout = 0; X try_conn(NULL); X } X if (n > 0) { X if (FD_ISSET(sock, &readfds)) X sockopen(&rw); X if (FD_ISSET(sock, &writefds)) X sockopen(&rw); X } X return n; X} *-*-END-of-main.c-*-* echo x - makemove.c sed 's/^X//' >makemove.c <<'*-*-END-of-makemove.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: makemove.c,v 1.1 87/02/12 11:03:53 schoch Exp $"; X#endif X X#include "externs.h" X Xmakemove (from, to, color) X int from, to, color; X{ X int victim; X LIST l, lmember (); X MOVELIST newmove; X static MOVELIST lastmove; X char *malloc (); X X newmove = (MOVELIST) malloc (sizeof (struct MOVE)); X newmove -> from = from; X newmove -> to = to; X newmove -> n = NULL; X if (!movelist) X movelist = newmove; X else X lastmove -> n = newmove; X lastmove = newmove; X victim = findvictim (from, to); X if (victim) { X if (option [ANNOUNCETAKES] || whose [victim] == ourcolor) { X char buf[128], *str; X X if (occupant [victim] == PAWN) X str = "pawn"; X else X str = "piece"; X if (reverse) X sprintf(buf, "%s captured: %1c%1d\r", X str, (9 - victim % 10) + 'a' - 1, X victim / 10); X else X sprintf(buf, "%s captured: %1c%1d\r", X str, victim % 10 + 'a' - 1, X 9 - victim / 10); X message(buf, CAPTURE); X } X if (whose[victim] == ourcolor) X redraw_pos(victim); X display_capture(whose[victim], occupant[victim]); X virgin [victim] = FALSE; X whose [victim] = EMPTY; X lfront (lmember (victim, piecelocs [1 - color]), X piecelocs [1 - color]); X piecelocs [1 - color] = (piecelocs [1 - color])->n; X } X l = lmember (from, piecelocs [color]); X l->i = to; X if (occupant [from] == KING) X kingloc [color] = to; X virgin [from] = FALSE; X whose [to] = color; X occupant [to] = occupant [from]; X whose [from] = EMPTY; X occupant [from] = 0; X if (occupant [to] == PAWN X && ((to / 10 == 1 && color == WHITE) X || (to / 10 == 8 && color == BLACK))) { X if (option [ANNOUNCETAKES]) X message("pawn promoted", PAWNWINDOW); X occupant [to] = QUEEN; X } X if (whose [to] == ourcolor) { X redraw_pos(from); X if (ghost[to]) { /* "capture" a ghost */ X ghost_capture(to); X ghost[to] = 0; X redraw_pos(to); X } X redraw_piece(to, 0); X } X} *-*-END-of-makemove.c-*-* echo x - mate.c sed 's/^X//' >mate.c <<'*-*-END-of-mate.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: mate.c,v 1.3 87/02/12 13:23:54 schoch Exp $"; X#endif X X/* mate.c */ X X#include "externs.h" X Xmate (pawnattempts, color) X int pawnattempts; Xu_char color; X{ X LIST l, tos, piecemoves (); X int from, to; X X l = piecelocs [color]; X while (l != NIL) { X from = l->i; X l = l->n; X tos = piecemoves (from, FALSE); X while (tos != NIL) { X to = tos->i; X tos = tos->n; X if (moveintocheck (from, to)) X continue; X if (occupant [from] == PAWN X && from % 10 != to % 10 X && pawnattempts > 3 X && option [ANNOUNCEPAWNS] == TRUE) X continue; X return FALSE; X } X } X return TRUE; X} X Xinsufficient () X{ X int i, p, minorpieces = 0; X LIST l; X X for (i = 0; i < 2; i++) { X l = piecelocs [i]; X while (l != NIL) { X p = occupant [l->i]; X if (p == QUEEN || p == ROOK || p == PAWN) X return FALSE; X if (p == KNIGHT || p == BISHOP) X minorpieces++; X l = l->n; X } X } X return (minorpieces <= 2); X} *-*-END-of-mate.c-*-* echo x - move.c sed 's/^X//' >move.c <<'*-*-END-of-move.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: xmove.c,v 1.5 87/03/31 17:41:49 schoch Exp $"; X#endif X X#include "externs.h" X Xu_char captured[32], disp_captured[32]; X Xdomove(from, to) X{ X X if (whose[from] != ourcolor) { X fprintf(stderr, "Moving wrong piece: %d at %d\n", whose[from], from); X return; X } X if (inp == NULL) { X message("Sorry, lost your opponent.", MESSAGE); X return; X } X fprintf(out, "%1c%1d-%1c%1d\r\n", from%10-1+'a', 9-from/10, X to%10-1+'a', 9-to/10); X if (movetry(from, to, ourcolor)) X return; X} X Xghost_capture(p) X{ X int i; X int n; X X if (theircolor == WHITE) X n = 0; X else X n = 16; X for (i = 0; i < 16; i+=2) X if (disp_captured[n+i] == 0) X break; X if (i >= 16) X for (i = 1; i < 16; i+=2) X if (disp_captured[n+i] == 0) X break; X if (i >= 16) { X fprintf(stderr, "panic: can't find capture space.\n"); X exit(1); X } X disp_captured[i+n] = ghost[p]; X redraw_captured(i+n); X} X Xdisplay_capture(color, piece) Xu_char color, piece; X{ X int i; X int n; X X if (color == WHITE) X n = 0; X else X n = 16; X for (i = 0; i < 16; i+=2) X if (captured[n+i] == 0) X break; X if (i >= 16) X for (i = 1; i < 16; i+=2) X if (captured[n+i] == 0) X break; X if (i >= 16) { X fprintf(stderr, "panic: can't find capture space.\n"); X exit(1); X } X captured[i+n] = piece; X if (color == ourcolor || state != PLAYING) { X disp_captured[n+i] = piece; X redraw_captured(i+n); X } X} *-*-END-of-move.c-*-* echo x - movecycle.c sed 's/^X//' >movecycle.c <<'*-*-END-of-movecycle.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: movecycle.c,v 1.1 87/12/07 17:29:12 schoch Exp $"; X#endif X X#include "externs.h" X#include <sys/time.h> X Xmovecycle() X{ X fd_set readfds, writefds; X extern int sock; X int n; X X for(;;) { X while (input_pending()) X handle_input(); X readfds = readset; X writefds = writeset; X n = select(FD_SETSIZE, &readfds, &writefds, 0, seltimeout); X if (n < 0) { X if (errno == EINTR) X continue; X if (errno == EBADF) { X /* Let's assume it's the socket */ X FD_CLR(0, &readfds); X FD_SET(sock, &readfds); X } else { X perror("select"); X exit(1); X } X } X if (n == 0) { X daemon(); /* must have timed out. */ X continue; X } X if (FD_ISSET(0, &readfds)) X handle_input(); X if (FD_ISSET(sock, &readfds)) X if (handle_sock(inp)) { X FD_CLR(sock, &readfds); X fclose(inp); X fclose(out); X inp = out = NULL; X sock = -1; X } X } X X} *-*-END-of-movecycle.c-*-* echo x - movetry.c sed 's/^X//' >movetry.c <<'*-*-END-of-movetry.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: movecycle.c,v 1.1 87/12/07 17:29:12 schoch Exp $"; X#endif X X#include "externs.h" X Xint pawntries=0; Xchar *colorname[3] = { "white", "black", "undecided" }; X X/* This function is called when either side tries a move. X * If the move is not valid, then we signal an error, no matter X * who tries the move (this is so we can see what our opponent is X * trying. X * If the move is correct, then we toggle color. X */ Xmovetry(from, to, whose) Xu_char whose; X{ X /* We can cheat with this initialization of pawntries because X * we know you can't take a pawn at the beginning of the games. X */ X static pawnattempts=0; X static LIST checkdirs = NIL; X int l; X LIST check (); X char buf[128]; X X mclear (CAPTURE); X if (ptmessage) { X ptmessage = 0; X mclear(MESSAGE); X } X X if ((l = legalmove (pawntries, &pawnattempts, checkdirs, X from, to, color)) != TRUE X && !drawok [color] && !drawok [1 - color] X && !resign && !dead) { X illegal (l, color); X return l; X } X mclear (CHECK); X mclear(LEGAL); X mclear(PAWNWINDOW); X X if (!drawok [1 - color] && !drawok [color] X && !resign && !dead) { X makemove (from, to, color); X if (occupant [to] == KING && to == from + 2) X makemove (from + 3, from + 1, color); X if (occupant [to] == KING && to == from - 2) X makemove (from - 4, from - 1, color); X lastmovefrom = from; X lastmoveto = to; X } else X if (!resign && drawok [1 - color] && !drawok [color]) { X drawok [1 - color] = FALSE; X message("Draw refused.\n", LEGAL); X } X X color = 1 - color; X X checkdirs = check (color); X X if (mate (pawnattempts, color)) { X if (checkdirs != NIL) { X message("CHECKMATE !\n", CHECK); X sprintf(buf, "%s wins.\n", colorname[1 - color]); X message(buf, TOMOVE); X } else { X message("STALEMATE\n", CHECK); X mclear(TOMOVE); X } X state_change(OVER); X mclear(PAWNTRIES); X return 0; X } X if (insufficient () || (drawok [WHITE] && drawok [BLACK])) { X message("Game ends in a draw.\n", CHECK); X mclear(TOMOVE); X mclear(PAWNTRIES); X state_change(OVER); X return 0; X } X if (resign) { X sprintf(buf, "%s resigns.\n", colorname[whose]); X message(buf, CHECK); X mclear(TOMOVE); X mclear(LEGAL); X mclear(PAWNTRIES); X state_change(OVER); X return 0; X } X if (dead) { X message("DEAD\n", CHECK); X message("lost your opponent (sorry)\n", MESSAGE); X state_change(OVER); X return 0; X } X X pawnattempts = 0; X pawntries = countpawntries (color); X if (drawok[1 - color]) { X message("Draw offered.\n", LEGAL); X if (color == ourcolor) X message("Type y or n.\n", TOMOVE); X else X mclear(TOMOVE); X } else { X sprintf(buf, "%s to move\n", colorname[color]); X message(buf, TOMOVE); X } X X if (option [ANNOUNCEPAWNS]) { X if(pawntries && pawnattempts < 3) { X if (pawntries == 1) X strcpy(buf, "1 pawntry\n"); X else X sprintf(buf, "%d pawntries\n", pawntries); X message(buf, PAWNTRIES); X } else X mclear(PAWNTRIES); X } else X mclear(PAWNTRIES); X X reportchecks (checkdirs, kingloc [color]); X if (color == theircolor) X hismove(); X return 0; X} *-*-END-of-movetry.c-*-* echo x - options.c sed 's/^X//' >options.c <<'*-*-END-of-options.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: options.c,v 1.1 87/02/12 11:06:21 schoch Exp $"; X#endif X X#include "externs.h" X#include <strings.h> X Xdooptions() X{ X register i; X char *cp; X char optbuf[128]; X u_char nopts[NOPTIONS]; X X if (iamserver) { X if (fgets(optbuf, sizeof optbuf, inp) == NULL) X if (ferror(inp)) X error ("recv in dooptions"); X else X return 0; X if (cp = index(optbuf, '\n')) X *cp = '\0'; X if (cp = index(optbuf, '\r')) X *cp = '\0'; X for (i = 0; optbuf[i]; i++) X if (optbuf[i] >= '0' && optbuf[i] <= '9') X nopts[i] = optbuf[i] - '0'; X else X nopts[i] = UNSET; X while (i < NOPTIONS) X nopts[i++] = UNSET; X for (i = 0; i < NOPTIONS; i++) { X if (option [i] == UNSET || nopts[i] == UNSET) X nopts[i] = option [i] = option[i] + nopts[i] - UNSET; X if (option [i] == UNSET) X if (i == COLOR) X option [i] = nopts[i] = RANDOM; X else X option [i] = nopts[i] = TRUE; X else if (option [i] != nopts[i]) X option [i] = nopts[i] = RANDOM; X if (option [i] == RANDOM) X option [i] = nopts[i] = random () & 01; X } X for (i = 0; i < NOPTIONS; i++) X optbuf[i] = nopts[i] + '0'; X optbuf[i] = '\0'; X fprintf(out, "%s\r\n", optbuf); X } else { X for (i = 0; i < NOPTIONS; i++) X nopts[i] = option [i]; X if (nopts[COLOR] == WHITE || nopts[COLOR] == BLACK) X nopts[COLOR] = ! option [COLOR]; X for (i = 0; i < NOPTIONS; i++) X optbuf[i] = nopts[i] + '0'; X optbuf[i] = '\0'; X fprintf(out, "%s\r\n", optbuf); X if (fgets(optbuf, sizeof optbuf, inp) == NULL) X if (errno != EINTR) X error ("recv in dooptions"); X if (cp = index(optbuf, '\n')) X *cp = '\0'; X if (cp = index(optbuf, '\r')) X *cp = '\0'; X for (i = 0; optbuf[i]; i++) X option[i] = optbuf[i] - '0'; X option [COLOR] = !(optbuf[COLOR]-'0'); X } X ourcolor = option [COLOR]; X} *-*-END-of-options.c-*-* echo x - output.c sed 's/^X//' >output.c <<'*-*-END-of-output.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: output.c,v 1.1 87/02/12 11:07:18 schoch Exp $"; X#endif X X#include "externs.h" X#include <strings.h> X Xextern bool place_printed; X Xredraw () X{ X int i; X X if (vtterm) { X /* make characters double-width on a vt100 type terminal */ X overwrite (stdscr, backupscreen); X overwrite (blankscreen, stdscr); X refresh (); X printf("\0337\033[0;0H\033#6"); /* save cursor, home, X and widen first line */ X for (i = 1; i <= LINES - 1; i++) X printf("\n\033#6"); /* wide next line */ X printf("\0338"); /* restore cursor */ X overwrite (backupscreen, stdscr); X refresh(); X } else X wrefresh(curscr); X} X Xreportchecks (checkdirs, kingloc) X LIST checkdirs; X int kingloc; X{ X LIST l, lmember (); X int quadrant, n; X char str [2] [40]; X X n = 0; X quadrant = ((kingloc % 10 > 4) == (kingloc/10 < 5)); X if (lmember (-9, checkdirs) || lmember (9, checkdirs)) X if (quadrant == 1) X strcpy (str[n++], "long diagonal\n"); X else X strcpy (str[n++], "short diagonal\n"); X if (lmember (-11, checkdirs) || lmember (11, checkdirs)) X if (quadrant == 0) X strcpy (str[n++], "long diagonal\n"); X else X strcpy (str[n++], "short diagonal\n"); X if (lmember (-10, checkdirs) || lmember (10, checkdirs)) X strcpy (str[n++], "file\n"); X if (lmember (-1, checkdirs) || lmember (1, checkdirs)) X strcpy (str[n++], "rank\n"); X l = dirlist [KNIGHT]; X while (l != NIL) { X if (lmember (l->i, checkdirs)) X strcpy (str[n++], "knight\n"); X l = l->n; X } X if (n > 0) { X waddstr (win [CHECK], "check by the\n"); X waddstr (win [CHECK], str[0]); X } X if (n == 2) { X waddstr (win [CHECK], "and "); X waddstr (win [CHECK], str[1]); X } X refresh(); X} X Xillegal (why, color) X int color, why; X{ X wclear (win [LEGAL]); X if (why == ILLEGAL) X waddstr (win [LEGAL], "illegal"); X else if (color == ourcolor) { X if (why == NOMOREPAWNTRIES) X waddstr (win [LEGAL], "3 pawns tried"); X else if (why == NOWAY) X waddstr (win [LEGAL], "no way"); X else if (why == AMBIGUOUS) X waddstr (win [LEGAL], "ambiguous"); X } else X waddstr (win [LEGAL], "nope"); X} X Xhelp() X{ X if (state == REVIEW) X if (out) X message("Type (S)top, (F)aster, (W)Slower, e(X)it, or (M)essage\n", X MESSAGE); X else X message("Type (S)top, (F)aster, (W)Slower, or e(X)it\n", MESSAGE); X else if (state == OVER) X if (out) X message("Type (R)eview, e(X)it, or (M)essage\n", MESSAGE); X else X message("Type (R)eview or e(X)it\n", MESSAGE); X else if (drawok[theircolor] && !drawok[ourcolor]) X message("Type (Y)es, (N)no, or (M)essage\n", MESSAGE); X else X message("Type (R)esign, (D)raw, or (M)essage\n", MESSAGE); X} X Xxit() X{ X if (state == PLAYING) { X message("Type (R)esign or (D)raw first.\n", MESSAGE); X return; X } X cleanup(0); X} X Xmymove() X{ X if (state == PLAYING) X message("Type space to pick up piece.\n", MESSAGE); X place_printed = 0; X putchar('\007'); X fflush(stdout); X} X XBeep() X{ X putchar('\007'); X fflush(stdout); X} X Xhismove() X{ X} X Xstate_change(newstate) X{ X int n; X int oldstate = state; X X switch (state = newstate) { X case OVER: X if (oldstate == PLAYING) { X ; X } else { X ; X } X break; X case REVIEW: X break; X } X} *-*-END-of-output.c-*-* echo x - pawntries.c sed 's/^X//' >pawntries.c <<'*-*-END-of-pawntries.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: pawntries.c,v 1.3 87/02/12 13:23:56 schoch Exp $"; X#endif X X/* "pawntries.c */ X#include "externs.h" X Xcountpawntries (color) Xu_char color; X{ X LIST l, moves, piecemoves (); X int tries, /* move,*/ start, end; X X tries = 0; X l = piecelocs [color]; X while (l != NIL) { X start = l->i; X l = l->n; X if (occupant [start] != PAWN) X continue; X moves = piecemoves (start, FALSE); X while (moves != NIL) { X end = moves->i; X moves = moves->n; X if (start % 10 == end % 10) X continue; X if (moveintocheck (start, end)) X continue; X tries++; X } X } X return tries; X} X X Xfindvictim (from, to) X int from, to; X{ X if (occupant [from] == PAWN) { X if (from % 10 == to % 10) X return FALSE; X if (whose [to] == 1 - whose [from]) X return to; X else X return (to - pawndir [whose [from]]); /* en passent */ X } else { X if (whose [to] == 1 - whose[from]) X return to; X else X return FALSE; X } X} *-*-END-of-pawntries.c-*-* echo x - piecemoves.c sed 's/^X//' >piecemoves.c <<'*-*-END-of-piecemoves.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: piecemoves.c,v 1.1 87/02/12 11:08:18 schoch Exp $"; X#endif X X#include "externs.h" X XLIST Xpiecemoves (from, ignoreenemy) X /* doesn't include castling */ X int from, ignoreenemy; X{ X int piece, color, front, spot, side, addend, to; X LIST dirs, moves, linsert (); X X piece = occupant [from]; X color = whose [from]; X moves = NIL; X if (piece == PAWN) { X front = from + pawndir [color]; X if (whose [front] != color X && (ignoreenemy || whose [front] == EMPTY)) { X moves = linsert (moves, front); X if (from / 10 == 7 - 5 * color) { /* pawn can move 2 */ X spot = front + pawndir [color]; X if (whose [spot] != color X && (ignoreenemy || whose [spot] == EMPTY)) X moves = linsert (moves, spot); X } X } X for (side = -1; side <= 1; side += 2) { X spot = front + side; X if (whose [spot] != color X && whose [spot] != OFFBOARD X && (ignoreenemy || whose [spot] == 1 - color X || (from / 10 == 4 + color /* en passent */ X && occupant [from + side] == PAWN X && lastmovefrom == spot + pawndir [color] X && lastmoveto == from + side))) X moves = linsert (moves, spot); X } X } else { X dirs = dirlist [piece]; X while (dirs != NIL) { X addend = dirs->i; X dirs = dirs->n; X to = from; X while (TRUE) { X to += addend; X if (to < 0 || to > 99) X break; X if (whose [to] == OFFBOARD X || whose [to] == color) X break; X moves = linsert (moves, to); X if (ignoreenemy == FALSE X && whose [to] == 1 - color) X break; X if (piece == KING || piece == KNIGHT) X break; X } X } X } X return moves; X} *-*-END-of-piecemoves.c-*-* echo x - review.c sed 's/^X//' >review.c <<'*-*-END-of-review.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: review.c,v 1.4 87/05/19 18:45:56 schoch Exp $"; X#endif X X#include "externs.h" X#define STEPTIME 3*1000 /* time between moves */ X#define MINSTEPTIME 100 /* 1/10 second */ X Xstatic void make_next_move(); X Xstatic long steptime; Xstatic MOVELIST m; Xstatic r_color; X#ifdef XKS Xstatic XtIntervalId replay_id; X#else Xstatic struct timeval tv; X#endif X/* X * Show a review of the game, with all pieces showing. I assume this doesn't X * get called when we're playing. X */ Xreview () X{ X auto int fds; X X if (state == REVIEW) { X message("Already showing review\n", MESSAGE); X return; X } X state_change(REVIEW); X initdirlists (); X initpiecelocs (); X initboard (TRUE); X r_color = WHITE; X steptime = STEPTIME; X#ifndef XKS X touchwin (stdscr); X#else X redraw_board(); X redraw_pieces(); X#endif X m = movelist; X#ifdef XKS X replay_id = XtAppAddTimeOut(my_app, steptime, make_next_move, NULL); X#else X tv.tv_usec = (steptime % 1000) * 1000; X tv.tv_sec = steptime / 1000; X seltimeout = &tv; X daemon_bits = D_REPLAY; X#endif X} X Xreplay_faster() X{ X /* decrease steptime by 33% */ X#ifdef XKS X XtRemoveTimeOut(replay_id); X#endif X steptime -= steptime / 3; X if (steptime < MINSTEPTIME) X steptime = MINSTEPTIME; X make_next_move(); X} X Xreplay_slower() X{ X /* increase steptime by 50% */ X steptime += steptime / 2; X} X Xstop_replay() X{ X if (state != REVIEW) X return; X state_change(OVER); X#ifdef XKS X if (replay_id == NULL) X return; X XtRemoveTimeOut(replay_id); X replay_id = NULL; X#endif X} X Xvoid Xmake_next_move() X{ X if (state != REVIEW) /* somebody stopped us. */ X return; X if (m == 0) X goto out; X if (occupant[m->from] == KING && X ((m->to - m->from) == 2 || X (m->from - m->to) == 2)) { /* castling */ X makereviewmove (m -> from, m -> to, r_color); X m = m->n; X } X if (m == 0) X goto out; X makereviewmove (m -> from, m -> to, r_color); X#ifndef XKS X refresh(); X#endif X r_color = 1 - r_color; X m = m -> n; X#ifdef XKS X if (m) { X replay_id = XtAppAddTimeOut(my_app, steptime, make_next_move, NULL); X return; X } Xout: X replay_id = NULL; X state_change(OVER); X#else X if (m) { X tv.tv_usec = (steptime % 1000) * 1000; X tv.tv_sec = steptime / 1000; X seltimeout = &tv; X return; X } Xout: X daemon_bits &= ~D_REPLAY; X return; X#endif X} X Xmakereviewmove (from, to, color) X int from, to, color; X{ X int victim; X#ifndef XKS X char buf[128]; X X mclear(INPUT); X#endif X if (victim = findvictim (from, to)) { X display_capture(whose[victim], occupant[victim]); X whose [victim] = EMPTY; X occupant[victim] = 0; X redraw_pos(victim); X } X whose [to] = color; X occupant [to] = occupant [from]; X whose [from] = EMPTY; X occupant [from] = 0; X if (occupant [to] == PAWN X && ((to / 10 == 1 && color == WHITE) X || (to / 10 == 8 && color == BLACK))) X occupant [to] = QUEEN; X redraw_pos(from); X redraw_piece(to, 0); X#ifndef XKS X if (reverse) { X from = 99 - from; X to = 99 - to; X } X sprintf(buf, ": %1c%1d-%1c%1d", 'a' + (9-from%10)-1, (9-from/10), X 'a' + (9 - to%10)-1, (9 - to/10)); X message(buf, INPUT); X#endif X} *-*-END-of-review.c-*-* echo x - screen.c sed 's/^X//' >screen.c <<'*-*-END-of-screen.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: screen.c,v 1.1 87/02/12 11:11:03 schoch Exp $"; X#endif X X#include "externs.h" X#include <ctype.h> X Xmessage(s, where) Xchar *s; X{ X if (where == PAWNWINDOW) X where = MESSAGE; X waddch(win[where], '\r'); X waddstr(win[where], s); X} X Xmclear(where) X{ X if (win[where]) X wclear(win[where]); X} X Xinitscreen () X{ X int ww, ws1, ws2, ws3, ws; X char *termtype, *getenv(); X X termtype = getenv("TERM"); X vtterm = (!strncmp(termtype, "vt", 2) && !dumbterm); X if (vtterm) X COLS = 40; X if (dumbterm) X LINES = 10; X initscr(); X noecho(); X crmode(); X if (SO == NIL || dumbterm) X reversescr = FALSE; X else X reversescr = TRUE; X if (vtterm) { X sqheight = 3; X sqwidth = 3; X sqcolor [WHITE] = ' '; X sqcolor [BLACK] = ' '; X blankscreen = newwin (LINES, COLS, 0, 0); X } else if (reversescr) { X sqheight = 3; X sqwidth = 5; X sqcolor [WHITE] = ' '; X sqcolor [BLACK] = ' '; X } else { X sqheight = 1; X sqwidth = 2; X sqcolor [WHITE] = '.'; X sqcolor [BLACK] = '*'; X } X backupscreen = newwin (LINES, COLS, 0, 0); X if (vtterm) X ws = sqwidth * 8 + 1; X else if (dumbterm) X ws = sqwidth * 8 + 4; X else X ws = sqwidth * 8 + 2; X ww = COLS - ws; X if (dumbterm) { X ww = ww / 3 - 1; X ws1 = ws + 1; X ws2 = ws1 + ww + 1; X ws3 = ws2 + ww + 1; X win [MYCOLOR] = subwin (stdscr, 1, 15 , 9, 3); X win [TOMOVE] = subwin (stdscr, 1, ww , 1, ws3); X win [CLOCK] = newwin (/*none*/1, 1 , 1, 1); X win [CAPTURE] = subwin (stdscr, 1, ww , 3, ws3); X win [PAWNTRIES] = subwin (stdscr, 1, ww , 4, ws3); X win [CHECK] = subwin (stdscr, 3, ww , 5, ws3); X win [PROMPT] = subwin (stdscr, 1, ww , 1, ws1); X win [INPUT] = subwin (stdscr, 3, ww , 2, ws1); X win [LEGAL] = subwin (stdscr, 1, ww , 5, ws1); X win [MESSAGE] = subwin (stdscr, 4, ww , 1, ws2); X win [OPPONENT] = subwin (stdscr, 5, ww , 5, ws2); X } else { X win [MYCOLOR] = subwin (stdscr, 1, ww , 1, ws); X win [TOMOVE] = subwin (stdscr, 1, ww - 1, 3, ws); X win [CLOCK] = subwin (stdscr, 1, 1, 3, COLS-1); X win [CAPTURE] = subwin (stdscr, 1, ww , 5, ws); X win [PAWNTRIES] = subwin (stdscr, 1, ww , 6, ws); X win [CHECK] = subwin (stdscr, 3, ww , 7, ws); X win [PROMPT] = subwin (stdscr, 1, ww , 10, ws); X win [INPUT] = subwin (stdscr, 3, ww , 11, ws); X win [LEGAL] = subwin (stdscr, 1, ww , 14, ws); X win [MESSAGE] = subwin (stdscr, 5, ww , 15, ws); X win [OPPONENT] = subwin (stdscr, 4, ww , 20, ws); X scrollok (win [MESSAGE], TRUE); X scrollok (win [INPUT], TRUE); X } X} X Xredraw_pos(pos) X{ X waddch(square[pos], sqcolor[(pos + pos / 10) % 2]); X} X Xredraw_piece(pos) X{ X if (whose[pos] == ourcolor) X waddch(square[pos], symbol[occupant[pos]]); X else X waddch(square[pos], tolower(symbol[occupant[pos]])); X} X X/* This routine is not needed. */ Xredraw_pieces() X{ X} X Xredraw_gen(pos) X{ X if (whose[pos] == ourcolor || X (state != PLAYING && whose[pos] != EMPTY)) X redraw_piece(pos); X else X redraw_pos(pos); X} X Xredraw_captured() X{ X} X Xredraw_board() X{ X int x, y; X X for (y = 1; y <= 8; y++) X for (x = 1; x <= 8; x++) X redraw_pos(y*10+x); X} X X#define start_pos 9 X Xstart_note() X{ X wclear(win[INPUT]); X scrollok(win[INPUT], 0); X message("Message: ", INPUT); X wmove(win[INPUT], start_pos, 0); X move(win[INPUT]->_cury + win[INPUT]->_begy, X win[INPUT]->_curx + win[INPUT]->_begx); X} X Xdo_note(c) Xint c; X{ X int x, y; X X switch(c) { X case '\b': X case '\0177': /* DELETE */ X (void)end_char(); X wclrtobot(win[INPUT]); X break; X X case '\025': /* control-U */ X case '\030': /* control-X */ X getyx(win[INPUT], y, x); X if (x == 0 && y > 0) X y--; X if (y == 0) X wmove(win[INPUT], y, start_pos); X else X wmove(win[INPUT], y, 0); X wclrtoeol(win[INPUT]); X break; X X case '\027': /* Control-W */ X while (end_char() == ' ') X ; X while ((c = end_char()) && c != ' ') X ; X waddch(win[INPUT], c); X wclrtobot(win[INPUT]); X break; X X case '\n': X case '\r': X xmit_note(); X return 1; X X case '\014': X redraw(); X break; X X case K_UP: X getyx(win[INPUT], y, x); X if (y > 0) X y--; X if (y == 0 && x < start_pos) X x = start_pos; X wmove(win[INPUT], y, x); X break; X X case K_DOWN: X getyx(win[INPUT], y, x); X y++; X if (y >= win[INPUT]->_maxy) X y = win[INPUT]->_maxy - 1; X wmove(win[INPUT], y, x); X break; X X case K_LEFT: X getyx(win[INPUT], y, x); X if (x > 0 && (y > 0 || x > start_pos)) X x--; X wmove(win[INPUT], y, x); X break; X X case K_RIGHT: X getyx(win[INPUT], y, x); X x++; X if (x >= win[INPUT]->_maxx) X x = win[INPUT]->_maxx - 1; X wmove(win[INPUT], y, x); X break; X X case 0: X break; X X default: X if (!isprint(c&0x7f)) { X waddstr(win[INPUT], unctrl(c&0x7f)); X } else X waddch(win[INPUT], c&0x7f); X break; X } X move(win[INPUT]->_cury + win[INPUT]->_begy, X win[INPUT]->_curx + win[INPUT]->_begx); X return 0; X} X Xend_char() X{ X int y, x, c; X X getyx(win[INPUT], y, x); X if (y > 0 || x > start_pos) { X if (x == 0) { X x = win[INPUT]->_maxx - 1; X y--; X } else X x--; X wmove(win[INPUT], y, x); X return winch(win[INPUT]); X } X return 0; X} X Xxmit_note() X{ X /* This will be a little over, but who cares? */ X int len = win[INPUT]->_maxx * win[INPUT]->_cury + 1; X char *buf; X register char *cp; X X buf = (char *)malloc(len); X if (buf == 0) X error("malloc"); X cp = buf + len; X *--cp = '\0'; X while (*--cp = end_char()) X ; X cp++; X fprintf(out, "say %s\r\n", cp); X} *-*-END-of-screen.c-*-* echo x - traps.c sed 's/^X//' >traps.c <<'*-*-END-of-traps.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: traps.c,v 1.2 87/02/12 11:11:36 schoch Exp $"; X#endif X X#include "externs.h" X#include <signal.h> X Xtrap_sigint(sig) X{ X int y, x; X int iy, ix; X char c; X X if (state == OVER) X error(0); X signal (SIGINT, SIG_IGN); X getyx (stdscr, y, x); X getyx (win[INPUT], iy, ix); X overwrite (stdscr, backupscreen); X wclear (win [PROMPT]); X wclear (win [MESSAGE]); X wclear (win [INPUT]); X message("Quit?", PROMPT); X message("type y or n\n", MESSAGE); X waddstr (win [INPUT], ": "); X move (win [INPUT]->_cury + win [INPUT]->_begy, X win [INPUT]->_curx + win [INPUT]->_begx); X refresh (); X c = getchar(); X while (c!='n' && c!='N' && c!='y' && c!='Y') { X if (c == '\f') /* ^L */ X refresh (); X c = getchar(); X } X if (c == 'y') { X if (out) X fputs("resign\r\n", out); X error ((char *) NULL); X } X overwrite (backupscreen, stdscr); X move (y, x); X wmove(win[INPUT], iy, ix); X refresh(); X signal (SIGINT, trap_sigint); X} *-*-END-of-traps.c-*-* echo x - xboard.c sed 's/^X//' >xboard.c <<'*-*-END-of-xboard.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: xboard.c,v 1.6 87/05/19 17:21:01 schoch Exp $"; X#endif X X#include "externs.h" X Xstatic deltax, deltay; Xstatic oldx, oldy; Xstatic Pixmap shadow; Xstatic int frompos; Xstatic bool realmove; X Xextern GC move_gc; X X#define piece_width 64 X#define piece_height 64 X Xstartmove(x, y) X{ X int pos; X int posx, posy; X X if (moving) X return; X pos = xytopos(x, y); X postoxy(pos, &posx, &posy); X if (pos < 0) X return; X if (pos >= 100) { X fprintf(stderr, "Help! pos out of range.\n"); X return; X } X if (dead || state == OVER) { X message("The game is over!", TOMOVE); X return; X } X if (whose[pos] == OFFBOARD) { X int myx; X X if (ourcolor == WHITE && pos/10 != 9) X return; X if (ourcolor == BLACK && pos/10 != 0) X return; X myx = x - 16; X if (myx < 0) X pos = 0; X else X pos = myx / 32; X if (pos > 15) X return; X pos += (ourcolor == WHITE) ? 16 : 0; X if (disp_captured[pos] == 0) { X if (myx % 32 < 16) X pos--; X else X pos++; X if (pos < 0) X return; X if (disp_captured[pos] == 0) X return; X } X moving = 1; X deltax = x - (pos%16)*32; X deltay = y - posy; X shadow = pieces_icons[disp_captured[pos]]; X frompos = -pos; X realmove = FALSE; X goto done; X } X if ((occupant[pos] == 0 || whose[pos] == theircolor) && ghost[pos] == 0) X return; X if (whose[pos] == ourcolor) { X if (color != ourcolor) { X message("It's not your turn!", TOMOVE); X return; X } else if (drawok[theircolor]) { X message("Respond with 'y' or 'n'", TOMOVE); X return; X } else X realmove = TRUE; X } else X realmove = FALSE; /* ghost */ X moving = 1; X frompos = pos; X deltax = x - posx; X deltay = y - posy; X X /* Do sanity checking here! */ X if (ghost[pos]) X shadow = pieces_icons[ghost[pos]]; X else X shadow = pieces_icons[occupant[pos]]; Xdone: X oldx = x; X oldy = y; X XCopyArea(XtDisplay(board), shadow, XtWindow(board), move_gc, X 0, 0, 64, 64, x-deltax, y-deltay); X} X Xstopmove() X{ X bool *arr; X int tpos; X int pos; X X droppiece(); X X pos = xytopos(oldx, oldy); X if (pos < 0) /* out of window */ X return; X if (pos == frompos) X return; /* didn't move anywhere */ X X /* Check if opponent resigned while we were in the process of moving. */ X if (dead || resign || (drawok[BLACK] && drawok[WHITE])) X return; X if (realmove == FALSE) { /* move a ghost */ X if (frompos <= 0) { X frompos = -frompos; X arr = disp_captured; X if (whose[pos] == OFFBOARD) X return; /* it didn't go anywhere */ X } else X arr = ghost; X if (whose[pos] == ourcolor || ghost[pos]) X return; /* A ghost can't capture. */ X if (arr == ghost) X redraw_pos(frompos); X else { X int cpos; X X if (frompos < 16) X tpos = 1; X else X tpos = 91; X X if (reverse) X tpos += 7 - ((frompos % 16) / 2); X else X tpos += (frompos % 16) / 2; X redraw_pos(tpos); X X if (frompos&1) { X redraw_captured(frompos-1); X if ((frompos-1)%16) X redraw_captured(frompos-2); X if (frompos%16 < 15) { X if (reverse) X tpos--; X else X tpos++; X redraw_pos(tpos); X redraw_captured(frompos+1); X redraw_captured(frompos+2); X } X } else { X if (frompos%16) X redraw_captured(frompos-1); X redraw_captured(frompos+1); X } X } X if (whose[pos] == OFFBOARD) { X ghost_capture(frompos); X ghost[frompos] = 0; X return; X } X ghost[pos] = arr[frompos]; X arr[frompos] = 0; X redraw_piece(pos, True); X return; X } X if (whose[pos] == OFFBOARD) { X return; X } X domove(frompos, pos); X X} X Xpiecemove(x, y) Xregister x, y; X{ X X if (oldx==x && oldy==y) X return; X XCopyArea(XtDisplay(board), shadow, XtWindow(board), move_gc, X 0, 0, piece_width, piece_height, oldx-deltax, oldy-deltay); X XCopyArea(XtDisplay(board), shadow, XtWindow(board), move_gc, X 0, 0, piece_width, piece_height, x-deltax, y-deltay); X oldx=x; X oldy=y; X} X Xdroppiece() X{ X if (!moving) X return; X moving = 0; X /* Remove shadow */ X XCopyArea(XtDisplay(board), shadow, XtWindow(board), move_gc, X 0, 0, 64, 64, oldx-deltax, oldy-deltay); X} *-*-END-of-xboard.c-*-* echo x - xinput.c sed 's/^X//' >xinput.c <<'*-*-END-of-xinput.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: xinput.c,v 1.8 87/05/19 18:46:30 schoch Exp $"; X#endif X X#include "externs.h" X#include <ctype.h> X#include <strings.h> X X/* Takes window coordinates and returns a board position from 0-99. X * returns -1 if point is not on board. */ Xxytopos(x, y) X{ X x += 64; X if (y < 0 || x < 0) X return -1; X x /= 64; X y /= 64; X if (x > 9 || y > 9) X return -1; X if (reverse) { X y = 9 - y; X x = 9 - x; X } X return (y * 10) + x; X} X Xvoid Xsockcallback(data, source, id) Xcaddr_t data; Xint *source; XXtInputId *id; X{ X int n; X X if (*source != fileno(inp)) { X printf("input: %d != %d\n", *source, fileno(inp)); X return; /* Something's wrong. */ X } X do { X if (handle_sock(inp)) { X fclose(inp); X inp = NULL; X XtRemoveInput(*id); X return; X } X } while (inp->_cnt); X} X X/* X * sockopen - gets called when socket is ready to connect/accept. X */ Xvoid Xsockopen(data, source, id) Xcaddr_t data; Xint *source; XXtInputId *id; X{ X int i = *(int *)data; X XtInputId oldid = NULL; X X if (id) X oldid = *id; X if (finish_conn(i) < 0) { X if (oldid) X XtRemoveInput(oldid); X return; X } X dooptions(); X state = PLAYING; X XtSetSensitive(message_wins[MYCOLOR], True); X XtSetSensitive(c_message, True); X XtSetSensitive(c_resign, True); X mclear(MESSAGE); X X XtSetSensitive(message_wins[TOMOVE], True); X if (ourcolor == WHITE) { X message("--- WHITE ---", MYCOLOR); X mymove(0); X reverse = False; X } else { X message("--- BLACK ---", MYCOLOR); X hismove(); X } X initboard(False); X redraw_pieces(); X X /* Make capture area the correct color. */ X for (i = 1; i <= 8; i++) X redraw_pos(i); X for (i = 91; i <= 98; i++) X redraw_pos(i); X if (oldid) X XtRemoveInput(oldid); X sockid = XtAppAddInput(my_app, fileno(inp), XtInputReadMask, X sockcallback, NULL); X} *-*-END-of-xinput.c-*-* echo x - xmain.c sed 's/^X//' >xmain.c <<'*-*-END-of-xmain.c-*-*' X#ifndef lint Xstatic char rcsid[] = "$Header: xmain.c,v 1.7 87/05/19 17:19:25 schoch Exp $"; X#endif X X#include <strings.h> X#include <ctype.h> X#include <sys/signal.h> X#include <errno.h> X#include "externs.h" X Xextern int errno; X XLIST dirlist[7]; XLIST piecelocs[2]; Xint kingloc[2]; Xu_char occupant[100]; Xu_char virgin[100]; Xu_char ghost[100]; Xu_char ourcolor = UNSET; Xu_char theircolor = UNSET; Xu_char state = CONNECTING, color=WHITE; Xbool iamserver = UNSET; Xbool drawok[2]; Xbool resign, dead; Xbool reverse = True; Xbool ptmessage = False; Xu_char option[NOPTIONS]; Xbool xks = 1; Xint pawndir[2] = { -10, 10 }; Xint lastmovefrom = 0; Xint lastmoveto = 0; XMOVELIST movelist = (MOVELIST)NULL; Xextern int sock; X Xlong random(); X X/* Command line options table. Only resources are entered here...there is a X pass over the remaining options after XtParseCommand is let loose. */ X Xstatic XrmOptionDescRec optionDescList[] = { X{"-cr", "*cursorColor", XrmoptionSepArg, (caddr_t) NULL}, X{"-fb", "*boldFont", XrmoptionSepArg, (caddr_t) NULL}, X{"-vb", "*visualBell", XrmoptionNoArg, (caddr_t) "on"}, X{"+vb", "*visualBell", XrmoptionNoArg, (caddr_t) "off"}, X{"-b", "*side", XrmoptionNoArg, (caddr_t) "black"}, X{"-w", "*side", XrmoptionNoArg, (caddr_t) "white"}, X{"-c", "*side", XrmoptionNoArg, (caddr_t) "random"}, X{"-a", "*announceTakes", XrmoptionNoArg, (caddr_t) "off"}, X{"+a", "*announceTakes", XrmoptionNoArg, (caddr_t) "on"}, X{"-p", "*announcePawns", XrmoptionNoArg, (caddr_t) "off"}, X{"+p", "*announcePawns", XrmoptionNoArg, (caddr_t) "on"}, X{"-s", "*server", XrmoptionNoArg, (caddr_t) "on"}, X{"+s", "*server", XrmoptionNoArg, (caddr_t) "off"}, X{"-r", "*reverse", XrmoptionNoArg, (caddr_t) "off"}, X{"+r", "*reverse", XrmoptionNoArg, (caddr_t) "on"}, X}; X Xmain(argc, argv) Xchar **argv; X{ X int i; X u_short port=0; X char *cp; X Widget toplevel; X X if (cp = rindex(argv[0], '/')) X cp++; X else X cp = argv[0]; X srandom(time(0) ^ getpid()); X toplevel = XtAppInitialize(&my_app, "XKs", X optionDescList, XtNumber(optionDescList), &argc, argv, NULL, NULL, 0); X X argv++; argc--; X if (argc != 1) { Xusage: X fprintf(stderr, "Usage: xks [-+][bwcaprs] user[@host]\n"); X exit(1); X } X X initwidgets(toplevel); X X XtRealizeWidget(toplevel); X initdirlists(); X initpiecelocs(); X screen_init(); X p_init(); X message("Connecting...", MESSAGE); X start_conn(*argv, port); X XtAppMainLoop(my_app); X} *-*-END-of-xmain.c-*-* exit -- Dan Heller ------------------------------------------------ O'Reilly && Associates Zyrcom Inc Senior Writer President argv@ora.com argv@zipcode.com