[comp.sources.games] v01i023: chess - C source for chess

games-request@tekred.UUCP (05/21/87)

Submitted by: jhs@hpltca.HP.COM (John Stanback)
Comp.sources.games: Volume 1, Issue 23
Archive-name: chess

	[This game was posted to net.sources.games just as that
	 newsgroup was disappearing, so many of you may not have
	 seen it.  This has fixes for BSD Unix by Rich Salz and
	 the index variable name conflict fixed.  It compiles
	 and runs on our 4.3bsd Vax.  Other postings have indicated
	 it plays a decent game.    -br]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README Makefile patchlevel.h chess.c chess.opn chess.001
# Wrapped by billr@tekred on Wed May 20 17:15:52 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(2865 characters\)
sed "s/^X//" >README <<'END_OF_README'
X
XC source for CHESS
X
XHere is a shar script containing source code in 'C' for a chess 
Xprogram I've written. The following files are included: 
X  1. chess.c   : C source for CHESS
X  2. chess.opn : Opening Library
X  3. chess.001 : Sample problem
X  
XThe file chess.c must be compiled with the -lcurses option. The 
Xcode is pretty generic (I think) and hopefully will run on a wide 
Xvariety of machines. The help command gives a list of the options
Xavailable.  To test out the program, enter 'get' and respond to
Xthe file name prompt with 'chess.001'.  Type 'switch' and the
Xcomputer should find mate in 4 with Nf7.  This takes a few seconds
Xon an HP350 computer.
X
XThe program plays a fairly respectable game of chess, although it 
Xis not competetive with a state-of-the art commercial program. The 
Xsearch rate is typically 100-300 nodes/sec. on an HP Vectra (8 Mhz. 
X286) and about 300-900 nodes/sec. on an HP 350 (25 Mhz. 68020). I 
Xam interested to find out what is achieved on other machines. I 
Xwould also be interested in any comments on playing strength, 
Xweaknesses or bugs in the program, and suggested improvements in 
Xthe algorithm. 
X
XHere are a few comments on the program:
X
X1. Opening Library
X     I'm a terrible chess player and don't know anything about 
X     openings. I copied 70-80 random lines of play from MCO into 
X     the file chess.opn. I think there are a few mistakes in the 
X     translation. If anyone generates a better library please let 
X     me know. 
X     
X2. Positional Heuristics
X     I think that improvement in this area would help the program 
X     quite a bit. In most situations the computer cannot do
X     anything forceful and the choice of a move is based on 
X     positional aspects. I haven't spent a lot of time on the 
X     heuristics and many times the program has no idea of what is 
X     happening and how to proceed. Perhaps optimizing the values of 
X     the existing heuristics would help, but to get a major 
X     improvement I think more chess knowledge will be necessary. 
X     
X3. Search Algorithm
X     This program uses a full-width alpha-beta searching technique 
X     with depth extensions on checks, check evasions, pawn promotion
X     threats and threats to multiple pieces. Capture sequences are
X     handled by a separate search routine. I imagine that much more
X     efficient search routines exist, and would be interested to hear
X     of any. Refinements of the search extension heuristics (similar
X     to the extensions for pawn promotion threats) could have a major 
X     effect on the programs ability. 
X     
X4. Move Generation
X     There are probably better ways to do this, but they would 
X     likely change the data structure drastically and necessitate 
X     a complete re-write. Maybe some good hacks would speed things 
X     up, the ataks function would be the best place to start.
X      
END_OF_README
if test 2865 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(152 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X# Makefile for chess program
X
X# comment out -DBSD for SYSV machines
XCFLAGS = -O -DBSD
X
Xchess:	chess.c
X	cc $(CFLAGS) -o chess chess.c -lcurses -ltermlib
END_OF_Makefile
if test 152 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f patchlevel.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"patchlevel.h\"
else
echo shar: Extracting \"patchlevel.h\" \(21 characters\)
sed "s/^X//" >patchlevel.h <<'END_OF_patchlevel.h'
X#define PATCHLEVEL 1
END_OF_patchlevel.h
if test 21 -ne `wc -c <patchlevel.h`; then
    echo shar: \"patchlevel.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f chess.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"chess.c\"
else
echo shar: Extracting \"chess.c\" \(47675 characters\)
sed "s/^X//" >chess.c <<'END_OF_chess.c'
X/*
X    C source for CHESS               Rev. 3-10-87
X
X    Written by John Stanback (hplabs!hpfcla!hpisla!hpltca!jhs)
X
X    Patches for BSD Unix by Rich Salz (rs@mirror.TMC.COM) - 5/3/87
X
X*/ 
X
X#include <stdio.h>
X#include <curses.h>
X
X#define DEF_TIME 400
X#define neutral 0
X#define white 1
X#define black 2 
X#define no_piece 0
X#define pawn 1
X#define knight 2
X#define bishop 3
X#define rook 4
X#define queen 5
X#define king 6
X#define px " PNBRQK"
X#define qx " pnbrqk"
X#define rx "12345678"
X#define cx "abcdefgh"
X#define check 0x0001
X#define capture 0x0002
X#define draw 0x0004
X#define promote 0x0010
X#define incheck 0x0020
X#define epmask 0x0040
X#define exact 0x0100
X#define pwnthrt 0x0200
X#define true 1
X#define false 0
X
Xstruct leaf
X  {
X    short f,t,score,reply;
X    unsigned short flags;
X  };
X
Xchar mvstr1[5],mvstr2[5];
Xstruct leaf Tree[2000],*root;
Xshort TrPnt[30];
Xshort row[64],col[64],locn[8][8],Index[64],svalue[64];
Xshort PieceList[3][16],PieceCnt[3];
Xshort castld[3],kingmoved[3],mtl[3],pmtl[3],emtl[3],hung[3];
Xshort mate,post,xkillr,ykillr,opponent,computer,Sdepth;
Xlong time0;
Xint response_time,extra_time,timeout,et,et0;
Xshort quit,reverse,bothsides,InChk,player;
Xint NodeCnt,srate;
Xshort atak[3][64],PawnCnt[3][8];
Xshort ChkFlag[30],CptrFlag[30],PawnThreat[30],PPscore[30];
Xshort BookSize,BookDepth;
Xshort GameCnt,Game50,epsquare,lpost;
Xunsigned short GameList[240],Book[80][24];
Xshort GameScore[240],GamePc[240],GameClr[240];
Xshort value[8]={0,100,330,330,500,950,999};
Xshort otherside[3]={0,2,1};
Xshort passed_pawn1[8]={0,3,4,8,14,24,40,80};
Xshort passed_pawn2[8]={0,2,3,4,6,9,13,80};
Xshort passed_pawn3[8]={0,1,2,3,4,5,6,80};
Xshort map[64]=
X   {26,27,28,29,30,31,32,33,38,39,40,41,42,43,44,45,
X    50,51,52,53,54,55,56,57,62,63,64,65,66,67,68,69,
X    74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,
X    98,99,100,101,102,103,104,105,110,111,112,113,114,115,116,117};
Xshort unmap[144]=
X   {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
X    -1,-1,0,1,2,3,4,5,6,7,-1,-1,-1,-1,8,9,10,11,12,13,14,15,-1,-1,
X    -1,-1,16,17,18,19,20,21,22,23,-1,-1,-1,-1,24,25,26,27,28,29,30,31,-1,-1,
X    -1,-1,32,33,34,35,36,37,38,39,-1,-1,-1,-1,40,41,42,43,44,45,46,47,-1,-1,
X    -1,-1,48,49,50,51,52,53,54,55,-1,-1,-1,-1,56,57,58,59,60,61,62,63,-1,-1,
X    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
Xshort edge[64]=
X   {0,1,2,3,3,2,1,0,1,2,3,4,4,3,2,1,2,3,4,5,5,4,3,2,3,4,5,6,6,5,4,3,
X    3,4,5,6,6,5,4,3,2,3,4,5,5,4,3,2,1,2,3,4,4,3,2,1,0,1,2,3,3,2,1,0};
Xshort pknight[64]=
X   {0,6,11,14,14,11,6,0,6,12,22,25,25,22,12,6,
X    11,20,30,36,36,30,20,11,14,25,36,44,44,36,25,14,
X    14,25,36,44,44,36,25,14,11,20,30,36,36,30,20,11,
X    6,12,22,25,25,22,12,6,0,6,11,14,14,11,6,0};
Xshort pbishop[64]=
X   {14,14,14,14,14,14,14,14,14,18,18,18,18,18,18,14,
X    14,18,22,22,22,22,18,14,14,18,22,22,22,22,18,14,
X    14,18,22,22,22,22,18,14,14,18,22,22,22,22,18,14,
X    14,18,18,18,18,18,18,14,14,14,14,14,14,14,14,14};
Xshort board[64]=
X   {rook,knight,bishop,queen,king,bishop,knight,rook,
X    pawn,pawn,pawn,pawn,pawn,pawn,pawn,pawn,
X    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
X    pawn,pawn,pawn,pawn,pawn,pawn,pawn,pawn,
X    rook,knight,bishop,queen,king,bishop,knight,rook};
Xshort color[64]=
X   {white,white,white,white,white,white,white,white,
X    white,white,white,white,white,white,white,white,
X    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
X    black,black,black,black,black,black,black,black,
X    black,black,black,black,black,black,black,black};
Xshort sweep[7]= {false,false,false,true,true,true,false};
Xshort Dstpwn[3]={0,4,6};
Xshort Dstart[7]={6,4,8,4,0,0,0};
Xshort Dstop[7]={7,5,15,7,3,7,7};
Xshort Dir[16]={1,12,-1,-12,11,13,-11,-13,10,-10,14,-14,23,-23,25,-25};
Xunsigned short PV,Swag1,Swag2,killr1[30],killr2[30],killr3[30],Qkillr[30];
Xunsigned short Ckillr[3],prvar[30];
X
Xreadline(x, y, prompt, p)
X    int x, y;
X    char *prompt, *p;
X{
X    char *q;
X
X    standout();
X    mvprintw(y-1,x-1, "%s", prompt);
X    standend();
X    ClrEoln();
X    getyx(stdscr, y, x);
X    for (q = p; (*p = getchar()) !=EOF; ) {
X	switch (*p) {
X	    default:
X		p++;
X		x++;
X		break;
X	    case 'L' & 037:
X		touchwin(stdscr);
X		refresh();
X		break;
X	    case '\n': case '\r':
X		move(y, x);
X		*p = '\0';
X		return;
X	    case '\b':
X		if (p > q) {
X		    p--;
X		    x--;
X		}
X		break;
X	    case 'U' & 037: case '\007': case '\033':
X		p = q;
X		x = 0;
X		break;
X	}
X	move(y, x);
X	ClrEoln();
X    }
X    *p = '\0';
X}
X
Xmain()
X{
X  initscr();
X  NewGame();
X  while (!(quit))
X    {
X      if (bothsides && !mate) select_move(opponent); else input_command();
X      if (!quit && !mate) select_move(computer);
X    }
X  endwin();
X}
X
X
XOpeningBook(side)
Xshort side;
X{
Xshort i,j,r0,pnt;
Xunsigned m,r;
X  srand(time(0));
X  r0 = m = 0;
X  for (i = 0; i < BookSize; i++)
X    {
X      for (j = 0; j <= GameCnt; j++)
X        if (GameList[j] != Book[i][j]) break;
X      if (j > GameCnt)
X        if ((r=rand()) > r0)
X          {
X            r0 = r; m = Book[i][GameCnt+1];
X          }
X    }
X  for (pnt = TrPnt[1]; pnt < TrPnt[2]; pnt++)
X    if ((Tree[pnt].f<<8) + Tree[pnt].t == m) Tree[pnt].score = 0;
X  sort(TrPnt[1],TrPnt[2]-1);
X  if (Tree[TrPnt[1]].score < 0) BookDepth = -1;
X}
X
X
Xselect_move(side)
Xshort side;
X
X/*
X     Select a move by calling function search() at progressively deeper
X     ply until time is up or a mate or draw is reached. An alpha-beta 
X     window of -0, +75 points is set around the score returned from the
X     previous iteration. 
X*/
X
X{
Xshort i,alpha,beta,tempb,tempc;
X
X  timeout = false; player = side;
X  for (i = 0; i < 30; i++)
X    prvar[i] = killr1[i] = killr2[i] = killr3[i] = 0;
X  PPscore[0] = -5000;
X  alpha = -9999; beta = 9999;
X  NodeCnt = Sdepth = extra_time = 0;
X  ataks(white,atak[white]); ataks(black,atak[black]);
X  TrPnt[1] = 0; root = &Tree[0];
X  MoveList(side,1);
X  if (GameCnt < BookDepth) OpeningBook(side); else BookDepth = -1;
X  if (BookDepth > 0) timeout = true;
X  while (!timeout && Sdepth<30)
X    {
X      Sdepth++;
X      gotoXY(70,1); printw("%d ",Sdepth); ClrEoln();
X      search(side,1,Sdepth,alpha,beta,prvar);
X      if (root->score < alpha)
X        search(side,1,Sdepth,-12000,alpha,prvar);
X      if (root->score > beta && !(root->flags & exact))
X        {
X          gotoXY(70,1); printw("%d+",Sdepth); ClrEoln();
X          search(side,1,Sdepth,beta,12000,prvar);
X        }
X      beta = root->score+75;
X      if (root->flags & exact) timeout = true;
X    }
X  if (root->score > -9999)
X    {
X      MakeMove(side,root,&tempb,&tempc);
X      algbrnot(root->f,root->t);
X      PrintBoard(side,root->f,root->t,0);
X      gotoXY(50,16); printw("My move is: %s",mvstr1); ClrEoln();
X    }
X  ElapsedTime(1);
X  gotoXY(18,23); printw("Nodes= %d",NodeCnt); ClrEoln();
X  gotoXY(18,24); printw("Nodes/Sec= %d",srate); ClrEoln();
X  gotoXY(50,13);
X  if (root->flags & draw) printw("draw game!");
X  if (root->score < -9000) printw("opponent will soon mate!");
X  if (root->score > 9000)  printw("computer will soon mate!");
X  if (root->score == -9999)
X    {
X      gotoXY(50,13);
X      printw("opponent mates!!"); mate = true;
X    }
X  if (root->score == 9998)
X    {
X      gotoXY(50,13);
X      printw("computer mates!!"); mate = true;
X    }
X  ClrEoln();
X  if (post) post_move(root);
X  if (root->f == 255 || root->t == 255) Game50 = GameCnt;
X  else if (board[root->t] == pawn || (root->flags & capture)) 
X    Game50 = GameCnt;
X  GameScore[GameCnt] = root->score;
X  if (GameCnt > 238) quit = true;
X  player = otherside[side];
X}
X
X
XVerifyMove(s,ok)
Xchar s[];
Xshort *ok;
X
X/*
X    See if the opponents move is legal, if so, make it.
X*/
X
X{
Xshort x,pnt,cnt,tempb,tempc;
Xunsigned short nxtline[30];
Xstruct leaf *node,*xnode;
X
X  *ok = false; cnt = 0;
X  MoveList(opponent,2);
X  pnt = TrPnt[2];
X  while (pnt < TrPnt[3])
X    {
X      node = &Tree[pnt]; pnt++;
X      algbrnot(node->f,node->t);
X      if (strcmp(s,mvstr1) == 0 || strcmp(s,mvstr2) == 0)
X        {
X          xnode = node; cnt++;
X        }
X    }
X  if (cnt == 1)
X    {
X      MakeMove(opponent,xnode,&tempb,&tempc);
X      CaptureSearch(computer,opponent,3,1,-9999,9999,0,&x,nxtline);
X      if (x == 10000) UnmakeMove(opponent,xnode,&tempb,&tempc);
X      else
X        {
X          *ok = true; PrintBoard(opponent,xnode->f,xnode->t,0);
X          if (xnode->f == 255 || xnode->t == 255) Game50 = GameCnt;
X          else if (board[xnode->t] == pawn || (xnode->flags & capture)) 
X            Game50 = GameCnt;
X        } 
X    }
X}
X
X 
Xinput_command()
X{
Xshort ok,i,f,t;
Xchar s[20],fname[20];
XFILE *fd;
X
X  ok=quit=false;
X  while (!(ok || quit))
X    {
X      readline(50,21,"Your move is? ", s);
X      player = opponent;
X      VerifyMove(s,&ok);
X      if (strcmp(s,"prt") == 0)
X        {
X          ClrScreen();  PrintBoard(white,0,0,1);
X        }
X      if (strcmp(s,"quit") == 0) quit = true;
X      if (strcmp(s,"post") == 0) post = !post;
X      if (strcmp(s,"set") == 0) SetBoard();
X      if (strcmp(s,"go") == 0) ok = true;
X      if (strcmp(s,"help") == 0) help();
X      if (strcmp(s, "redraw") == 0)
X	{
X	  ClrScreen();
X	  PrintBoard(white,0,0,1);
X	}
X      if (strcmp(s,"hint") == 0)
X        {
X          algbrnot(prvar[2]>>8,prvar[2] & 0xFF);
X          gotoXY(50,13); printw("try %5s",mvstr1); ClrEoln();
X        }
X      if (strcmp(s,"both") == 0)
X        {
X          bothsides = !bothsides;
X          select_move(opponent);
X          ok = true;
X        }
X      if (strcmp(s,"reverse") == 0)
X        {
X          reverse = !reverse;
X          ClrScreen();
X          PrintBoard(white,0,0,1);
X        }
X      if (strcmp(s,"switch") == 0)
X        {
X          computer = otherside[computer];
X          opponent = otherside[opponent];
X          ok = true;
X        }
X      if (strcmp(s,"save") == 0)
X        {
X	  readline(50, 21, "file name?  ", fname);
X          SaveGame(fname);
X        }
X      if (strcmp(s,"get") == 0)
X        {
X	  readline(50, 21, "file name?  ", fname);
X          GetGame(fname);
X          InitializeStats();
X          PrintBoard(white,0,0,1);
X        }
X      if (strcmp(s,"time") == 0)
X        {
X	  readline(50, 21, "enter time:  ", fname);
X	  response_time = atoi(fname);
X        }
X      if (strcmp(s,"undo") == 0 && GameCnt > 0)
X        {
X          f = GameList[GameCnt]>>8; t = GameList[GameCnt] & 0xFF;
X          board[f] = board[t]; color[f] = color[t];
X          board[t] = GamePc[GameCnt]; color[t] = GameClr[GameCnt];
X          GameCnt--;
X          PrintBoard(white,0,0,1);
X          InitializeStats();
X        }
X      if (strcmp(s,"list") == 0)
X        {
X          fd = fopen("chess.lst","w");
X          for (i = 0; i <= GameCnt; i++)
X            {
X              f = GameList[i]>>8; t = (GameList[i] & 0xFF);
X              algbrnot(f,t);
X              if ((i % 2) == 0) fprintf(fd,"\n");
X              fprintf(fd," %5s  %6d     ",mvstr1,GameScore[i]);
X            }
X          fprintf(fd,"\n");
X          fclose(fd);
X        }
X    }
X  ElapsedTime(1);
X}
X
X
XgotoXY(x,y)
Xshort x,y;
X{
X  move(y-1,x-1);
X}
X
X
XClrScreen()
X{
X  clear(); refresh();
X}
X
X
XClrEoln()
X{
X  clrtoeol(); refresh();
X}
X
X
Xalgbrnot(f,t)
Xshort f,t;
X{
X  if (f == 255)
X    { strcpy(mvstr1,"o-o"); strcpy(mvstr2,"o-o"); }
X  else if (t == 255)
X    { strcpy(mvstr1,"o-o-o"); strcpy(mvstr2,"o-o"); }
X  else
X    {
X      mvstr1[0] = cx[col[f]]; mvstr1[1] = rx[row[f]];
X      mvstr1[2] = cx[col[t]]; mvstr1[3] = rx[row[t]];
X      mvstr2[0] = qx[board[f]];
X      mvstr2[1] = mvstr1[2]; mvstr2[2] = mvstr1[3];
X      mvstr1[4] = '\0'; mvstr2[3] = '\0';
X    }
X}
X
X
Xparse(s,m)
Xunsigned short *m; char s[];
X{
Xshort r1,r2,c1,c2;
X  if (s[4] == 'o') *m = 0x00FF;
X  else if (s[0] == 'o') *m = 0xFF00;
X  else
X    {
X      c1 = s[0] - 'a'; r1 = s[1] - '1';
X      c2 = s[2] - 'a'; r2 = s[3] - '1';
X      *m = (locn[r1][c1]<<8) + locn[r2][c2];
X    }
X}
X
X
XGetOpenings()
X{
XFILE *fd;
Xint c,j;
Xchar s[80],*p;
X  fd = fopen("chess.opn","r");
X  BookSize = 0; BookDepth = 24; j = -1; c = '?';
X  while (c != EOF)
X    {
X      p = s;
X      while ((c=getc(fd)) != EOF)
X        if (c == '\n') break; else *(p++) = c;
X      *p = '\0';
X      if (c != EOF)
X        if (s[0] == '!')
X          {
X            while (j < BookDepth) Book[BookSize][j++] = 0; 
X            BookSize++; j = -1;
X          }
X        else if (j < 0) j++;
X        else
X          {
X            parse(&s[0],&Book[BookSize][j]); j++;
X            parse(&s[6],&Book[BookSize][j]); j++;
X          } 
X    }
X  fclose(fd);
X}
X
X
XGetGame(fname)
Xchar fname[20];
X{
XFILE *fd;
Xint c;
Xshort loc;
Xunsigned short m;
X
X  if (fname[0] == '\0') strcpy(fname,"chess.000");
X  if ((fd = fopen(fname,"r")) != NULL)
X    {
X      fscanf(fd,"%hd%hd",&castld[white],&castld[black]);
X      fscanf(fd,"%hd%hd",&kingmoved[white],&kingmoved[black]);
X      for (loc = 0; loc < 64; loc++)
X        {
X          fscanf(fd,"%hd",&m); board[loc] = (m >> 8); color[loc] = (m & 0xFF);
X        }
X      GameCnt = -1; c = '?';
X      while (c != EOF)
X        c = fscanf(fd,"%hd%hd%hd%hd",&GameList[++GameCnt],&GameScore[GameCnt],
X                   &GamePc[GameCnt],&GameClr[GameCnt]);
X      fclose(fd);
X    }
X}
X
X
XSaveGame(fname)
Xchar fname[20];
X{
XFILE *fd;
Xshort loc,i;
X
X  if (fname[0] == '\0') strcpy(fname,"chess.000");
X  fd = fopen(fname,"w");
X  fprintf(fd,"%d %d\n",castld[white],castld[black]);
X  fprintf(fd,"%d %d\n",kingmoved[white],kingmoved[black]);
X  for (loc = 0; loc < 64; loc++)
X    fprintf(fd,"%d\n",256*board[loc] + color[loc]);
X  for (i = 0; i <= GameCnt; i++)
X    fprintf(fd,"%d %d %d %d\n",GameList[i],GameScore[i],GamePc[i],GameClr[i]);
X  fclose(fd);
X}
X
X
XElapsedTime(iop)
Xshort iop;
X{
Xint minute,second;
X  et = time(0) - time0;
X  if (et < et0) et0 = 0;
X  if (et > et0 || iop == 1)
X    {
X      if (et > response_time+extra_time) timeout = true;
X      et0 = et;
X      if (iop == 1)
X        {
X          et0 = 0; time0 = time(0);
X        }
X      minute = et/60; second = (et - 60*minute);
X      if (player == computer) gotoXY(50,18); else gotoXY(50,23);
X      printw("%d:%d",minute,second); ClrEoln();
X      if (et > 0) srate = NodeCnt/et; else srate = 0;
X      if (post)
X        {
X          gotoXY(18,24); printw("Nodes/Sec= %d",srate); ClrEoln();
X        }
X    }
X}
X
X
Xpost_move(node)
Xstruct leaf *node;
X{
Xshort d,e,ply;
X  d = 4; ply = 1;
X  gotoXY(60,d); printw("%6d  ",node->score);
X  while (prvar[ply] > 0)
X    {
X      algbrnot(prvar[ply]>>8,prvar[ply] & 0x00FF);
X      gotoXY(50,d); printw("%5s",mvstr1);
X      ply++; d++;
X    }
X  e = d;
X  while (d < lpost)
X    {
X      gotoXY(50,d++); ClrEoln();
X    }
X  lpost = e;
X  refresh();
X}
X
X
XDrawPiece(loc)
Xshort loc;
X{
Xshort r,c; char x;
X  if (reverse) r = 7-row[loc]; else r = row[loc];
X  if (reverse) c = 7-col[loc]; else c = col[loc];
X  if (color[loc] == black) x = '*'; else x = ' ';
X  gotoXY(5+5*c,4+2*(7-r)); printw("%c%c",x,px[board[loc]]," ");
X}
X
X
XPrintBoard(side,f,t,flag)
Xshort side,f,t,flag;
X{
Xshort i,l,c,z; 
X
X  if (side == white) c = 0; else c = 56;
X  if (flag)
X    {
X      i = 2;
X      gotoXY(3,++i);
X      printw("|----|----|----|----|----|----|----|----|");
X      while (i<19)
X        {
X          gotoXY(1,++i);
X          if (reverse) z = (i/2)-1; else z = 10-(i/2);
X          printw("%d |    |    |    |    |    |    |    |    |",z);
X          gotoXY(3,++i);
X          printw("|----|----|----|----|----|----|----|----|");
X        }
X      gotoXY(3,20);
X      if (reverse) printw("   h    g    f    e    d    c    b    a");
X              else printw("   a    b    c    d    e    f    g    h");
X      for (l = 0; l < 64; l++) DrawPiece(l);
X    }
X  else if (f == 255)
X    {
X      DrawPiece(c+4); DrawPiece(c+6);
X      DrawPiece(c+7); DrawPiece(c+5);
X    }
X  else if (t == 255)
X    {
X      DrawPiece(c+4); DrawPiece(c+2);
X      DrawPiece(c); DrawPiece(c+3);
X    }
X  else
X    {
X      DrawPiece(f); DrawPiece(t);
X    }
X  refresh();
X}
X
X
XSetBoard()
X{
Xshort a,r,c,loc;
Xchar s[20];
X
X  ClrScreen(); PrintBoard(white,0,0,1);
X  a = white;
X  do
X  {
X    gotoXY(50,2); printw(".    Exit to Main");
X    gotoXY(50,3); printw("#    Clear Board");
X    readline(49,5, "Enter piece & location: ", s);
X    if (s[0] == '#')
X      {
X        for (loc = 0; loc < 64; loc++)
X          { board[loc] = no_piece; color[loc] = neutral; }
X        PrintBoard(white,0,0,1);
X      }
X    if (s[0] == 'c' || s[0] == 'C') a = otherside[a];
X    c = s[1]-'a'; r = s[2]-'1';
X    if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8))
X      {
X        loc = locn[r][c];
X        color[loc] = a;
X        if (s[0] == 'p') board[loc] = pawn;
X        else if (s[0] == 'n') board[loc] = knight;
X        else if (s[0] == 'b') board[loc] = bishop;
X        else if (s[0] == 'r') board[loc] = rook;
X        else if (s[0] == 'q') board[loc] = queen;
X        else if (s[0] == 'k') board[loc] = king;
X        else { board[loc] = no_piece; color[loc] = neutral; }
X        DrawPiece(loc); refresh();
X      }
X  }
X  while (s[0] != '.');
X  if (board[4] != king) kingmoved[white] = 10;
X  if (board[61] != king) kingmoved[black] = 10;
X  GameCnt = -1; Game50 = -1; BookDepth = 0;
X  InitializeStats(); ClrScreen(); PrintBoard(white,0,0,1);
X}
X  
X
XNewGame()
X{
Xshort l,r,c;
Xchar buff[20];
X
X  mate = quit = reverse = bothsides = post = false;
X  lpost =  NodeCnt = epsquare = xkillr = 0;
X  GameCnt = Game50 = -1;
X  castld[white] = castld[black] = false;
X  kingmoved[white] = kingmoved[black] = 0;
X  opponent = white; computer = black;
X  for (r = 0; r < 8; r++)
X    for (c = 0; c < 8; c++)
X      {
X        l = 8*r+c; locn[r][c] = l;
X        row[l] = r; col[l] = c;
X      }
X  ClrScreen();
X  readline(1, 20, "enter response time (or RETURN for default): ", buff);
X  response_time = buff[0] ? atoi(buff) : DEF_TIME;
X  ClrScreen(); PrintBoard(white,0,0,1);
X  InitializeStats();
X  ElapsedTime(1);
X  GetOpenings();
X}
X
X
Xhelp()
X{
Xchar c;
Xchar buff[10];
X
XClrScreen();
Xprintw("\n");
Xprintw("This program attempts to play CHESS\n\n");
Xprintw("To make a move, enter the column (labelled 'a' - 'h') and\n");
Xprintw("row (labelled '1' - '8') of the 'from' and 'to' squares.\n");
Xprintw("For example, to move the kings pawn forward 2 squares, type e2e4.\n");
Xprintw("Other commands are:\n\n");
Xprintw("o-o           castle king side\n");
Xprintw("o-o-o         castle queen side\n");
Xprintw("set           set up a board position\n");
Xprintw("switch        switch sides with computer\n");
Xprintw("go            skip your move\n");
Xprintw("reverse       reverse board display\n");
Xprintw("redraw        re-paint display\n");
Xprintw("both          computer plays both sides\n");
Xprintw("time          change response time\n");
Xprintw("post          post best line of play\n");
Xprintw("hint          computer suggests your move\n");
Xprintw("list          list moves to file chess.lst\n");
Xprintw("save          save game to disk\n");
Xprintw("get           get game from disk\n");
Xprintw("quit          exit CHESS\n");
Xrefresh();
Xreadline(10, 24, "Type return:", buff);
XClrScreen();
XPrintBoard(white,0,0,1);
X}
X
X
XUpdatePieceList(side,loc,iop)
Xshort side,loc,iop;
X
X/*
X    Array PieceList[side][indx] contains the location of all the pieces of
X    either side. Array Index[loc] contains the indx into PieceList for a
X    given square.
X*/
X
X{
Xregister short i;
X  if (iop == 1)
X    {
X      PieceCnt[side]--;
X      for (i = Index[loc]; i <= PieceCnt[side]; i++)
X        {
X          PieceList[side][i] = PieceList[side][i+1];
X          Index[PieceList[side][i]] = i;
X        }
X    }
X  else
X    {
X      PieceCnt[side]++;
X      PieceList[side][PieceCnt[side]] = loc;
X      Index[loc] = PieceCnt[side];
X    }
X}
X
X
XInitializeStats()
X{
Xregister short i,loc;
X  for (i = 0; i < 8; i++)
X    PawnCnt[white][i] = PawnCnt[black][i] = 0;
X  mtl[white] = mtl[black] = pmtl[white] = pmtl[black]=0;
X  PieceCnt[white] = PieceCnt[black] = 0;
X  for (loc = 0; loc < 64; loc++)
X    if (color[loc] != neutral)
X      {
X        mtl[color[loc]] += value[board[loc]];
X        if (board[loc] == pawn)
X          {
X            pmtl[color[loc]] += value[pawn];
X            ++PawnCnt[color[loc]][col[loc]];
X          }
X        if (board[loc] == king) Index[loc] = 0;
X          else Index[loc] = ++PieceCnt[color[loc]];
X        PieceList[color[loc]][Index[loc]] = loc;
X      }
X}
X
X
Xsort(p1,p2)
Xshort p1,p2;
X{
Xregister short p,p0,s;
Xstruct leaf temp;
X
X  s = 32000;
X  while (p1 < p2)
X    if (Tree[p1].score >= s) p1++;
X    else
X      {
X        s = Tree[p1].score; p0 = p1;
X        for (p = p1+1; p <= p2; p++)
X          if (Tree[p].score > s)
X            {
X              s = Tree[p].score; p0 = p;
X            }
X        temp = Tree[p1]; Tree[p1] = Tree[p0]; Tree[p0] = temp;
X        p1++;
X      }
X}
X
X
Xrepetition(node)
Xstruct leaf *node;
X
X/*
X    Check for draw by threefold repetition or 50 move rule.
X*/
X
X{
Xregister short i,f,t,c;
Xshort r,b[64];
Xunsigned short m;
X  r = c = 0;
X#ifdef	BSD
X  bzero((char *)b, sizeof b);
X#else
X  memset(b,0,64*sizeof(short));
X#endif	/* BSD */
X  for (i = GameCnt; i > Game50; i--)
X    {
X      m = GameList[i]; f = m>>8; t = m & 0xFF;
X      if (t != 255 && f != 255)
X        {
X          b[f]++; b[t]--;
X          if (b[f] == 0) c--; else c++;
X          if (b[t] == 0) c--; else c++;
X          if (c == 0) r++;
X        }
X    }
X  if (r == 1)
X    if (node->score > 0) node->score -= 20;
X    else node->score += 20;
X  if (GameCnt-Game50 > 99 || r == 2)
X    {
X      node->score = 0;
X      node->flags |= exact;
X      node->flags |= draw;
X    }
X}
X
X
Xataks(side,a)
Xshort side,a[];
X
X/*
X    Place the lowest value piece attacking a square into array atak[][].
X*/
X
X{
Xregister short m,u,d,j;
Xshort piece,i,m0,*aloc,*s;
X 
X#ifdef	BSD
X  bzero((char *)a, sizeof a);
X#else
X  a = (short *)memset(a,0,64*sizeof(short));
X#endif	/* BSD */
X  Dstart[pawn] = Dstpwn[side]; Dstop[pawn] = Dstart[pawn] + 1;
X  aloc = &PieceList[side][0];
X  for (i = 0; i <= PieceCnt[side]; i++)
X    {
X      piece = board[*aloc]; m0 = map[*aloc];
X      s = &svalue[*aloc]; *s = 0;
X      aloc++;
X      if (sweep[piece])
X        for (j = Dstart[piece]; j <= Dstop[piece]; j++)
X          {
X            d = Dir[j]; m = m0+d; u = unmap[m];
X            while (u >= 0)
X              {
X                *s += 2;
X                if (a[u] == 0 || piece < a[u]) a[u] = piece;
X                if (color[u] == neutral)
X                  {
X                    m += d; u = unmap[m];
X                  }
X                else u = -1;
X              }
X          }
X      else
X        {
X          for (j = Dstart[piece]; j <= Dstop[piece]; j++)
X            if ((u = unmap[m0+Dir[j]]) >= 0)
X              if (a[u] == 0 || piece < a[u]) a[u] = piece;
X        }
X    }
X}
X
X  
Xcastle(side,f,t,iop,ok)
Xshort side,f,t,iop,*ok;
X{
Xshort i,e,k1,k2,r1,r2,c1,c2,t0,xside;
X
X  xside = otherside[side];
X  if (side == white) e = 0; else e = 56;
X  if (f == 255)
X    {
X      k1 = e+4; k2 = e+6; r1 = e+7; r2 = e+5; c1 = k1; c2 = r1;
X    }
X  else
X    {
X      k1 = e+4; k2 = e+2; r1 = e; r2 = e+3; c1 = r1; c2 = k1;
X    }
X  if (iop == 0)
X    {
X      *ok = false;
X      if (board[k1] == king && board[r1] == rook) *ok = true;
X      for (i = c1; i <= c2; i++)
X        if (atak[xside][i] > 0) *ok = false; 
X      for (i = c1+1; i < c2; i++)
X        if (color[i] != neutral) *ok = false;
X    }
X  else
X    {
X      if (iop == 1) castld[side] = true; else castld[side] = false;
X      if (iop == 2)
X        {
X          t0 = k1; k1 = k2; k2 = t0;
X          t0 = r1; r1 = r2; r2 = t0;
X        }
X      board[k2] = king; color[k2] = side; Index[k2] = 0;
X      board[k1] = no_piece; color[k1] = neutral;
X      board[r2] = rook; color[r2] = side; Index[r2] = Index[r1];
X      board[r1] = no_piece; color[r1] = neutral;
X      PieceList[side][Index[k2]] = k2;
X      PieceList[side][Index[r2]] = r2;
X    }
X}
X
X
Xen_passant(side,xside,f,t,iop)
Xshort side,f,t,iop;
X{
Xshort l;
X  if (t > f) l = t-8; else l = t+8;
X  if (iop == 1)
X    {
X      board[l] = no_piece; color[l] = neutral;
X    }
X  else 
X    {
X      board[l] = pawn; color[l] = xside;
X    }
X  InitializeStats();
X}
X
X
XLinkMove(ply,f,t,side,xside)
Xshort ply,f,t,side,xside;
X{
X
X/*
X    Add a move to the tree.  Assign a bonus (in an attempt to
X    improve move ordering) if move is a
X    principle variation, "killer", or capturing move.
X*/
X
Xregister short s;
Xunsigned short mv;
Xstruct leaf *node;
X
X  node = &Tree[TrPnt[ply+1]];
X  ++TrPnt[ply+1];
X  node->flags = node->reply = 0;
X  node->f = f; node->t = t; mv = (f<<8) + t;
X  if (f == 255 || t == 255) s = 100;
X  else
X    {
X      s = 0;
X      if (mv == PV) s = 150;
X      else if (mv == killr1[ply]) s = 90;
X      else if (mv == killr2[ply]) s = 70;
X      else if (mv == killr3[ply]) s = 50;
X      else if (mv == Swag1) s = 30;
X      else if (mv == Swag2) s = 20;
X      if (color[t] != neutral)
X        {
X          node->flags |= capture;
X          if (t == xkillr) s += 400;
X          if (atak[xside][t] == 0) s += value[board[t]]-board[f];
X          else if (board[t] > board[f]) s += value[board[t]]-value[board[f]];
X          else s += 15;
X        }
X      if (board[f] == pawn)
X        {
X          if (row[t] == 0 || row[t] == 7) node->flags |= promote;
X          else if (row[t] == 1 || row[t] == 6) node->flags |= pwnthrt;
X          else if (t == epsquare) node->flags |= epmask;
X        }
X      if (atak[xside][f] > 0) s += 15;
X      if (atak[xside][t] > 0) s -= 20;
X      if (InChk)
X        {
X          if (board[f] == king && atak[xside][t] == 0) s += 600;  
X          if (mv == Qkillr[ply]) s += 100;
X        }
X    }
X  node->score = s-20000;
X}
X
X
XGenMoves(ply,loc,side,xside)
Xshort ply,loc,side,xside;
X
X/*
X     Generate moves for a piece. The from square is mapped onto a 12 by 
X     12 board and offsets (taken from array Dir[]) are added to the 
X     mapped location. Array unmap[] maps the move back onto array 
X     board[] (yielding a value of -1 if the to square is off the board). 
X     This process is repeated for bishops, rooks, and queens until a 
X     piece is encountered or the the move falls off the board. Legal 
X     moves are then linked into the tree. 
X*/
X    
X{
Xregister short m,u,d;
Xshort i,m0,piece; 
X
X  piece = board[loc]; m0 = map[loc];
X  if (sweep[piece])
X    {
X      for (i = Dstart[piece]; i <= Dstop[piece]; i++)
X        {
X          d = Dir[i]; m = m0+d; u = unmap[m];
X          while (u >= 0)
X            if (color[u] == neutral)
X              {
X                LinkMove(ply,loc,u,side,xside);
X                m += d; u = unmap[m];
X              }
X            else if (color[u] == xside)
X              {
X                LinkMove(ply,loc,u,side,xside);
X                u = -1;
X              }
X            else u = -1;
X        }
X    }
X  else if (piece == pawn)
X    {
X      if (side == white && color[loc+8] == neutral)
X        {
X          LinkMove(ply,loc,loc+8,side,xside);
X          if (row[loc] == 1)
X            if (color[loc+16] == neutral)
X              LinkMove(ply,loc,loc+16,side,xside);
X        }
X      else if (side == black && color[loc-8] == neutral)
X        {
X          LinkMove(ply,loc,loc-8,side,xside);
X          if (row[loc] == 6)
X            if (color[loc-16] == neutral)
X              LinkMove(ply,loc,loc-16,side,xside);
X        }
X      for (i = Dstart[piece]; i <= Dstop[piece]; i++)
X        if ((u = unmap[m0+Dir[i]]) >= 0)
X          if (color[u] == xside || u == epsquare)
X            LinkMove(ply,loc,u,side,xside);
X    }
X  else
X    {
X      for (i = Dstart[piece]; i <= Dstop[piece]; i++)
X        if ((u = unmap[m0+Dir[i]]) >= 0)
X          if (color[u] != side)
X            LinkMove(ply,loc,u,side,xside);
X    }
X}
X
X
X
XMoveList(side,ply)
Xshort side,ply;
X
X/*
X    Fill the array Tree[] with all available moves for side to
X    play. Array TrPnt[ply] contains the index into Tree[]
X    of the first move at a ply.
X*/
X    
X{
Xregister short i;
Xshort ok,xside;
X
X  xside = otherside[side];
X  TrPnt[ply+1] = TrPnt[ply];
X  Dstart[pawn] = Dstpwn[side]; Dstop[pawn] = Dstart[pawn] + 1;
X  for (i = 0; i <= PieceCnt[side]; i++)
X    GenMoves(ply,PieceList[side][i],side,xside);
X  if (kingmoved[side] == 0)
X    {
X      castle(side,255,0,0,&ok);
X      if (ok) LinkMove(ply,255,0,side,xside);
X      castle(side,0,255,0,&ok);
X      if (ok) LinkMove(ply,0,255,side,xside);
X    }
X  sort(TrPnt[ply],TrPnt[ply+1]-1);
X}
X
X
XMakeMove(side,node,tempb,tempc)
Xshort side,*tempc,*tempb;
Xstruct leaf *node;
X
X/*
X    Update Arrays board[], color[], and Index[] to reflect the new
X    board position obtained after making the move pointed to by
X    node.  Also update miscellaneous stuff that changes when a move
X    is made.
X*/
X    
X{
Xregister short f,t;
Xshort ok,xside;
X
X  xside = otherside[side];
X  f = node->f; t = node->t; epsquare = -1; xkillr = t;
X  GameList[++GameCnt] = (f<<8) + t;
X  if (f == 255 || t == 255)
X    {
X      GamePc[GameCnt] = no_piece; GameClr[GameCnt] = neutral;
X      castle(side,f,t,1,&ok);
X    }
X  else
X    {
X      *tempc = color[t]; *tempb = board[t];
X      GamePc[GameCnt] = *tempb; GameClr[GameCnt] = *tempc;
X      if (*tempc != neutral)
X        {
X          UpdatePieceList(*tempc,t,1);
X          if (*tempb == pawn) --PawnCnt[*tempc][col[t]];
X          if (board[f] == pawn)
X            {
X              --PawnCnt[side][col[f]];
X              ++PawnCnt[side][col[t]];
X            }
X          mtl[xside] -= value[*tempb];
X          if (*tempb == pawn) pmtl[xside] -= value[pawn];
X        }
X      color[t] = color[f]; board[t] = board[f];
X      Index[t] = Index[f]; PieceList[side][Index[t]] = t;
X      color[f] = neutral; board[f] = no_piece;
X      if (board[t] == pawn)
X        if (t-f == 16) epsquare = f+8;
X        else if (f-t == 16) epsquare = f-8;
X      if (node->flags & promote)
X        {
X          board[t] = queen;
X          mtl[side] += value[queen] - value[pawn];
X          pmtl[side] -= value[pawn];
X        } 
X      if (board[t] == king) ++kingmoved[side];
X      if (node->flags & epmask) en_passant(side,xside,f,t,1);
X    }
X}
X
X
XUnmakeMove(side,node,tempb,tempc)
Xshort side,*tempc,*tempb;
Xstruct leaf *node;
X
X/*
X    Take back the move pointed to by node.
X*/
X
X{
Xregister short f,t;
Xshort ok,xside;
X
X  xside = otherside[side];
X  f = node->f; t = node->t; epsquare = -1;
X  GameCnt--;
X  if (f == 255 || t == 255) castle(side,f,t,2,&ok);
X  else
X    {
X      color[f] = color[t]; board[f] = board[t];
X      Index[f] = Index[t]; PieceList[side][Index[f]] = f;
X      color[t] = *tempc; board[t] = *tempb;
X      if (*tempc != neutral)
X        {
X          UpdatePieceList(*tempc,t,2);
X          if (*tempb == pawn) ++PawnCnt[*tempc][col[t]];
X          if (board[f] == pawn)
X            {
X              --PawnCnt[side][col[t]];
X              ++PawnCnt[side][col[f]];
X            }
X          mtl[xside] += value[*tempb];
X          if (*tempb == pawn) pmtl[xside] += value[pawn];
X        }
X      if (node->flags & promote)
X        {
X          board[f] = pawn;
X          mtl[side] += value[pawn] - value[queen];
X          pmtl[side] += value[pawn];
X        } 
X      if (board[f] == king) --kingmoved[side];
X      if (node->flags & epmask) en_passant(side,xside,f,t,2);
X    }
X}
X
X
XLinkCapture(ply,f,t,ck)
Xshort ply,f,t,ck;
X{
Xstruct leaf *node;
X
X  node = &Tree[TrPnt[ply+1]];
X  ++TrPnt[ply+1];
X  node->flags = node->reply = 0;
X  node->f = f; node->t = t;
X  if (t == ykillr || t == ck) node->score = value[board[t]]-board[f];
X  else node->score = value[board[t]]-value[board[f]];
X}
X
X
XCaptureList(side,xside,ply)
Xshort side,xside,ply;
X
X/*
X    Generate a list of captures similiarly to GenMoves.
X*/
X
X{
Xregister short m,u,d;
Xshort i,j,m0,piece,ck,*aloc;
X
X  ck = Ckillr[side] & 0x00FF;
X  TrPnt[ply+1] = TrPnt[ply];
X  Dstart[pawn] = Dstpwn[side]; Dstop[pawn] = Dstart[pawn] + 1;
X  aloc = &PieceList[side][0];
X  for (i = 0; i <= PieceCnt[side]; i++)
X    { 
X      piece = board[*aloc]; m0 = map[*aloc];
X      if (sweep[piece])
X        for (j = Dstart[piece]; j <= Dstop[piece]; j++)
X          {
X            d = Dir[j]; m = m0+d; u = unmap[m];
X            while (u >= 0)
X              if (color[u] == neutral)
X                {
X                  m += d; u = unmap[m];
X                }
X              else
X                {
X                  if (color[u] == xside) LinkCapture(ply,*aloc,u,ck);
X                  u = -1;
X                }
X          }
X      else
X        for (j = Dstart[piece]; j <= Dstop[piece]; j++)
X          if ((u = unmap[m0+Dir[j]]) >= 0)
X            if (color[u] == xside) LinkCapture(ply,*aloc,u,ck);
X      aloc++;
X    }
X  sort(TrPnt[ply],TrPnt[ply+1]-1);
X}
X
X
Xdistance(a,b)
Xshort a,b;
X{
Xshort d1,d2;
X
X  d1 = col[a]-col[b]; if (d1 < 0) d1 = -d1;
X  d2 = row[a]-row[b]; if (d2 < 0) d2 = -d2;
X  if (d1 > d2) return(d1); else return(d2);
X}
X
X
XScorePosition(side,score)
Xshort side,*score;
X
X/*
X  Calculate a positional score for each piece as follows:
X    pawns:
X      material value     : 100 pts
X      d,e file, not moved: -10 pts
X           & also blocked: -10 pts
X      doubled            : -12 pts (each pawn)
X      isolated           : -24 pts
X      backward           : -8  pts
X         & attacked      : -6  pts
X      passed             : depends on rank, material balance,
X                           position of opponents king, blocked
X    knights:
X      material value     : 330 pts
X      centre proximity   : array pknight 
X    bishops:
X      material value     : 330 pts
X      discourage edges   : array pbishop
X      mobility           : +2 pts per move  
X    rooks:
X      material value     : 500 pts
X      mobility           : +2 pts per move
X      open file          : +12 pts
X      half open          : +6 pts
X    queen:
X      material value     : 950 pts
X    king:
X      castled            : ~ +10 pts (depends on material)
X      king moved         : ~ -15 pts (depends on material)
X      adjacent pawn      : +5 pts before endgame
X      attacks to         : -5 pts each if more than 1 attack
X      adjacent square        before endgame
X      pawn missing from  : -10 pts before endgame
X      adjacent column
X      centre proximity   : -2 pts before endgame, during endgame
X                           switches to a bonus for center proximity
X                           dependent on opponents control of adjacent
X                           squares
X                           
X    "hung" pieces        : -8  (1 hung piece)
X                           -24 (more than 1)
X*/
X
X{
Xregister short i,j,a;
Xshort loc,e,m0,u,piece,wking,bking,cwking,cbking;
Xshort r,db,dw,s,stage1,stage2,c1,c2,a1,a2;
Xshort pscore[3],xside,rank,column,in_square;
X
X  xside = otherside[side];
X  pscore[white] = pscore[black] = 0;
X  emtl[white] = mtl[white] - pmtl[white] - value[king];
X  emtl[black] = mtl[black] - pmtl[black] - value[king];
X  wking = PieceList[white][0]; bking = PieceList[black][0];
X  cwking = col[wking]; cbking = col[bking];
X  stage1 = 10 - (emtl[white]+emtl[black]) / 670;
X  stage2 = (stage1*stage1) / 10;
X
X  for (c1 = white; c1 <= black; c1++)
X  {
X    c2 = otherside[c1];
X    for (i = 0; i <= PieceCnt[c1]; i++)
X      {
X        loc = PieceList[c1][i]; piece = board[loc];
X        a1 = atak[c1][loc]; a2 = atak[c2][loc];
X        rank = row[loc]; column = col[loc];
X        s = svalue[loc];
X
X        if (piece == pawn && c1 == white)
X          {
X            if (column == 3 || column == 4)
X              if (rank == 1)
X                {
X                  s -= 10;
X                  if (color[loc+8] == white) s -=10;
X                }
X              else if (rank == 4 && a1 == pawn) s += 8;
X            if (column-cwking > 1 || cwking-column > 1) s += stage1*rank;
X            if (PawnCnt[white][column] > 1) s -= 12;
X            if (column > 0 && PawnCnt[white][column-1] == 0 &&
X                column < 7 && PawnCnt[white][column+1] == 0) s -= 24;
X            if (a1 != pawn && atak[c1][loc+8] != pawn)
X              {
X                s -= 8;
X                if (a2 > 0) s -= 6;
X              }
X            if (PawnCnt[black][column] == 0)
X              {
X                dw = distance(loc,wking);
X                db = distance(loc,bking);
X                s += stage2*(db-dw);
X                if (side == white) r = rank-1; else r = rank;
X                if (row[bking] >= r && db < 8-r) in_square = true;
X                  else in_square = false;
X                e = 0; 
X                for (a = loc+8; a < 64; a += 8)
X                  if (atak[black][a] == pawn) a = 99;
X                  else if (atak[black][a] > 0 || color[a] != neutral) e = 1; 
X                if (a == 99) s += stage1*passed_pawn3[rank];
X                else if (in_square || e == 1) s += stage1*passed_pawn2[rank];
X                else s += stage1*passed_pawn1[rank];
X              }
X          }
X        else if (piece == pawn && c1 == black)
X          {
X            if (column == 3 || column == 4)
X              if (rank == 6)
X                {
X                  s -= 10;
X                  if (color[loc-8] == black) s -= 10;
X                }
X              else if (rank == 3 && a1 == pawn) s += 8;
X            if (column-cbking > 1 || cbking-column > 1) s += stage1*(7-rank);
X            if (PawnCnt[black][column] > 1) s -= 12;
X            if (column > 0 && PawnCnt[black][column-1] == 0 &&
X                column < 7 && PawnCnt[black][column+1] == 0) s -= 24;
X            if (a1 != pawn && atak[c1][loc-8] != pawn)
X              {
X                s -= 8;
X                if (a2 > 0) s -= 6;
X              }
X            if (PawnCnt[white][column] == 0)
X              {
X                dw = distance(loc,wking);
X                db = distance(loc,bking);
X                s += stage2*(dw-db);
X                if (side == black) r = rank+1; else r = rank;
X                if (row[wking] <= r && dw < r+1) in_square = true;
X                  else in_square = false;
X                e = 0; 
X                for (a = loc-8; a >= 0 ; a -= 8)
X                  if (atak[white][a] == pawn) a = -99;
X                  else if (atak[white][a] > 0 || color[a] != neutral) e = 1; 
X                if (a == -99) s += stage1*passed_pawn3[7-rank];
X                else if (in_square || e == 1) s += stage1*passed_pawn2[7-rank];
X                else s += stage1*passed_pawn1[7-rank];
X              }
X          }
X        else if (piece == knight)
X          {
X            s = pknight[loc];
X          }
X        else if (piece == bishop)
X          {
X            s += pbishop[loc];
X          }
X        else if (piece == rook)
X          {
X            if (PawnCnt[white][column] == 0) s += 6;
X            if (PawnCnt[black][column] == 0) s += 6;
X          }
X        else if (piece == queen)
X          {
X            s = s/3;
X          }
X        else if (piece == king)
X          {
X            m0 = map[loc];
X            if (castld[c1]) s += (20/(stage1+1));
X            else if (kingmoved[c1] > 0) s -= (30/(stage1+1));
X            if (emtl[c1] > 1300)
X              {
X                s -= 2*edge[loc]; a = 0;
X                for (j = Dstart[king]; j <= Dstop[king]; j++)
X                  if ((u = unmap[m0+Dir[j]]) >= 0)
X                    {
X                      if (atak[c2][u] > 0) a++;
X                      if (board[u] == pawn) s += 5;
X                    }
X                if (a > 1) s -= 5*a; 
X                if (column > 0 && PawnCnt[c1][column-1] == 0) s -= 10;
X                if (column < 7 && PawnCnt[c1][column+1] == 0) s -= 10;
X                if (PawnCnt[c1][column] == 0) s -= 12;
X              }
X            else
X              {
X                e = edge[loc];
X                for (j = Dstart[king]; j <= Dstop[king]; j++)
X                  if ((u=unmap[m0+Dir[j]]) >= 0)
X                    if (atak[c2][u] == 0) e += edge[u];
X                s += (e*((1300-emtl[c1])/100))/8;
X              }
X            if (mtl[c1]<1000 && mtl[c2]<1990 && distance(wking,bking)==2
X                && e<12) s -= 30;
X          }
X        if (a2 > 0 && (a1 == 0 || a2 < piece)) ++hung[c1];
X        if (a2 > 0) s -= 3;
X        pscore[c1] += s; svalue[loc] = s;
X      }
X  }
X  if (hung[side] > 1) pscore[side] -= 12;
X  if (hung[xside] == 1) pscore[xside] -= 8;
X  if (hung[xside] > 1) pscore[xside] -= 24;
X  *score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] - 5;
X  if (*score > 0 && pmtl[side] == 0 && emtl[side] <= value[bishop])
X    *score = 0;
X  if (*score < 0 && pmtl[xside] == 0 && emtl[xside] <= value[bishop])
X    *score = 0;
X}
X
X
XCaptureSearch(side,xside,ply,depth,alpha,beta,qscore,best,bstline)
Xshort side,xside,ply,depth,alpha,beta,qscore,*best;
Xunsigned short bstline[];
X
X/*
X    Perform alpha-beta search on captures up to 9 ply past
X    nominal search depth.
X*/
X
X{
Xregister short j,f,t;
Xshort v,q,pnt,tempb,tempc,pbst,sv;
Xunsigned short nxtline[30];
Xstruct leaf *node;
X
X  *best = -qscore; bstline[ply] = 0;
X  CaptureList(side,xside,ply);
X  pnt = TrPnt[ply]; pbst = 0;
X  while (pnt < TrPnt[ply+1] && *best <= beta)
X    {
X      node = &Tree[pnt]; pnt++;
X      f = node->f; t = node->t;
X      v = value[board[t]]-qscore+svalue[t]; 
X      if (v > alpha)
X        {
X          if (board[t] == king) node->score = 10000;
X          else if (depth == 1) node->score = v;
X          else
X            {
X              ykillr = t; NodeCnt++;
X              sv = svalue[t]; svalue[t] = svalue[f];
X              tempb = board[t]; tempc = color[t];
X              UpdatePieceList(tempc,t,1);
X              board[t] = board[f]; color[t] = color[f];
X              Index[t] = Index[f]; PieceList[side][Index[t]] = t;
X              board[f] = no_piece; color[f] = neutral;
X              CaptureSearch(xside,side,ply+1,depth-1,-beta,-alpha,v,
X                            &q,nxtline);
X              node->score = -q;
X              board[f] = board[t]; color[f] = color[t];
X              Index[f] = Index[t]; PieceList[side][Index[f]] = f;
X              board[t] = tempb; color[t] = tempc;
X              UpdatePieceList(xside,t,2);
X              svalue[f] = svalue[t]; svalue[t] = sv;
X            }
X        if (node->score > *best)
X          {
X            pbst = pnt;
X            *best = node->score;
X            if (*best > alpha) alpha = *best;
X            for (j = ply; j < 30; j++) bstline[j] = nxtline[j];
X            bstline[ply] = (f<<8) + t;
X          } 
X        }
X    }
X  if (pbst == 0) Ckillr[side] = -1;
X    else Ckillr[side] = (Tree[pbst].f<<8) + Tree[pbst].t;
X}
X
X
Xexpand(side,node,depth,ply,alpha,beta,nxtline)
Xshort side,depth,alpha,beta,ply;
Xunsigned short nxtline[];
Xstruct leaf *node;
X
X/*
X    Generate a score for current position by calling search routine
X    to generate opponents best response.
X*/
X
X{
Xshort s,xside;
Xstruct leaf *reply;
X
X  xside = otherside[side];
X  nxtline[ply] = (node->f<<8) + node->t;
X  nxtline[ply+1] = node->reply;
X  search(xside,ply+1,depth-1,-beta,-alpha,nxtline);
X  if (!timeout)
X    {
X      reply = &Tree[TrPnt[ply+1]];
X      s = -reply->score;
X      if (s >= alpha && s <= beta) node->score = s;
X      else if (s < alpha && s < node->score) node->score = s;
X      else if (s > beta && s > node->score) node->score = s;
X      if ((reply->flags & incheck) && !(node->flags & check))
X        {
X          node->flags |= draw; node->score = 0;
X        }
X      if ((node->flags & draw) || (node->score <= -9000) ||
X          (node->score >= 9000)) node->flags |= exact;
X      node->reply = nxtline[ply+1];
X    }
X}
X
X
Xevaluate(side,node,ply,depth,alpha,beta,nxtline)
Xshort side,ply,alpha,beta;
Xunsigned short nxtline[];
Xstruct leaf *node;
X
X/*
X    See if either king is in check.  If positional score estimate
X    passed forward from previous ply warrants, score the position.
X    If positional score is greater than alpha, perform CaptureSearch
X    to modify score based on ensuing capture sequence.
X*/
X
X{
Xshort xside,s,x,t;
X
X  hung[white] = hung[black] = 0;
X  xside = otherside[side];
X  ataks(xside,atak[xside]);
X  if (atak[xside][PieceList[side][0]] > 0)
X    {
X      node->score = ply-10000;
X      node->flags |= incheck;
X      node->flags |= exact;
X    }
X  else
X    {
X      ataks(side,atak[side]);
X      if (atak[side][PieceList[xside][0]]) node->flags |= check;
X      if (ply > Sdepth) t = 0; else t = 90;
X      s = -PPscore[ply-1]+mtl[side]-mtl[xside];
X      if (s+t > alpha || (node->flags & check) ||
X        (node->flags & pwnthrt)) ScorePosition(side,&s);
X      PPscore[ply] = s-mtl[side]+mtl[xside];
X      if (s < alpha || depth > 1)
X        {
X          if (node->score < -12000) node->score = s;
X        }
X      else
X        {
X          ykillr = xkillr;
X          CaptureSearch(xside,side,ply+1,9,-s-1,-alpha,s,&x,nxtline);
X          node->score = -x;
X          node->reply = nxtline[ply+1];
X        }
X      repetition(node);
X    }
X}
X
X
Xsearch(side,ply,depth,alpha,beta,bstline)
Xshort side,ply,depth,alpha,beta;
Xunsigned short bstline[];
X
X/*
X    Perform the main alpha-beta search.  Extensions up to 3 ply
X    beyond the nominal iterative search depth MAY occur for checks,
X    check evasions, pawn promotion threats, and threats to multiple
X    pieces.  
X*/
X
X{
Xregister short j;
Xshort best,tempb,tempc,xside,pnt,pbst,hhh,d;
Xunsigned short mv,nxtline[30];
Xstruct leaf *node;
X
X  xside = otherside[side];
X  if (ply == 1) InChk = false; else InChk = ChkFlag[ply-1];
X  PV = bstline[ply];
X  if (ply < 3)
X    {
X      Swag1 = Swag2 = 0;
X    }
X  else
X    {
X      Swag1 = (Tree[TrPnt[ply-2]].f<<8) + Tree[TrPnt[ply-2]].t;
X      Swag2 = (Tree[TrPnt[ply-2]+1].f<<8) + Tree[TrPnt[ply-2]+1].t;
X    }
X  if (ply > 1) MoveList(side,ply);
X  best = -12000; PPscore[ply] = -PPscore[ply-1];
X  pnt = TrPnt[ply]; pbst = pnt;
X  while (pnt < TrPnt[ply+1] && best<=beta && !timeout)
X    {
X      node = &Tree[pnt]; NodeCnt++;
X      nxtline[ply+1] = 0;
X      if (ply == 1)
X        {
X          d = node->score-best;
X          if (pnt == TrPnt[ply]) extra_time = 0;
X          else if (d < -50) extra_time = -response_time/3;
X          else if (d < 20) extra_time = 0;
X          else if (d < 60) extra_time = response_time/3;
X          else if (d < 200) extra_time = response_time;
X          else extra_time = 2*response_time;
X        }
X      if (node->flags & capture) CptrFlag[ply] = true;
X        else CptrFlag[ply] = false;
X      if (node->flags & pwnthrt) PawnThreat[ply] = true;
X        else PawnThreat[ply] = false;
X      if (ply == 1 && post)
X        {
X          algbrnot(node->f,node->t);
X          gotoXY(50,2); printw("%5s",mvstr1,' '); ClrEoln();
X        }
X      if ((node->flags & exact) == 0)
X      {
X        MakeMove(side,node,&tempb,&tempc);
X        evaluate(side,node,ply,depth,alpha,beta,nxtline);
X        if (hung[xside] > 1 && ply <= Sdepth) hhh = true;
X          else hhh = false;
X        if (node->flags & check) ChkFlag[ply] = true; 
X          else ChkFlag[ply] = false;
X        if ((node->flags & exact) == 0)
X          {
X            if (depth > 1) expand(side,node,depth,ply,alpha,beta,nxtline);
X            if (node->score <= beta && (PawnThreat[ply] ||
X               ((ChkFlag[ply] || hhh) && depth == 1)))
X              expand(side,node,depth+1,ply,alpha,beta,nxtline);
X            else if ((ChkFlag[ply-1] || PawnThreat[ply-1]) &&
X                     ply<=Sdepth+2 && Sdepth>1 &&
X                     (ply>Sdepth || CptrFlag[ply-1] ||
X                     (ply>3 && (ChkFlag[ply-3] || CptrFlag[ply-3])) ||
X                     (hung[side] > 1)))
X              expand(side,node,depth+1,ply,alpha,beta,nxtline);
X          }
X        UnmakeMove(side,node,&tempb,&tempc);
X      }
X      if (node->score > best && !timeout)
X        {
X          if (ply == 1 && depth > 1 && node->score>alpha &&
X            (node->flags & exact) == 0) node->score += 5;
X          best = node->score; pbst = pnt;
X          if (best > alpha) alpha = best;
X          for (j = ply; j < 30; j++) bstline[j] = nxtline[j];
X          bstline[ply] = (node->f<<8) + node->t;
X          if (ply == 1 && post) post_move(node);
X        }
X      if ((pnt % 5) == 0) ElapsedTime(0);
X      pnt++;
X      if (best > 9000) beta = 0;
X    }
X  if (timeout) pnt--;
X  if (ply == 1) sort(TrPnt[ply],pnt-1);
X  else Tree[TrPnt[ply]] = Tree[pbst];
X  node = &Tree[TrPnt[ply]];
X  mv = (node->f<<8) + node->t;
X  if (node->t != (GameList[GameCnt] & 0x00FF))
X    if (best > beta) killr1[ply] = mv;
X    else if (mv != killr2[ply])
X      {
X        killr3[ply] = killr2[ply];
X        killr2[ply] = mv;
X      }
X  if (InChk && best > -9000) Qkillr[ply] = mv;
X}
X
END_OF_chess.c
if test 47675 -ne `wc -c <chess.c`; then
    echo shar: \"chess.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f chess.opn -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"chess.opn\"
else
echo shar: Extracting \"chess.opn\" \(9500 characters\)
sed "s/^X//" >chess.opn <<'END_OF_chess.opn'
XFour Knight's Game
Xe2e4  e7e5
Xg1f3  b8c6
Xb1c3  g8f6
Xf1b5  f8b4
Xo-o   o-o
Xd2d3  b4c3
Xb2c3  d7d6
Xc1g5  d8e7
Xf1e1  c6d8
Xd3d4  d8e6
X!
XGiuoco Piano
Xe2e4  e7e5
Xg1f3  b8c6
Xf1c4  f8c5
Xc2c3  g8f6
Xd2d4  e5d4
Xc3d4  c5b4
Xb1c3  f6e4
Xo-o   b4c3
X!
XGiuoco Piano
Xe2e4  e7e5
Xg1f3  b8c6
Xf1c4  f8c5
Xd2d3  g8f6
Xb1c3  d7d6
Xc1g5  h7h6
Xg5f6  d8f6
Xc3d5  f6d8
X!
XTwo Knights Defence
Xe2e4  e7e5
Xg1f3  b8c6
Xf1c4  g8f6
Xf3g5  d7d5
Xe4d5  c6a5
Xc4b5  c7c6
Xd5c6  b7c6
Xb5e2  h7h6
X!
XTwo Knights Defence -- Max Lange Attack
Xe2e4  e7e5
Xg1f3  b8c6
Xf1c4  g8f6
Xd2d4  e5d4
Xo-o   f8c5
Xe4e5  d7d5
Xe5f6  d5c4
Xf6g7  h8g8
X!
XPetrov's Defence
Xe2e4  e7e5
Xg1f3  g8f6
Xf3e5  d7d6
Xe5f3  f6e4
Xd2d4  d6d5
Xf1d3  f8d6
Xo-o   o-o
Xc2c4  c8g4
Xc4d5  f7f5
Xb1c3  b8d7
X!
XPetrov's Defence
Xe2e4  e7e5
Xg1f3  g8f6
Xd2d4  e5d4
Xe4e5  f6e4
Xd1d4  d7d5
X!
XVienna Game
Xe2e4  e7e5
Xb1c3  g8f6
Xf1c4  b8c6
Xd2d3  f8b4
Xc1g5  h7h6
Xg5f6  b4c3
Xb2c3  d8f6
Xg1e2  d7d6
X!
XVienna Game
Xe2e4  e7e5
Xb1c3  f8c5
Xg1f3  d7d6
Xd2d4  e5d4
Xf3d4  g8f6
Xc1g5  h7h6
Xg5h4  b1c3
X!
XThree Knights Game
Xe2e4  e7e5
Xb1c3  b8c6
Xg1f3  g7g6
Xd2d4  e5d4
Xc3d5  f8g7
Xc1g5  c6e7
Xf3d4  c7c6
Xd5c3  h7h6
X!
XBishop's Opening
Xe2e4  e7e5
Xf1c4  g8f6
Xd2d4  e5d4
Xg1f3  f6e4
Xd1d4  e4c5
Xo-o   c5e6
Xf1e1  c7c6
Xb1c3  d7d5
Xc4d3  f8e7
X!
XRuy Lopez -- Classical Defence
Xe2e4  e7e5
Xg1f3  b8c6
Xf1b5  f8c5
Xc2c3  g8f6
Xd2d4  e5d4
Xe4e5  f6e4
Xo-o   d7d5
X!
XRuy Lopez -- Birds Defence
Xe2e4  e7e5
Xg1f3  b8c6
Xf1b5  c6d4
Xb5a4  f8c5
Xo-o   d4f3
Xd1f3  g8e7
Xd2d3  o-o
Xc1e3  c5b6
Xb1c3  d7d6
X!
XRuy Lopez -- Schliemann Defence
Xe2e4  e7e5
Xg1f3  b8c6
Xf1b5  f7f5
Xb1c3  f5e4
Xc3e4  d7d5
Xf3e5  d5e4
Xe5c6  d8d5
Xc2c4  d5d6
Xc6a7  c8d7
X!
XRuy Lopez -- Old Steinitz Defence
Xe2e4  e7e5
Xg1f3  b8c6
Xf1b5  d7d6
Xd2d4  c8d7
Xb1c3  g8f6
Xo-o   f8e7
Xf1e1  e5d4
Xf3d4  o-o
Xd4f5  f8e8
X!
XRuy Lopez -- Old Steinitz Defence
Xe2e4  e7e5
Xg1f3  b8c6
Xf1b5  d7d6
Xd2d4  c8d7
Xb1c3  g8f6
Xb5c6  d7c6
Xd1d3  e5d4
Xf3d4  f8e7
Xc1g5  c6d7
X!
XRuy Lopez -- Modern Steinitz Defence
Xe2e4  e7e5
Xg1f3  b8c6
Xf1b5  a7a6
Xb5a4  d7d6
Xd2d4  b7b5
Xa4b3  c6d4
Xf3d4  e5d4
Xc2c3  d4c3
Xb1c3  c8b7
X!
XRuy Lopez -- Open Defence
Xe2e4  e7e5
Xg1f3  b8c6
Xf1b5  a7a6
Xb5a4  g8f6
Xo-o   f6e4
Xd2d4  b7b5
Xa4b3  d7d5
Xd4e5  c8e6
Xc2c3  f8c5
Xb1d2  o-o
X!
XRuy Lopez -- Open Defence
Xe2e4  e7e5
Xg1f3  b8c6
Xf1b5  a7a6
Xb5a4  g8f6
Xo-o   f8e7
Xf1e1  b7b5
Xa4b3  d7d6
Xc2c3  o-o
Xh2h3  c6a5
Xb3c2  c2c4
Xd2d4  d8c7
X!
XRuy Lopez
Xe2e4  e7e5
Xg1f3  b8c6
Xf1b5  a7a6
Xb5c6  d7c6
Xd2d4  e5d4
Xd1d4  d8d4
Xf3d4  c8d7
Xc1e3  o-o-o
Xb1d2  g8e7
X!
XScotch Game
Xe2e4  e7e5
Xg1f3  b8c6
Xd2d4  e5d4
Xf3d4  f8c5
Xc1e3  d8f6
Xc2c3  g8e7
Xb1d2  d7d6
Xe3c5  d6c5
X!
XPhilidor's Defence
Xe2e4  e7e5
Xg1f3  d7d6
Xd2d4  g8f6
Xb8c6  b1d2
Xf8c5  f1e2
Xo-o   o-o
Xd1e2  c7c6
X!
XAlekhine's Defence
Xe2e4  g8f6
Xe4e5  f6d5
Xc2c4  d5b6
Xd2d4  d7d6
Xf2f4  d6e5
Xf4e5  b8c6
Xc1e3  c8f5
Xb1c3  e7e6
Xg1f3  f8e7
X!
XAlekhine's Defence
Xe2e4  g8f6
Xe4e5  f6d5
Xd2d4  d7d6
Xg1f3  c8g4
Xf1e2  e7e6
Xo-o   f8e7
Xh2h3  g4h5
Xc2c4  d5b6
X!
XKings Gambit Accepted
Xe2e4  e7e5
Xf2f4  e5f4
Xg1f3  d7d6
Xf1c4  h7h6
Xd2d4  g7g5
Xo-o   f8g7
Xc2c3  b8c6
Xd1b3  d8e7
X!
XPonziani's Opening
Xe2e4  e7e5
Xg1f3  b8c6
Xc2c3  d7d5
Xd1a4  g8f6
Xf3e5  f8d6
Xe5c6  b7c6
Xd2d3  o-o
Xc1g5  h7h6
X!
XCaro-Kann Defence
Xe2e4  c7c6
Xd2d4  d7d5
Xe4d5  c6d5
Xc2c4  g8f6
Xb1c3  b8c6
Xc1g5  e7e6
Xc4c5  f8e7
Xf1b5  o-o
Xg1f3  f6e4
X!
XCaro-Kann Defence
Xe2e4  c7c6
Xd2d4  d7d5
Xe4e5  c8f5
Xf1d3  f5d3
Xd1d3  e7e6
Xb1c3  d8b6
Xb1d2  c6c5
Xd4c5  f8c5
X!
XCaro-Kann Defence
Xe2e4  c7c6
Xb1c3  d7d5
Xg1f3  c8g4
Xh2h3  g4f3
Xd1f3  e7e6
Xd2d4  g8f6
Xf1d3  d5e4
Xc3e4  d8d4
Xc2c3  d4d8
X!
XFrench Defence -- Classical
Xe2e4  e7e6
Xd2d4  d7d5
Xb1c3  g8f6
Xc1g5  f8e7
Xe4e5  f6d7
Xg5e7  d8e7
Xd1d2  o-o
Xf2f4  c7c5
Xg1f3  b8c6
Xo-o-o c5c4
X!
XFrench Defence -- MacCutcheon
Xe2e4  e7e6
Xd2d4  d7d5
Xb1c3  g8f6
Xc1g5  c8g4
Xe4e5  h7h6
Xg5d2  g4f3
Xg2f3  f6e4
Xd1g4  e8f8
Xh2h4  c7c5
X!
XFrench Defence -- Rubenstein
Xe2e4  e7e6
Xd2d4  d7d5
Xb1c3  d5e4
Xc3e4  b8d7
Xg1f3  g8f6
Xe4f6  d7f6
Xf1d3  b7b6
Xd1e2  c8b7
Xc1g5  f8e7
X!
XFrench Defence -- Winawer
Xe2e4  e7e6
Xd2d4  d7d5
Xb1c3  f8b4
Xe4e5  c7c5
Xa2a3  b4c3
Xb2c3  b8d7
Xd1g4  o-o
Xg1f3  b8c6
Xf1e3  f7f5
X!
XFrench Defence -- Tarrasch
Xe2e4  e7e6
Xd2d4  d7d5
Xb1d2  b8c6
Xg1f3  g8f6
Xe4e5  f6d7
Xd2b3  f7f6
Xf1b5  f8e7
Xc1f4  o-o
X!
XSicilian Defence -- Dragon Variation
Xe2e4  c7c5
Xg1f3  b8c6
Xd2d4  c5d4
Xf3d4  g8f6
Xb1c3  d7d6
Xf1e2  g7g6
Xc1e3  f8g7
Xo-o   o-o
Xd4b3  c8e6
Xf2f4  c6a5
Xf4f5  e6c4
X!
XSicilian Defence -- Dragon Variation
Xe2e4  c7c5
Xg1f3  b8c6
Xd2d4  c5d4
Xf3d4  g7g6
Xb1c3  f8g7
Xc1e3  g8f6
Xf1c4  o-o
X!
XSicilian Defence -- Boleslavsky Variation
Xe2e4  c7c5
Xg1f3  b8c6
Xd2d4  c5d4
Xf3d4  g8f6
Xb1c3  d7d6
Xf1e2  e7e5
Xd4b3  f8e7
Xo-o   o-o
Xc1e3  c8e6
X!
XSicilian Defence -- Najdorf
Xe2e4  c7c5
Xg1f3  d7d6
Xd2d4  c5d4
Xf3d4  g8f6
Xb1c3  a7a6
Xc1g5  e7e6
Xd1d2  f8e7
Xo-o-o o-o
X!
XSicilian Defence -- Najdorf
Xe2e4  c7c5
Xg1f3  d7d6
Xd2d4  c5d4
Xf3d4  g8f6
Xb1c3  a7a6
Xf1e2  e7e5
Xd4b3  f8e7
Xo-o   o-o
Xf2f4  b7b5
Xa2a3  c8b7
X!
XSicilian Defence -- Najdorf
Xe2e4  c7c5
Xg1f3  d7d6
Xd2d4  c5d4
Xf3d4  g8f6
Xb1c3  a7a6
Xg2g3  e7e5
Xd4e2  c8e6
Xf1g2  b7b5
Xo-o   b8d7
X!
XSicilian Defence -- Closed
Xe2e4  c7c5
Xb1c3  b8c6
Xg2g3  g7g6
Xf1g2  f8g7
Xd2d3  e7e6
Xc1e3  d7d6
Xg1e2  c6d4
Xd1d2  d8h4
Xo-o   g8d7
X!
XNimzowitsch Defence
Xe2e4  b8c6
Xd2d4  d7d5
Xe4e5  f7f6
Xg1f3  c1g4
Xf1e2  e7e6
Xe5f6  g8f6
Xc2c3  f8d6
Xc1g5  d8d7
X!
XQueens Gambit Accepted
Xd2d4  d7d5
Xc2c4  d5c4
Xg1f3  g8f6
Xe2e3  e7e6
Xf1c4  c7c5
Xo-o   a7a6
Xd1e2  b7b5
Xc4d3  c5d4
Xe3d4  b8c6
X!
XQueens Gambit -- Catalan
Xd2d4  d7d5
Xc2c4  e7e6
Xg2g3  g8f6
Xg1f3  f8e7
Xf1g2  o-o
Xo-o   f6d7
Xd1c2  c7c6
Xb1d2  b7b6
Xe2e4  c8b7
Xb2b3  a8c8
X!
XQueens Gambit Declined -- Orthodox
Xd2d4  d7d5
Xc2c4  e7e6
Xb1c3  g8f6
Xc1g5  f8e7
Xe2e3  o-o
Xg1f3  b8d7
Xa1c1  c7c6
Xf8d3  d5c4
Xf1c4  f6d5
X!
XQueens Gambit Declined -- Cambridge Springs
Xd2d4  d7d5
Xc2c4  e7e6
Xb1c3  g8f6
Xc1g5  b8d7
Xe2e3  c7c6
Xg1f3  d8a5
Xf3d2  f8b4
Xd1c2  o-o
Xg5h4  c6c5
X!
XQueens Gambit Declined -- Exchange Var.
Xd2d4  d7d5
Xc2c4  e7e6
Xb1c3  g8f6
Xc1g5  b8d7
Xc4d5  e6d5
Xe2e3  c7c6
Xf1d3  f8e7
Xd1c2  o-o
Xg1e2  f8e8
X!
XQueens Gambit Declined -- Semi-Tarrasch
Xd2d4  d7d5
Xc2c4  e7e6
Xb1c3  g8f6
Xg1f3  c7c5
Xc4d5  c5d4
Xd1d4  e6d5
Xe2e4  b8c6
Xf1b5  f6e4
X!
XQueens Gambit Declined -- Tarrasch
Xd2d4  d7d5
Xc2c4  e7e6
Xb1c3  c7c5
Xc4d5  e6d5
Xg1f3  b8c6
Xg2g3  g8f6
Xf1g2  f8e7
Xo-o   o-o
X!
XQueens Gambit Declined -- Vienna
Xd2d4  d7d5
Xc2c4  e7e6
Xg1f3  g8f6
Xf1b5  f8b4
Xb1c3  d5c4
Xe2e4  c7c5
Xe4e5  c5d4
Xd1a4  b8c6
Xo-o-o c1d2
X!
XQueens Gambit Declined -- Slav (Marshall Gambit)
Xd2d4  d7d5
Xc2c4  c7c6
Xb1c3  e7e6
Xe2e4  d4e4
Xc3e4  f8b4
Xc1d2  d8d4
Xd2b4  d4e4
Xf1e2  b8a6
Xb4d6  b7b6
X!
XQueens Gambit --Slav (Krause)
Xd2d4  d7d5
Xc2c4  c7c6
Xg1f3  g8f6
Xb1c3  d5c4
Xa2a4  c8f5
Xf3e5  e7e6
Xf2f3  f8b4
Xc1g5  h7h6
Xg5f6  d8f6
Xe2e4  f5h7
X!
XModern Benoni Counter Gambit
Xd2d4  g8f6
Xc2c4  c7c5
Xd4d5  e7e6
Xb1c3  e6d5
Xc4d5  d7d6
Xe2e4  g7g6
Xf1d3  f8g7
Xg1e2  o-o
Xo-o   a7a6
Xa2a4  d8c7
X!
XQueens Pawn Game
Xd2d4  d7d5
Xg1f3  g8f6
Xc1f4  c7c5
Xe2e3  b8c6
Xc2c3  d8b6
Xd1c1  c8f5
Xd4c5  b6c5
Xb1d2  a8c8
Xf3d4  c6d4
Xe3d4  c5b6
X!
XPirc-Robatsch Defence
Xd2d4  d7d6
Xe2e4  g8f6
Xb1c3  g7g6
Xc1g5  f8g7
Xd1d2  b8d7
Xo-o-o e7e5
Xd4e5  d6e5
Xg1f3  h7h6
Xg5h4  g6g5
Xh4g3  d8e7
X!
XPirc-Robatsch Defence
Xd2d4  d7d6
Xe2e4  g8f6
Xb1c3  g7g6
Xf1c4  c7c6
Xd1e2  f8g7
Xg1f3  o-o
Xc1g5  b7b5
Xc4d3  d8c7
X!
XQueens Indian Defence
Xd2d4  g8f6
Xc2c4  e7e6
Xg1f3  b7b6
Xg2g3  c8b7
Xf1g2  f8e7
Xo-o   o-o
Xb1c3  f6e4
Xd1c2  e4c3
Xc2c3  d7d6
Xc3c2  f7f5
X!
XQueens Indian Defence
Xd2d4  g8f6
Xc2c4  e7e6
Xg1f3  b7b6
Xe2e3  c8b7
Xf1d3  f8e7
Xb1c3  d7d5
Xo-o   o-o
Xd1e2  b8d7
X!
XNimzo-Indian Defence
Xd2d4  g8f6
Xc2c4  e7e6
Xb1c3  f8b4
Xd1c2  d7d5
Xa2a3  b4c3
Xc2c3  b8c6
Xg1f3  f6e4
Xc3b3  c6a5
Xb3a4  c7c6
X!
XNimzo-Indian Defence (Rubenstein)
Xd2d4  g8f6
Xc2c4  e7e6
Xb1c3  f8b4
Xe2e3  o-o
Xf1d3  d7d5
Xg1f3  c7c5
Xo-o   b8c6
Xa2a3  b4c3
Xb2c3  d5c4
Xd3c4  d8c7
X!
XNimzo-Indian Defence -- Samisch 
Xd2d4  g8f6
Xc2c4  e7e6
Xb1c3  f8b4
Xa2a3  b4c3
Xb2c3  o-o
Xf2f3  d7d5
Xc4d5  e6d5
Xe2e3  c8f5
Xg1e2  b8d7
Xe2g3  f5g6
X!
XNimzo-Indian Defence
Xd2d4  g8f6
Xc2c4  e7e6
Xb1c3  f8b4
Xc1d2  o-o
Xe2e3  d7d5
Xg1f3  c7c5
Xa2a3  b4c3
Xd2c3  f6e4
Xa1c1  e4c3
Xc1c3  c5d4
X!
XGrunfeld Defence
Xd2d4  g8f6
Xc2c4  g7g6
Xb1c3  d7d5
Xc4d5  f6d5
Xe2e4  d5c3
Xb2c3  c7c5
Xf1c4  f8g7
Xg1e2  o-o
Xo-o   c5d4
Xc3d4  b8c6
X!
XGrunfeld Defence -- Smyslov
Xd2d4  g8f6
Xc2c4  g7g6
Xb1c3  d7d5
Xg1f3  f8g7
Xd1b3  d5c4
Xb3c4  o-o
Xe2e4  c8g4
Xc1e3  f6d7
Xo-o-o b8c6
X!
XGrunfeld Defence
Xd2d4  g8f6
Xc2c4  g7g6
Xb1c3  d7d5
Xc1f4  f8g7
Xd2d3  o-o
Xc4d5  f6d5
Xc3d5  d8d5
Xf4c7  b8c6
X!
XKings Indian Defence -- Classical
Xd2d4  g8f6
Xc2c4  g7g6
Xb1c3  f8g7
Xe2e4  d7d6
Xg1f3  o-o
Xf1e2  e7e5
Xo-o   b8c6
Xc1e3  f8e8
Xd4e5  d6e5
X!
XKings Indian Defence -- 4 pawns attack
Xd2d4  g8f6
Xc2c4  g7g6
Xb1c3  f8g7
Xe2e4  d7d6
Xf2f4  c7c5
Xg1f3  o-o
Xd4d5  e7e6
Xf1d3  e6d5
Xc4d5  d8b6
X!
XKings Indian Defence -- Samisch
Xd2d4  g8f6
Xc2c4  g7g6
Xb1c3  f8g7
Xe2e4  d7d6
Xf2f3  o-o
Xc1e3  e7e5
Xd4d5  c7c6
Xg1e2  c6d5
Xc3d5  f6d5
X!
XKings Indian Defence -- Main Line
Xd2d4  g8f6
Xc2c4  g7g6
Xg2g3  f8g7
Xf1g2  o-o
Xb1c3  d7d6
Xg1f3  b8d7
Xo-o   e7e5
Xe2e4  c7c6
Xh2h3  d8b6
X!
XKings Indian Defence
Xd2d4  g8f6
Xc2c4  g7g6
Xb1c3  f8g7
Xg1f3  o-o
Xc1f4  d7d6
Xh2h3  b8d7
Xe2e3  c7c6
X!
XDutch Defence
Xd2d4  f7f5
Xg2g3  e7e6
Xf1g2  g8f6
Xg1f3  f8e7
Xo-o   o-o
Xc2c4  d7d6
Xb1c3  d8e8
Xd1c2  e8h5
Xb2b3  b8c6
Xc1a3  a7a5
X!
XEnglish Opening
Xc2c4  e7e5
Xb1c3  g8f6
Xg1f3  b8c6
Xe2e4  f8b4
Xd2d3  d7d6
Xf1e2  o-o
Xo-o   b4c3
Xb2c3  d8e7
X!
XEnglish Opening
Xc2c4  g8f6
Xb1c3  d7d5
Xc4d5  f6d5
Xe2e4  d5f4
Xf1c4  c8e6
Xc4e6  f7e6
X!
XEnglish Opening
Xc2c4  e7e5
Xb1c3  g8f6
Xg1f3  b8c6
Xg2g3  d7d5
Xc4d5  f6d5
Xf1g2  d5b6
Xo-o   f8e7
Xd2d3  o-o
Xc1e3  f7f5
X!
XReti -- Accepted
Xg1f3  d7d5
Xc2c4  d5c4
Xe2e3  c7c5
Xf1c4  e7e6
Xo-o   g8f6
Xb2b3  b8c6
Xc1b2  a7a6
Xa2a4  f8e7
X!
XReti -- Neo Catalan
Xg1f3  d7d5
Xc2c4  e7e6
Xg2g3  g8f6
Xf1g2  f8e7
Xo-o   o-o
Xb2b3  c7c5
Xc4d5  f6d5
Xc1b2  b8c6
Xd2d4  b7b6
Xb1c3  d5c3
X!
XReti -- Barcza
Xg1f3  d7d5
Xg2g3  g8f6
Xf1g2  g7g6
Xo-o   f8g7
Xd2d3  o-o
Xb1d2  b8c6
Xe2e4  e7e5
Xc2c3  a7a5
Xf1e1  d5e4
Xd3e4  f6d7
X!
END_OF_chess.opn
if test 9500 -ne `wc -c <chess.opn`; then
    echo shar: \"chess.opn\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f chess.001 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"chess.001\"
else
echo shar: Extracting \"chess.001\" \(163 characters\)
sed "s/^X//" >chess.001 <<'END_OF_chess.001'
X0 0
X10 10
X0
X0
X0
X0
X0
X0
X0
X1537
X0
X0
X0
X0
X0
X0
X257
X257
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X1281
X0
X0
X513
X0
X0
X0
X1026
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X258
X258
X0
X0
X1026
X0
X0
X0
X0
X1538
END_OF_chess.001
if test 163 -ne `wc -c <chess.001`; then
    echo shar: \"chess.001\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0