v11i057: kriegspiel - a chess variant, Part02/03
Steve Schoch
schoch at trident.arc.nasa.gov
Wed Feb 13 18:04:14 AEST 1991
Submitted-by: schoch at 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 at 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 at ora.com argv at zipcode.com
More information about the Comp.sources.x
mailing list