From mipos3!intelca!oliveb!pyramid!amdahl!ames!ll-xn!husc6!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request Thu Jan 14 17:56:04 PST 1988 Article 44 of net.sources.games: Path: td2cad!mipos3!intelca!oliveb!pyramid!amdahl!ames!ll-xn!husc6!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request From: games-request@tekred.TEK.COM Newsgroups: net.sources.games Subject: v03i038: gnuchess - Technology Chess program for GNU Unix, Part01/03 Message-ID: <2035@tekred.TEK.COM> Date: 12 Jan 88 20:00:51 GMT Sender: billr@tekred.TEK.COM Lines: 1855 Approved: billr@tekred.TEK.COM Submitted by: Stuart Cracraft Comp.sources.games: Volume 3, Issue 38 Archive-name: gnuchess/Part01 #! /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 README <<'END_OF_README' XThis is the comp.sources.games distribution of Gnuchess. The source Xis the latest as of mid December 1987. The C source is split into Xtwo files in order to get the shar files into reasonable sizes for Xnetwork transfer. I hacked up the man page based on the "help" Xscreen and a man page from an earlier release of gnuchess. See the Xfile COPYING for the standard GNU info. X X -Bill Randle X Moderator, comp.sources.games X Tektronix, Inc. X games-request@tekred.TEK.COM END_OF_README if test 468 -ne `wc -c MANIFEST <<'END_OF_MANIFEST' X File Name Archive # Description X----------------------------------------------------------- X COPYING 1 X MANIFEST 1 This shipping list X Makefile 2 X README 1 X gnuchess.1 1 X gnuchess.book 2 X gnuchess.c1 1 X gnuchess.c2 3 END_OF_MANIFEST if test 354 -ne `wc -c COPYING <<'END_OF_COPYING' X X GNU CHESS GENERAL PUBLIC LICENSE X X Copyright (C) 1986,1987 Free Software Foundation, Inc. X Everyone is permitted to copy and distribute verbatim copies X of this license, but changing it is not allowed. X X The license agreements of most software companies keep you at the Xmercy of those companies. By contrast, our general public license is Xintended to give everyone the right to share GNU Chess. To make Xsure that you get the rights we want you to have, we need to make Xrestrictions that forbid anyone to deny you these rights or to ask you Xto surrender the rights. Hence this license agreement. X X Specifically, we want to make sure that you have the right to give Xaway copies of GNU Chess, that you receive source code or else can get it Xif you want it, that you can change GNU Chess or use pieces of it in new Xfree programs, and that you know you can do these things. X X To make sure that everyone has such rights, we have to forbid you to Xdeprive anyone else of these rights. For example, if you distribute Xcopies of GNU Chess, you must give the recipients all the rights that you Xhave. You must make sure that they, too, receive or can get the Xsource code. And you must tell them their rights. X X Also, for our own protection, we must make certain that everyone Xfinds out that there is no warranty for GNU Chess. If GNU Chess is Xmodified by someone else and passed on, we want its recipients to know Xthat what they have is not what we distributed, so that any problems Xintroduced by others will not reflect on our reputation. X X Therefore the Free Software Foundation, Inc. makes the following Xterms which say what you must do to be allowed to distribute or change XGNU Chess. X X COPYING POLICIES X X 1. You may copy and distribute verbatim copies of GNU Chess source Xcode as you receive it, in any medium, provided that you conspicuously Xand appropriately publish on each file a valid copyright notice X"Copyright (C) 1986,1987 Free Software Foundation, Inc.", containing the Xyear of last change for the file in question; keep intact the notices Xon all files that refer to this License Agreement and to the absence Xof any warranty; and give any other recipients of the GNU Chess Xprogram a copy of this License Agreement along with the program. X X 2. You may modify your copy or copies of GNU Chess source code or Xany portion of it, and copy and distribute such modifications under Xthe terms of Paragraph 1 above, provided that you also do the following: X X a) cause the modified files to carry prominent notices stating X who last changed such files and the date of any change; and X X b) cause the whole of any work that you distribute or publish, X that in whole or in part contains or is a derivative of GNU Chess X or any part thereof, to be freely distributed X and licensed to all third parties on terms identical to those X contained in this License Agreement (except that you may choose X to grant more extensive warranty protection to third parties, X at your option). X X c) if the modified program serves as a text editor, cause it X when started running in the simplest and usual way, to print X an announcement including a valid copyright notice ("Copyright X (C)", the year of authorship, and all copyright owners' names), X saying that there is no warranty (or else, saying that you provide X a warranty) and that users may redistribute the program under X these conditions, and telling the user how to view a copy of X this License Agreement. X X 3. You may copy and distribute GNU Chess or any portion of it in Xcompiled, executable or object code form under the terms of Paragraphs X1 and 2 above provided that you do the following: X X a) cause each such copy of GNU Chess to be accompanied by the X corresponding machine-readable source code; or X X b) cause each such copy of GNU Chess to be accompanied by a X written offer, with no time limit, to give any third party X free (except for a nominal shipping charge) machine readable X copy of the corresponding source code; or X X c) in the case of a recipient of GNU Chess in compiled, executable X or object code form (without the corresponding source code) you X shall cause copies you distribute to be accompanied by a copy X of the written offer of source code which you received along X with the copy of GNU Chess. X X 4. You may not copy, sublicense, distribute or transfer GNU Chess Xexcept as expressly provided under this License Agreement. Any attempt Xotherwise to copy, sublicense, distribute or transfer GNU Chess is void and Xyour rights to use GNU Chess under this License agreement shall be Xautomatically terminated. However, parties who have received computer Xsoftware programs from you with this License Agreement will not have Xtheir licenses terminated so long as such parties remain in full compliance. X XYour comments and suggestions about our licensing policies and our Xsoftware are welcome! Please contact the Free Software Foundation, Inc., X1000 Mass Ave, Cambridge, MA 02138, or call (617) 876-3296. X X NO WARRANTY X X BECAUSE GNU CHESS IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY XNO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT XWHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, XAND/OR OTHER PARTIES PROVIDE GNU CHESS "AS IS" WITHOUT WARRANTY OF ANY XKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE XIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR XPURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE XPROGRAM IS WITH YOU. SHOULD THE GNU CHESS PROGRAM PROVE DEFECTIVE, XYOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. X X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL FREE SOFTWARE XFOUNDATION, INC., AND/OR ANY OTHER PARTY WHO MAY MODIFY AND XREDISTRIBUTE GNU CHESS AS PERMITTED ABOVE, BE LIABLE TO YOU FOR XDAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, XINCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR XINABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA XBEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A XFAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY XFREE SOFTWARE FOUNDATION, INC.) THE PROGRAM, EVEN IF YOU HAVE BEEN XADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY XOTHER PARTY. X====================================================================== END_OF_COPYING if test 6439 -ne `wc -c gnuchess.1 <<'END_OF_gnuchess.1' X.TH GNU CHESS X.SH NAME Xgnuchess \- The Technology Chess Program for GNU Unix X.SH SYNOPSIS X.B gnuchess X.br X.B chesstool gnuchess X[ X.I level X] X.SH DESCRIPTION X.I Gnuchess Xplays a game of chess against the user. Or it plays against Xitself. Or it referees a game. X.PP X.I Gnuchess Xhas two display modes. The first mode is simply a normal Xmode that you could use with a terminal. The second mode Xis a fancy display mode you can use with a SUN workstation. XTo use the former, simply type 'gnuchess'. To use the Xlatter, simply type 'chesstool gnuchess' on a SUN Xworkstation where 'chesstool' is installed. In the Xlatter example, the argument should be the path Xspecifying where to find the gnuchess binary. X.PP XThe X.I level Xoption when using 'chesstool' allows setting the search level Xtime limit (in seconds). The default is 30 seconds. In other Xdisplay modes, the user is prompted for a time limit. The Xsearch limit can be changed with the "time" command. X.PP XThe following documentation assumes you are in Xthe first mode (e.g. normal mode using a regular Xterminal). If not, then you should read the chesstool documentation. X.PP XFor help once in X.I Gnuchess Xtype "help". To type in your move, use the Xnotation "e2e4" where the first letter-number pair Xindicates the origination square and the second Xletter-number pair indicates the destination square. XThe letter indicates the column with the left-most Xcolumn being "a" and the right-most column being "h". XThe number indicates the row, the first row (White's Xfirst rank) being "1" and the last row (Black's Xfirst rank) being "8". To castle, type the origin Xsquare of the king and the destination square of the Xking, just as you would do for a regular move. X.SH LIST OF COMMANDS X.LP X.nf XAwindow set Alpha window size XBwindow set Beta window size Xbd redraw board Xbeep toggle beep Xblack computer plays black Xbook force computer to ignore opening book (?) Xboth computer match Xclock set time control Xcontempt ? Xdebug debug piece locations Xdepth set search depth Xeasy toggle easy mode Xforce enter game moves Xg1f3 move from g1 to f3 Xget game from file Xgo ? Xhash toggle hashing Xhelp print help message Xhint suggest a move Xlist game to chess.lst Xnew start new game Xnf3 move knight to f3 Xo-o castle king side Xo-o-o castle queen side Xpost principle variation Xprune prune search tree Xquit exit CHESS Xrandom randomize play Xremove undo last two moves Xreverse board display Xsave game to file Xset edit board Xswitch sides with computer Xtime change search level Xundo undo last move Xverify verify move against the book (?) Xwhite computer plays white X.fi X.SH BUGS X.PP XThere are probably some bugs. Suggestions for improvements Xand bug reports should be mailed to the author. X.SH AUTHOR X.nf XStuart Cracraft Stuart Cracraft XP.O. Box 13123 UCLA, Dept. of Mathematics XTorrance, Ca. Los Angeles, Ca. X90503 90024 X(213) 214-1136 (213) 825-9040 X Xemail: cracraft@venera.isi.edu X.fi X.sp XManpage created by Bill Randle (billr@tekred.tek.com), based on Xthe man page for an earlier release of Gnuchess. X.SH AUTHOR'S COMMENT X.PP XThis software is being made available by the Free Software XFoundation under the restrictions described in its license Xagreement which accompanies this distribution. This software, Xits sources, binaries, documentation and all associated parts Xare copyright (C) 1986 by the Free Software Foundation, Inc. X.SH SEE ALSO X.nf Xchesstool(6) Xdbm(3) X.fi END_OF_gnuchess.1 if test 3459 -ne `wc -c gnuchess.c1 <<'END_OF_gnuchess.c1' X/* Compile via: cc gnuchess.c -o gnuchess. For display version, X add -DDISPLAY flag and -lcurses -ltermcap libraries to X command-line. For SUN Chesstool version, add -DCHESSTOOL X but don't include display options in last sentence. X For faster version, add -O flag to any of these flags. X*/ X/* This file contains code for CHESS. X Copyright (C) 1986, 1987 Free Software Foundation, Inc. X XThis file is part of CHESS. X XCHESS is distributed in the hope that it will be useful, Xbut WITHOUT ANY WARRANTY. No author or distributor Xaccepts responsibility to anyone for the consequences of using it Xor for whether it serves any particular purpose or works at all, Xunless he says so in writing. Refer to the CHESS General Public XLicense for full details. X XEveryone is granted permission to copy, modify and redistribute XCHESS, but only under the conditions described in the XCHESS General Public License. A copy of this license is Xsupposed to have been given to you along with CHESS so you Xcan know your rights and responsibilities. It should be in a Xfile named COPYING. Among other things, the copyright notice Xand this notice must be preserved on all copies. */ X X/* Modified 12/18/87 by Bill Randle (billr@tekred.tek.com) to X remove a redundant #include and #ifdef section. X*/ X X#include X#include X#include X X#ifdef MSDOS X#include X#include X#include X#include X#define printz printf X#define scanz scanf X#define refresh(); X#define initscr(); X#define crmode(); X#define nocrmode(); X#define endwin(); X#define _stklen 8000 X#define ttblsz 4096 X#else X#include X#include X#define ttblsz 16384 X#ifdef DISPLAY X#include X#define printz printw X#define scanz fflush(stdout), scanw X#else X#define printz printf X#define scanz fflush(stdout), scanf X#define refresh(); X#define initscr(); X#define crmode(); X#define nocrmode(); X#define endwin(); X#endif DISPLAY X#endif MSDOS X#ifndef HZ X#define HZ 60 X#endif X 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 valueP 100 X#define valueN 330 X#define valueB 330 X#define valueR 520 X#define valueQ 980 X#define valueK 999 X#define ctlP 0x4000 X#define ctlN 0x2800 X#define ctlB 0x1800 X#define ctlR 0x0400 X#define ctlQ 0x0200 X#define ctlK 0x0100 X#define ctlBQ 0x1200 X#define ctlRQ 0x0600 X#define ctlNN 0x2000 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 0x0008 X#define cstlmask 0x0010 X#define epmask 0x0020 X#define exact 0x0040 X#define pwnthrt 0x0080 X#define truescore 0x0001 X#define lowerbound 0x0002 X#define upperbound 0x0004 X#define maxdepth 30 X#define true 1 X#define false 0 X#define absv(x) ((x) < 0 ? -(x) : (x)) X#define taxicab(a,b) (absv(col[a]-col[b]) + absv(row[a]-row[b])) X Xstruct leaf X { X short f,t,score,reply; X unsigned short flags; X }; Xstruct GameRec X { X unsigned short gmove; X short score,depth,time,piece,color; X long nodes; X }; Xstruct TimeControlRec X { X short moves[3]; X long clock[3]; X }; Xstruct hashval X { X unsigned long bd; X unsigned short key; X }; Xstruct hashentry X { X unsigned long hashbd; X unsigned short reply,flags; X short score,depth; X }; X Xchar mvstr1[5],mvstr2[5]; Xstruct leaf Tree[2000],*root; Xshort TrPnt[maxdepth],board[64],color[64]; Xshort row[64],col[64],locn[8][8],Pindex[64],svalue[64]; Xshort PieceList[3][16],PieceCnt[3],atak[3][64],PawnCnt[3][8]; Xshort castld[3],kingmoved[3],mtl[3],pmtl[3],emtl[3],hung[3]; Xshort mate,post,opponent,computer,Sdepth,Awindow,Bwindow,randflag; Xlong ResponseTime,ExtraTime,Level,et,et0,time0,cputimer,ft; Xlong NodeCnt,evrate,ETnodes,EvalNodes,HashCnt; Xlong OperatorTime; Xshort quit,reverse,bothsides,hashflag,InChk,player,force,easy,beep; Xshort wking,bking,TOsquare,timeout,Zscore,zwndw,cptrval,prune,slk; Xshort HasPawn[3],HasKnight[3],HasBishop[3],HasRook[3],HasQueen[3]; Xshort ChkFlag[maxdepth],CptrFlag[maxdepth],PawnThreat[maxdepth]; Xshort Pscore[maxdepth],Tscore[maxdepth],Threat[maxdepth]; Xstruct GameRec GameList[240]; Xshort GameCnt,Game50,epsquare,lpost; Xshort BookSize,BookDepth,MaxSearchDepth; Xstruct TimeControlRec TimeControl; Xshort TCflag,TCmoves,mycnt1,mycnt2; X#ifdef MSDOS Xunsigned short Book[80][24]; X#else Xunsigned short Book[250][50]; Xstruct tms tmbuf1,tmbuf2; X#endif Xshort otherside[3]={0,2,1}; 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 Stboard[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 Stcolor[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 sweep1[7]= {false,false,false,false,true,true,false}; Xshort sweep2[7]= {false,false,false,true,false,true,false}; Xshort Dpwn[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}; Xshort rank7[3] = {0,6,1}; Xunsigned short killr0[maxdepth],killr1[maxdepth],killr2[maxdepth]; Xunsigned short killr3[maxdepth],Qkillr[maxdepth],PrVar[maxdepth]; Xunsigned short PV,hint,Swag0,Swag1,Swag2,Swag3,Swag4,Swag5; Xunsigned short hashkey; Xunsigned long hashbd; Xstruct hashval hashcode[3][7][64]; X#ifdef MSDOS Xstruct hashentry far *ttable,*ptbl; X#else Xstruct hashentry *ttable,*ptbl; Xint TerminateSearch(),Die(); X#endif MSDOS Xunsigned char history[2][64][64]; X Xshort Mwpawn[64],Mbpawn[64],Mknight[3][64],Mbishop[3][64],Mking[3][64]; Xshort WeakSq[3][64],Kfield[3][64],contempt[3]; Xshort value[7]={0,valueP,valueN,valueB,valueR,valueQ,valueK}; Xshort control[7]={0,ctlP,ctlN,ctlB,ctlR,ctlQ,ctlK}; Xshort passed_pawn1[8]={0,15,30,60,100,180,280,800}; Xshort passed_pawn2[8]={0,15,25,35,50,90,140,800}; Xshort passed_pawn3[8]={0,5,10,15,20,30,120,800}; Xshort ISOLANI[8] = {-12,-14,-16,-20,-20,-16,-14,-12}; Xshort DOUBLED[8] = {-12,-12,-12,-10,-10,-12,-12,-12}; Xshort BMBLTY[30] = {-4,-2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,13,14,14, X 15,15,16,16,17,17,18,18,18,18,18}; Xshort RMBLTY[30] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,14,15,15, X 16,16,17,17,18,18,19,19,20,20,20,20}; Xshort Kthreat[16] = {0,-6,-16,-32,-48,-64,-64,-64,-64,-64,-64,-64, X -64,-64,-64,-64}; Xshort KNIGHTPOST,KNIGHTSTRONG,BISHOPSTRONG,KATAK; Xshort PEDRNK2B,PBKWRD,PWEAKA,PWEAKH,PADVNCM,PAWNSHIELD; Xshort RHOPN,RHOPNX,KHOPN,KHOPNX; Xshort ATAKD,HUNGP,HUNGX,KCASTLD,KMOVD,XRAY; Xshort stage,Zwmtl,Zbmtl,c1,c2,KSFTY,Developed[3]; Xshort KingOpening[64]= X { 0, 0, -4, -8, -8, -4, 0, 0, X -4, -4, -8,-12,-12, -8, -4, -4, X -12,-16,-20,-20,-20,-20,-16,-12, X -16,-20,-24,-24,-24,-24,-20,-16, X -16,-20,-24,-24,-24,-24,-20,-16, X -12,-16,-20,-20,-20,-20,-16,-12, X -4, -4, -8,-12,-12, -8, -4, -4, X 0, 0, -4, -8, -8, -4, 0, 0}; Xshort KingEnding[64]= X { 0, 6,12,18,18,12, 6, 0, X 6,12,18,24,24,18,12, 6, X 12,18,24,30,30,24,18,12, X 18,24,30,36,36,30,24,18, X 18,24,30,36,36,30,24,18, X 12,18,24,30,30,24,18,12, X 6,12,18,24,24,18,12, 6, X 0, 6,12,18,18,12, 6, 0}; Xshort DyingKing[64]= X { 0, 8,16,24,24,16, 8, 0, X 8,32,40,48,48,40,32, 8, X 16,40,56,64,64,56,40,16, X 24,48,64,72,72,64,48,24, X 24,48,64,72,72,64,48,24, X 16,40,56,64,64,56,40,16, X 8,32,40,48,48,40,32, 8, X 0, 8,16,24,24,16, 8, 0}; Xshort pknight[64]= X { 0, 4, 8,10,10, 8, 4, 0, X 4, 8,16,20,20,16, 8, 4, X 8,16,24,28,28,24,16, 8, X 10,20,28,32,32,28,20,10, X 10,20,28,32,32,28,20,10, X 8,16,24,28,28,24,16, 8, X 4, 8,16,20,20,16, 8, 4, X 0, 4, 8,10,10, 8, 4, 0}; Xshort pbishop[64]= X {14,14,14,14,14,14,14,14, X 14,22,18,18,18,18,22,14, X 14,18,22,22,22,22,18,14, X 14,18,22,22,22,22,18,14, X 14,18,22,22,22,22,18,14, X 14,18,22,22,22,22,18,14, X 14,22,18,18,18,18,22,14, X 14,14,14,14,14,14,14,14}; Xshort PawnAdvance[64]= X { 0, 0, 0, 0, 0, 0, 0, 0, X 0, 2, 4, 0, 0, 4, 2, 0, X 6, 8,10,12,12,10, 8, 6, X 8,12,20,32,32,20,12, 8, X 12,20,28,40,40,28,20,12, X 16,28,36,48,48,36,28,16, X 16,28,36,48,48,36,28,16, X 0, 0, 0, 0, 0, 0, 0, 0}; X X Xmain(argc,argv) Xint argc; char *argv[]; X{ X#ifdef MSDOS X ttable = (struct hashentry far *)farmalloc(ttblsz * X (unsigned long)sizeof(struct hashentry)); X printf("%lu bytes free\n",farcoreleft()); X#else X ttable = (struct hashentry *)malloc(ttblsz * X (unsigned long)sizeof(struct hashentry)); X signal(SIGINT,Die); signal(SIGQUIT,Die); X#endif MSDOS X#ifdef CHESSTOOL X setlinebuf(stdout); X if (argc > 1) Level = atoi(argv[1]); X else Level = 30; /* Default to 30 seconds */ X#endif CHESSTOOL X initscr(); X crmode(); X NewGame(); X while (!(quit)) X { X if (bothsides && !mate) SelectMove(opponent,1); else input_command(); X if (!(quit || mate || force)) SelectMove(computer,1); X } X nocrmode(); X endwin(); X} X X X#ifndef MSDOS XDie() X{ Xchar s[80]; X signal(SIGINT,SIG_IGN); X signal(SIGQUIT,SIG_IGN); X gotoXY(50,24); X printz("Abort? "); X scanz("%s",s); X if (strcmp(s,"yes") == 0) X { X#ifdef DISPLAY X gotoXY(1,24); X nocrmode(); X endwin(); X#endif DISPLAY X exit(0); X } X signal(SIGINT,Die); signal(SIGQUIT,Die); X} X XTerminateSearch() X{ X signal(SIGINT,SIG_IGN); X signal(SIGQUIT,SIG_IGN); X timeout = true; X bothsides = false; X signal(SIGINT,Die); signal(SIGQUIT,Die); X} X#endif X X XOpeningBook() X{ Xshort i,j,r0,pnt; Xunsigned m,r; X srand((unsigned)time0); X r0 = m = 0; X for (i = 0; i < BookSize; i++) X { X for (j = 0; j <= GameCnt; j++) X if (GameList[j].gmove != Book[i][j]) break; X if (j > GameCnt) X if ((r=rand()) > r0) X { X r0 = r; m = Book[i][GameCnt+1]; X hint = Book[i][GameCnt+2]; 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 XShowDepth(ch) Xchar ch; X{ X#ifdef DISPLAY X gotoXY(75,1); printz("%2d%c",Sdepth,ch); ClrEoln(); X#endif DISPLAY X} X XShowResults(ch) Xchar ch; X{ X#ifndef DISPLAY X#ifndef CHESSTOOL Xregister int i; X printz("%2d%c %5d %4ld %7ld ",Sdepth,ch,root->score,et,NodeCnt); X for (i = 1; PrVar[i] > 0; i++) X { X algbr((short)(PrVar[i] >> 8),(short)(PrVar[i] & 0xFF),false); X if (i == 9 || i == 17) printz("\n "); X printz("%5s ",mvstr1); X } X printz("\n"); X fflush(stdout); X#endif CHESSTOOL X#endif DISPLAY X} X X Xint SelectMove(side,iop) Xshort side,iop; 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 -9000 to +90 points is set around the score returned from the X previous iteration. X*/ X X{ Xstatic short i,j,alpha,beta,score,tempb,tempc,temps,xside,rpt; X X#ifndef MSDOS X (void) times(&tmbuf1); X signal(SIGINT,TerminateSearch); signal(SIGQUIT,TerminateSearch); X#endif MSDOS X timeout = false; X xside = otherside[side]; X if (iop != 2) player = side; X if (TCflag) X { X ResponseTime = (TimeControl.clock[side]) / X (TimeControl.moves[side] + 3) - X OperatorTime; X ResponseTime += (ResponseTime*TimeControl.moves[side])/(2*TCmoves+1); X } X else ResponseTime = Level; X if (iop == 2) ResponseTime = 999; X if (Sdepth > 0 && root->score > Zscore-zwndw) ResponseTime -= ft; X else if (ResponseTime < 1) ResponseTime = 1; X ExtraTime = 0; X X if (Sdepth == 0) X { X ExaminePosition(); X ptbl = ttable; X for (i = 0; i < ttblsz; i++,ptbl++) ptbl->depth = 0; X for (i = 0; i < 64; i++) X for (j = 0; j < 64; j++) X history[0][i][j] = history[1][i][j] = 0; X TOsquare = -1; X PV = 0; X if (iop != 2) hint = 0; X for (i = 0; i < maxdepth; i++) X PrVar[i] = killr0[i] = killr1[i] = killr2[i] = killr3[i] = Qkillr[i] = 0; X#ifdef DISPLAY X for (i = 1; i < 17; i++) X { X gotoXY(50,i); ClrEoln(); X } X#else X post = false; X#ifndef CHESSTOOL X printz("\nMove# %d Target= %ld Clock: %ld\n",TimeControl.moves[side], X ResponseTime,TimeControl.clock[side]); X#endif CHESSTOOL X#endif DISPLAY X alpha = -9000; beta = 9000; rpt = 0; X TrPnt[1] = 0; root = &Tree[0]; X MoveList(side,1); X if (GameCnt < BookDepth) OpeningBook(); else BookDepth = -1; X if (BookDepth > 0) timeout = true; X NodeCnt = ETnodes = EvalNodes = HashCnt = 0; X Zscore = 0; zwndw = 25; X } X X while (!timeout && Sdepth < MaxSearchDepth) X { X Sdepth++; X ShowDepth(' '); X score = search(side,1,Sdepth,alpha,beta,PrVar,&rpt); X for (i = 1; i <= Sdepth; i++) killr0[i] = PrVar[i]; X if (score < alpha) X { X ShowDepth('-'); X ExtraTime = 5*ResponseTime; X score = search(side,1,Sdepth,-9000,beta,PrVar,&rpt); X } X if (score > beta && !(root->flags & exact)) X { X ShowDepth('+'); X ExtraTime = 0; X score = search(side,1,Sdepth,alpha,9000,PrVar,&rpt); X } X score = root->score; X ShowResults('.'); X beta = score + Bwindow; X if (Awindow != 9000) alpha = score - Awindow; X for (i = 1; i <= Sdepth; i++) killr0[i] = PrVar[i]; X if (!timeout) sort(0,TrPnt[2]-1); X if (score > Zscore-zwndw && score > Tree[1].score+250) ExtraTime = 0; X else if (score > Zscore-3*zwndw) ExtraTime = ResponseTime; X else ExtraTime = 3*ResponseTime; X if (root->flags & exact) timeout = true; X if (Tree[1].score < -9000) timeout = true; X if (4*et > 2*ResponseTime + ExtraTime) timeout = true; X if (!timeout) X { X Tscore[0] = score; X if (Zscore == 0) Zscore = score; X else Zscore = (Zscore+score)/2; X } X zwndw = 25+absv(Zscore/12); X } X X score = root->score; X if (rpt >= 2 || score < -12000) root->flags |= draw; X if (iop == 2) return(0); X if (BookDepth < 0) hint = PrVar[2]; X ElapsedTime(1); X#ifdef DISPLAY X gotoXY(50,22); printz("Nodes= %6ld",NodeCnt); ClrEoln(); X gotoXY(50,23); printz("Nodes/Sec= %4ld",evrate); ClrEoln(); X#else X#ifndef CHESSTOOL Xprintz("Nodes= %ld Eval= %ld Hash= %ld Rate= %ld ", X NodeCnt,EvalNodes,HashCnt,evrate); Xprintz("CPU= %.2ld:%.2ld.%.2ld\n", X cputimer/6000,(cputimer % 6000)/100,cputimer % 100); X#endif CHESSTOOL X#endif DISPLAY X X if (score > -9999 && rpt <= 2) X { X MakeMove(side,root,&tempb,&tempc,&temps); X algbr(root->f,root->t,root->flags & cstlmask); X } X else algbr(PieceList[side][0],PieceList[side][0],false); X if (root->flags & epmask) UpdateDisplay(0,0,1,0); X else UpdateDisplay(root->f,root->t,0,root->flags & cstlmask); X#ifdef CHESSTOOL X gotoXY(50,17); printz("%d. ... %s",++mycnt1,mvstr1); ClrEoln(); X if (root->flags & draw) printz("Draw\n"); X if (score == -9999) X if (opponent == white) printz("White\n"); else printz("Black\n"); X if (score == 9998) X if (computer == white) printz("White\n"); else printz("Black\n"); X#else X gotoXY(50,17); printz("My move is: %s",mvstr1); X if (beep) printz("%c",7); X ClrEoln(); X gotoXY(50,24); X if (root->flags & draw) printz("Draw game!"); X if (score == -9999) printz("opponent mates!"); X else if (score == 9998) printz("computer mates!"); X else if (score < -9000) printz("opponent will soon mate!"); X else if (score > 9000) printz("computer will soon mate!"); X ClrEoln(); X#endif CHESSTOOL X#ifndef DISPLAY X printz("\n"); X#endif DISPLAY X if (score == -9999 || score == 9998) mate = true; X if (mate) hint = 0; X if (post) post_move(root); X if (root->flags & cstlmask) Game50 = GameCnt; X else if (board[root->t] == pawn || (root->flags & capture)) X Game50 = GameCnt; X GameList[GameCnt].score = score; X GameList[GameCnt].nodes = NodeCnt; X GameList[GameCnt].time = (short)et; X GameList[GameCnt].depth = Sdepth; X if (TCflag) X { X TimeControl.clock[side] -= (et + OperatorTime); X if (--TimeControl.moves[side] == 0) X SetTimeControl(); X } X#ifdef MSDOS X if (kbhit()) bothsides = false; X#endif X if ((root->flags & draw) && bothsides) quit = true; X if (GameCnt > 238) quit = true; X player = xside; X Sdepth = 0; X fflush(stdin); X return(0); X} X X X#ifdef CHESSTOOL X#define illegalmsg printz("illegal move\n") X#else X#define illegalmsg {gotoXY(50,24); printz("illegal move!"); ClrEoln();} X#endif X Xint VerifyMove(s,iop,mv) Xchar s[]; Xshort iop; Xunsigned short *mv; X{ Xstatic short pnt,tempb,tempc,temps,cnt; Xstatic struct leaf xnode; Xstruct leaf *node; X X *mv = 0; X if (iop == 2) X { X UnmakeMove(opponent,&xnode,&tempb,&tempc,&temps); X return(false); X } X cnt = 0; X MoveList(opponent,2); X pnt = TrPnt[2]; X while (pnt < TrPnt[3]) X { X node = &Tree[pnt]; pnt++; X algbr(node->f,node->t,node->flags & cstlmask); X if (strcmp(s,mvstr1) == 0 || strcmp(s,mvstr2) == 0) X { X cnt++; xnode = *node; X } X } X if (cnt == 0) X if (isdigit(s[1]) || isdigit(s[2])) illegalmsg; X if (cnt == 1) X { X MakeMove(opponent,&xnode,&tempb,&tempc,&temps); X if (SqAtakd(PieceList[opponent][0],computer)) X { X UnmakeMove(opponent,&xnode,&tempb,&tempc,&temps); X illegalmsg; X return(false); X } X else X { X if (iop == 1) return(true); X if (xnode.flags & epmask) UpdateDisplay(0,0,1,0); X else UpdateDisplay(xnode.f,xnode.t,0,xnode.flags & cstlmask); X if (xnode.flags & cstlmask) Game50 = GameCnt; X else if (board[xnode.t] == pawn || (xnode.flags & capture)) X Game50 = GameCnt; X GameList[GameCnt].depth = GameList[GameCnt].score = 0; X GameList[GameCnt].nodes = 0; X ElapsedTime(1); X GameList[GameCnt].time = (short)et; X TimeControl.clock[opponent] -= et; X --TimeControl.moves[opponent]; X *mv = (xnode.f << 8) + xnode.t; X return(true); X } X } X else if (cnt > 1) X { X gotoXY(50,24); printz("ambiguous move!"); ClrEoln(); X } X return(false); X} X X Xinput_command() X{ Xshort ok,i,f,t,c,p,tc,tp; Xunsigned short mv; Xchar s[80],fname[20]; X X ok=quit=false; X player = opponent; X ataks(white,atak[white]); ataks(black,atak[black]); X#ifdef DISPLAY X gotoXY(50,19); printz("Your move is? "); ClrEoln(); X#endif X ft = 0; X if (hint > 0 && !easy && BookDepth < 0) X { X fflush(stdout); X time0 = time((long *)0); X algbr(hint>>8,hint & 0xFF,false); X strcpy(s,mvstr1); X f = epsquare; X if (VerifyMove(s,1,&mv)) X { X SelectMove(computer,2); X VerifyMove(mvstr1,2,&mv); X if (Sdepth > 0) Sdepth--; X } X ft = time((long *)0) - time0; X epsquare = f; X } X fflush(stdin); X X while (!(ok || quit)) X { X#ifndef CHESSTOOL X gotoXY(50,19); printz("Your move is? "); ClrEoln(); X#endif CHESSTOOL X scanz("%s",s); X player = opponent; X ok = VerifyMove(s,0,&mv); X if (ok && mv != hint) X { X Sdepth = 0; X ft = 0; X } X if (strcmp(s,"bd") == 0) X { X#ifdef DISPLAY X ClrScreen(); UpdateDisplay(0,0,1,0); X#else X PrintBoard(); X#endif DISPLAY 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,"force") == 0) force = !force; X if (strcmp(s,"random") == 0) randflag = !randflag; X if (strcmp(s,"book") == 0) BookDepth = -1; X if (strcmp(s,"undo") == 0 && GameCnt >= 0) Undo(); X if (strcmp(s,"new") == 0) NewGame(); X if (strcmp(s,"list") == 0) ListGame(); X if (strcmp(s,"clock") == 0) SetTimeControl(); X if (strcmp(s,"hash") == 0) hashflag = !hashflag; X if (strcmp(s,"beep") == 0) beep = !beep; X if (strcmp(s,"Awindow") == 0) X { X gotoXY(50,24); printz("window: "); ClrEoln(); X scanz("%hd",&Awindow); X } X if (strcmp(s,"Bwindow") == 0) X { X gotoXY(50,24); printz("window: "); ClrEoln(); X scanz("%hd",&Bwindow); X } X if (strcmp(s,"hint") == 0) X { X algbr((short)(hint>>8),(short)(hint & 0xFF),false); X gotoXY(50,24); printz("try %5s",mvstr1); ClrEoln(); X } X if (strcmp(s,"both") == 0) X { X bothsides = !bothsides; X Sdepth = 0; X SelectMove(opponent,1); X ok = true; X } X if (strcmp(s,"reverse") == 0) X { X reverse = !reverse; X ClrScreen(); X UpdateDisplay(0,0,1,0); X } X if (strcmp(s,"switch") == 0) X { X computer = otherside[computer]; X opponent = otherside[opponent]; X UpdateDisplay(0,0,1,0); X force = false; X ok = true; X Sdepth = 0; X } X if (strcmp(s,"white") == 0) X { X computer = white; opponent = black; X UpdateDisplay(0,0,1,0); X ok = true; force = false; X Sdepth = 0; X } X if (strcmp(s,"black") == 0) X { X computer = black; opponent = white; X UpdateDisplay(0,0,1,0); X ok = true; force = false; X Sdepth = 0; X } X if (strcmp(s,"time") == 0) X { X gotoXY(50,24); printz("enter time: "); ClrEoln(); X scanz("%ld",&Level); X TCflag = false; X } X if (strcmp(s,"remove") == 0 && GameCnt >= 1) X { X Undo(); Undo(); X } X if (strcmp(s,"get") == 0) X { X gotoXY(50,24); printz("fname? "); ClrEoln(); scanz("%s",fname); X GetGame(fname); X InitializeStats(); X UpdateDisplay(0,0,1,0); X Sdepth = 0; X } X if (strcmp(s,"save") == 0) X { X gotoXY(50,24); printz("fname? "); ClrEoln(); scanz("%s",fname); X SaveGame(fname); X } X if (strcmp(s,"depth") == 0) X { X gotoXY(50,24); printz("depth= "); ClrEoln(); X scanz("%hd",&MaxSearchDepth); X } X if (strcmp(s,"verify") == 0) VerifyBook(); X if (strcmp(s,"easy") == 0) easy = !easy; X if (strcmp(s,"contempt") == 0) X { X gotoXY(50,24); printz("contempt= "); ClrEoln(); X scanz("%hd",&c); X contempt[computer] = c; X contempt[opponent] = -c; X } X if (strcmp(s,"prune") == 0) X { X gotoXY(50,24); printz("prune= "); ClrEoln(); X scanz("%hd",&prune); X } X if (strcmp(s,"debug") == 0) X { X ExaminePosition(); X gotoXY(50,24); printz("enter piece: "); ClrEoln(); X scanz("%s",s); X if (s[0] == 'w') c = white; else c = black; X if (s[1] == 'p') p = pawn; X else if (s[1] == 'n') p = knight; X else if (s[1] == 'b') p = bishop; X else if (s[1] == 'r') p = rook; X else if (s[1] == 'q') p = queen; X else if (s[1] == 'k') p = king; X else p = no_piece; X for (i = 0; i < 64; i++) X { X gotoXY(4+5*col[i],5+2*(7-row[i])); X tp = board[i]; tc = color[i]; X board[i] = p; color[i] = c; X c1 = c; c2 = otherside[c1]; X printz("%3d ",SqValue(i,opponent)); X board[i] = tp; color[i] = tc; X } X refresh(); X } X } X#ifdef CHESSTOOL X printf("%d. %s\n",++mycnt2,s); X#endif CHESSTOOL X gotoXY(50,24); ClrEoln(); X ElapsedTime(1); X if (force) X { X computer = opponent; opponent = otherside[computer]; X } X} X X XgotoXY(x,y) Xshort x,y; X{ X#ifdef DISPLAY X#ifdef MSDOS Xunion REGS r1,r2; X r1.h.ah = 0x02; r1.h.bh = 0x00; X r1.h.dl = x-1; r1.h.dh = y-1; X int86(0x10,&r1,&r2); X#else X move(y-1,x-1); X#endif MSDOS X#else X#ifndef CHESSTOOL X printz("\n"); X#endif CHESSTOOL X#endif DISPLAY X} X X XClrScreen() X{ X#ifdef DISPLAY X#ifdef MSDOS Xunion REGS r1,r2; X gotoXY(1,1); X r1.h.ah = 0x08; r1.h.bh = 0x00; X int86(0x10,&r1,&r2); X r1.h.ah = 0x09; r1.h.al = 0x20; X r1.h.bh = 0x00; r1.h.bl = r2.h.ah; X r1.h.ch = 0x07; r1.h.cl = 0xD0; X int86(0x10,&r1,&r2); X gotoXY(1,1); X#else X clear(); refresh(); X#endif MSDOS X#else X printz("\n\n"); X#endif DISPLAY X} X X XClrEoln() X{ X#ifdef DISPLAY X#ifdef MSDOS Xunion REGS r1,r2; Xchar x,y; X r1.h.ah = 0x03; r1.h.bh = 0x00; X int86(0x10,&r1,&r2); X x = r2.h.dl+1; y = r2.h.dh+1; X r1.h.ah = 0x08; r1.h.bh = 0x00; X int86(0x10,&r1,&r2); X r1.h.ah = 0x09; r1.h.al = 0x20; X r1.h.bh = 0x00; r1.h.bl = r2.h.ah; X r1.h.ch = 0x00; r1.h.cl = 81-x; X int86(0x10,&r1,&r2); X gotoXY(x,y); X#else X clrtoeol(); refresh(); X#endif MSDOS X#endif DISPLAY X} X X Xalgbr(f,t,iscastle) Xshort f,t,iscastle; 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 if (iscastle) X if (t > f) strcpy(mvstr2,"o-o"); X else strcpy(mvstr2,"o-o-o"); X} X X XUndo() X{ Xshort f,t; X f = GameList[GameCnt].gmove>>8; X t = GameList[GameCnt].gmove & 0xFF; X if (board[t] == king && distance(t,f) > 1) X castle(GameList[GameCnt].color,f,t,2); X else X { X board[f] = board[t]; color[f] = color[t]; X board[t] = GameList[GameCnt].piece; X color[t] = GameList[GameCnt].color; X if (board[f] == king) --kingmoved[color[f]]; X } X if (TCflag) ++TimeControl.moves[color[f]]; X GameCnt--; mate = false; Sdepth = 0; X UpdateDisplay(0,0,1,0); X InitializeStats(); X} X X Xparse(s,m,j) Xunsigned short *m; char s[]; Xshort j; X{ Xshort r1,r2,c1,c2; X if (s[4] == 'o') X if (j & 1) *m = 0x3C3A; else *m = 0x0402; X else if (s[0] == 'o') X if (j & 1) *m = 0x3C3E; else *m = 0x0406; 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 if ((fd = fopen("gnuchess.book","r")) != NULL) X { X BookSize = 0; j = 0; c = '?'; p = s; X while ((c = getc(fd)) != EOF) X if (c != '\n') *(p++) = c; X else X { X *p = '\0'; X if (s[0] == '!') X { X if (j > 0) X { X while (j < BookDepth) Book[BookSize][j++] = 0; X BookSize++; j = 0; X } X } X else X { X parse(&s[0],&Book[BookSize][j],j); j++; X parse(&s[6],&Book[BookSize][j],j); j++; X } X p = s; X } X fclose(fd); X } 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%hd",&computer,&opponent,&Game50); X fscanf(fd,"%hd%hd%hd%hd", X &castld[white],&castld[black], X &kingmoved[white],&kingmoved[black]); X fscanf(fd,"%hd%hd",&TCflag,&OperatorTime); X fscanf(fd,"%ld%ld%hd%ld", X &TimeControl.clock[white],&TimeControl.clock[black], X &TimeControl.moves[white],&TimeControl.moves[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 { X ++GameCnt; X c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove, X &GameList[GameCnt].score,&GameList[GameCnt].depth, X &GameList[GameCnt].nodes,&GameList[GameCnt].time, X &GameList[GameCnt].piece,&GameList[GameCnt].color); X } X GameCnt--; X } X fclose(fd); 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 %d\n",computer,opponent,Game50); X fprintf(fd,"%d %d %d %d\n", X castld[white],castld[black],kingmoved[white],kingmoved[black]); X fprintf(fd,"%d %d\n",TCflag,OperatorTime); X fprintf(fd,"%ld %ld %d %ld\n", X TimeControl.clock[white],TimeControl.clock[black], X TimeControl.moves[white],TimeControl.moves[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 %ld %d %d %d\n", X GameList[i].gmove,GameList[i].score,GameList[i].depth, X GameList[i].nodes,GameList[i].time, X GameList[i].piece,GameList[i].color); X fclose(fd); X} X X XListGame() X{ XFILE *fd; Xshort i,f,t; X fd = fopen("chess.lst","w"); X fprintf(fd,"\n"); X fprintf(fd," score depth nodes time "); X fprintf(fd," score depth nodes time\n"); X for (i = 0; i <= GameCnt; i++) X { X f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF); X algbr(f,t,false); X if ((i % 2) == 0) fprintf(fd,"\n"); else fprintf(fd," "); X fprintf(fd,"%5s %5d %2d %6ld %5d",mvstr1, X GameList[i].score,GameList[i].depth, X GameList[i].nodes,GameList[i].time); X } X fprintf(fd,"\n\n"); X fclose(fd); X} X X XVerifyBook() X{ Xshort i,j,side,found,pnt,tempb,tempc,temps; Xunsigned short mv; Xstruct leaf *node; X ClrScreen(); X for (i = 0; i < BookSize; i++) X { X CopyBoard(Stboard,board); CopyBoard(Stcolor,color); X InitializeStats(); GameCnt = 0; X kingmoved[white] = kingmoved[black] = false; X castld[white] = castld[black] = false; X side = white; X for (j = 0; Book[i][j] > 0; j++) X { X MoveList(side,1); X found = false; X for (pnt = TrPnt[1]; pnt < TrPnt[2]; pnt++) X { X node = &Tree[pnt]; X mv = (node->f << 8) + node->t; X if (mv == Book[i][j]) X { X found = true; X MakeMove(side,node,&tempb,&tempc,&temps); X break; X } X } X if (!found) break; X side = otherside[side]; X } X if (found) printz("%d ok\n",i); X else printz("%d bad (%d)\n",i,j); X } X} X X XSetTimeControl() X{ Xlong minutes; X X TCmoves = 0; OperatorTime = 30000; X while (TCmoves <= 0) X { X gotoXY(50,24); printz("Enter #moves #minutes: "); ClrEoln(); X scanz("%hd %ld",&TCmoves,&minutes); X } X while (OperatorTime * TCmoves > 60*minutes + TCmoves) X { X gotoXY(50,24); printz("Operator time= "); ClrEoln(); X scanz("%ld",&OperatorTime); X } X TimeControl.moves[white] = TimeControl.moves[black] = TCmoves; X TimeControl.clock[white] = TimeControl.clock[black] = 60*minutes; X TCflag = true; X et = 0; X#ifndef MSDOS X (void) times(&tmbuf1); X#endif MSDOS X ElapsedTime(1); X} X X XElapsedTime(iop) Xshort iop; X{ Xshort m,s; X et = time((long *)0) - time0; X if (et < 0) et = 0; X ETnodes += 50; X if (et > et0 || iop == 1) X { X if (et > ResponseTime+ExtraTime) timeout = true; X#ifdef MSDOS X if (kbhit()) timeout = true; X#endif MSDOS X et0 = et; X if (iop == 1) X { X time0 = time((long *)0); et0 = 0; X } X#ifdef DISPLAY X m = et/60; s = (et - 60*m); X if (TCflag) X { X m = (TimeControl.clock[player] - et) / 60; X s = absv(TimeControl.clock[player]) - et - 60*m; X } X if (player == white) X if (reverse) gotoXY(20,2); else gotoXY(20,23); X else X if (reverse) gotoXY(20,23); else gotoXY(20,2); X printz("%d:%2d ",m,s); X#endif DISPLAY X#ifdef MSDOS X cputimer = 100*et; X if (et > 0) evrate = NodeCnt/(et+ft); else evrate = 0; X#else X (void) times(&tmbuf2); X cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ; X if (cputimer > 0) evrate = (100*NodeCnt)/(cputimer+100*ft); X else evrate = 0; X#endif MSDOS X ETnodes = NodeCnt + 50; X if (post) X { X gotoXY(50,22); printz("Nodes= %6ld",NodeCnt); X gotoXY(50,23); printz("Nodes/Sec= %4ld",evrate); X } X refresh(); X } X} X X Xpost_move(node) Xstruct leaf *node; X{ Xshort c,d,e,ply; X e = lpost; c = player; X gotoXY(50,3); printz("Score= %6d",node->score); X if (c == white) d = 4; else d = 5; X for (ply = 1; PrVar[ply] > 0; ply++) X { X algbr((short)(PrVar[ply]>>8),(short)(PrVar[ply] & 0x00FF),false); X if (c == white) gotoXY(50,++d); else gotoXY(60,d); X printz("%5s",mvstr1); X c = otherside[c]; X } X ClrEoln(); X lpost = d; X while (++d <= e) X { X gotoXY(50,d); ClrEoln(); X } X} X X XDrawPiece(loc) Xshort loc; X{ X#ifdef DISPLAY 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,5+2*(7-r)); printz("%c%c ",x,px[board[loc]]); X#endif DISPLAY X} X X XUpdateDisplay(f,t,flag,iscastle) Xshort f,t,flag,iscastle; X{ X#ifdef DISPLAY Xshort i,l,c,z; X if (flag) X { X i = 3; X gotoXY(3,++i); X printz("|----|----|----|----|----|----|----|----|"); X while (i<19) X { X gotoXY(1,++i); X if (reverse) z = (i/2)-1; else z = 10-(i/2); X printz("%d | | | | | | | | |",z); X gotoXY(3,++i); X printz("|----|----|----|----|----|----|----|----|"); X } X gotoXY(3,21); X if (reverse) printz(" h g f e d c b a"); X else printz(" a b c d e f g h"); X if (reverse) gotoXY(5,23); else gotoXY(5,2); X if (computer == black) printz("Computer"); else printz("Human "); X if (reverse) gotoXY(5,2); else gotoXY(5,23); X if (computer == white) printz("Computer"); else printz("Human "); X for (l = 0; l < 64; l++) DrawPiece(l); X } X else X { X DrawPiece(f); DrawPiece(t); X if (iscastle) X if (t > f) X { DrawPiece(f+3); DrawPiece(t-1); } X else X { DrawPiece(f-4); DrawPiece(t+1); } X } X refresh(); X#endif DISPLAY X} X X XPrintBoard() X{ Xshort r,c,l; X#ifndef DISPLAY Xprintz("\n"); Xfor (r = 7; r >= 0; r--) X { X for (c = 0; c <= 7; c++) X { X if (reverse) l = locn[7-r][7-c]; else l = locn[r][c]; X if (color[l] == neutral) printz(" -"); X else if (color[l] == white) printz(" %c",qx[board[l]]); X else printz(" %c",px[board[l]]); X } X printz("\n"); X } X#endif DISPLAY X} X X XSetBoard() X{ Xshort a,r,c,loc; Xchar s[80]; X X ClrScreen(); UpdateDisplay(0,0,1,0); X gotoXY(50,2); printz(". exit to main"); X gotoXY(50,3); printz("# clear board"); X a = white; X do X { X gotoXY(49,5); X printz("enter piece & location: "); ClrEoln(); scanz("%s",s); X if (s[0] == '#') X { X for (loc = 0; loc < 64; loc++) X { board[loc] = no_piece; color[loc] = neutral; } X UpdateDisplay(0,0,1,0); 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); X } X } X while (s[0] != '.'); X if (board[4] != king) kingmoved[white] = 10; X if (board[60] != king) kingmoved[black] = 10; X GameCnt = -1; Game50 = 0; BookDepth = -1; Sdepth = 0; X InitializeStats(); ClrScreen(); UpdateDisplay(0,0,1,0); X} X X XNewGame() X{ Xshort l,r,c,p; X X mate = quit = reverse = bothsides = post = randflag = TCflag = false; X hashflag = force = easy = false; X beep = true; X mycnt1 = mycnt2 = 0; X lpost = NodeCnt = epsquare = et0 = 0; X Awindow = 9000; X Bwindow = 90; X MaxSearchDepth = 30; X prune = 50; X contempt[white] = contempt[black] = 0; X#ifdef MSDOS X BookDepth = 24; X#else X BookDepth = 50; X#endif MSDOS X GameCnt = -1; Game50 = 0; X Zwmtl = Zbmtl = 0; X Developed[white] = Developed[black] = false; X castld[white] = castld[black] = false; X kingmoved[white] = kingmoved[black] = 0; X PawnThreat[0] = CptrFlag[0] = Threat[0] = false; X Pscore[0] = 12000; Tscore[0] = 12000; X TimeControl.clock[white] = TimeControl.clock[black] = 0; X TimeControl.moves[white] = TimeControl.moves[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 board[l] = Stboard[l]; color[l] = Stcolor[l]; X } X for (c = white; c <= black; c++) X for (p = pawn; p <= king; p++) X for (l = 0; l < 64; l++) X { X hashcode[c][p][l].key = (unsigned short)rand(); X hashcode[c][p][l].bd = ((unsigned long)rand() << 16) + X (unsigned long)rand(); X } X#ifdef CHESSTOOL X printf("Chess\n"); X easy = true; X#else X ClrScreen(); gotoXY(1,20); X printz("enter response time: "); ClrEoln(); X scanz("%ld",&Level); X ClrScreen(); X#endif CHESSTOOL X UpdateDisplay(0,0,1,0); X InitializeStats(); X time0 = time((long *)0); X ElapsedTime(1); X GetOpenings(); X} X X Xhelp() X{ X ClrScreen(); X gotoXY(28,1); printz("CHESS command summary"); X gotoXY(1,3); printz("g1f3 move from g1 to f3"); X gotoXY(1,4); printz("nf3 move knight to f3"); X gotoXY(1,5); printz("o-o castle king side"); X gotoXY(1,6); printz("o-o-o castle queen side"); X gotoXY(1,7); printz("set edit board"); X gotoXY(1,8); printz("switch sides with computer"); X gotoXY(1,9); printz("white computer plays white"); X gotoXY(1,10); printz("black computer plays black"); X gotoXY(1,11); printz("reverse board display"); X gotoXY(1,12); printz("both computer match"); X gotoXY(1,13); printz("random randomize play"); X gotoXY(1,14); printz("undo undo last move"); X gotoXY(42,3); printz("time change level"); X gotoXY(42,4); printz("depth set search depth"); X gotoXY(42,5); printz("post principle variation"); X gotoXY(42,6); printz("hint suggest a move"); X gotoXY(42,7); printz("bd redraw board"); X gotoXY(42,8); printz("clock set time control"); X gotoXY(42,9); printz("force enter game moves"); X gotoXY(42,10); printz("list game to chess.lst"); X gotoXY(42,11); printz("save game to file"); X gotoXY(42,12); printz("get game from file"); X gotoXY(42,13); printz("new start new game"); X gotoXY(42,14); printz("quit exit CHESS"); X gotoXY(10,21); printz("Computer: "); X if (computer == white) printz("WHITE"); else printz("BLACK"); X gotoXY(10,22); printz("Opponent: "); X if (opponent == white) printz("WHITE"); else printz("BLACK"); X gotoXY(10,23); printz("Response time: %ld",Level," sec."); X gotoXY(10,24); printz("Easy mode: "); X if (easy) printz("ON"); else printz("OFF"); X gotoXY(40,21); printz("Depth: %d",MaxSearchDepth); X gotoXY(40,22); printz("Random: "); X if (randflag) printz("ON"); else printz("OFF"); X gotoXY(40,23); printz("Transposition table: "); X if (hashflag) printz("ON"); else printz("OFF"); X refresh(); X while (getchar() != '\n'); X ClrScreen(); X UpdateDisplay(0,0,1,0); X} X X XUpdateHashbd(side,piece,f,t) Xshort side,piece,f,t; X/* X hashbd contains a 32 bit "signature" of the board position. X hashkey contains a 16 bit code used to address the hash table. X When a move is made, XOR'ing the hashcode of moved piece on the from and X to squares with the hashbd and hashkey values keeps things current. X*/ X{ X if (f >= 0) X { X hashbd ^= hashcode[side][piece][f].bd; X hashkey ^= hashcode[side][piece][f].key; X } X if (t >= 0) X { X hashbd ^= hashcode[side][piece][t].bd; X hashkey ^= hashcode[side][piece][t].key; X } X} X X XUpdatePieceList(side,loc,iop) Xshort side,loc,iop; X X/* X Array PieceList[side][Pindx] contains the location of all the pieces of X either side. Array Pindex[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 = Pindex[loc]; i <= PieceCnt[side]; i++) X { X PieceList[side][i] = PieceList[side][i+1]; X Pindex[PieceList[side][i]] = i; X } X } X else X { X PieceCnt[side]++; X PieceList[side][PieceCnt[side]] = loc; X Pindex[loc] = PieceCnt[side]; X } X} X X END_OF_gnuchess.c1 if test 41541 -ne `wc -c