diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /gnu/games |
initial import of NetBSD tree
Diffstat (limited to 'gnu/games')
-rw-r--r-- | gnu/games/Makefile | 5 | ||||
-rw-r--r-- | gnu/games/Makefile.inc | 10 | ||||
-rw-r--r-- | gnu/games/chess/DOCUMENTATION/ARTICLE | 66 | ||||
-rw-r--r-- | gnu/games/chess/DOCUMENTATION/ARTICLE.2 | 123 | ||||
-rw-r--r-- | gnu/games/chess/DOCUMENTATION/CHANGES | 362 | ||||
-rw-r--r-- | gnu/games/chess/DOCUMENTATION/COPYING | 123 | ||||
-rw-r--r-- | gnu/games/chess/DOCUMENTATION/GENERAL | 34 | ||||
-rw-r--r-- | gnu/games/chess/DOCUMENTATION/HEURISTICS | 122 | ||||
-rw-r--r-- | gnu/games/chess/DOCUMENTATION/MAN-PAGE | 161 | ||||
-rw-r--r-- | gnu/games/chess/Makefile | 21 | ||||
-rw-r--r-- | gnu/games/chess/gnuchess.book | 3878 | ||||
-rw-r--r-- | gnu/games/chess/gnuchess.c | 2310 | ||||
-rw-r--r-- | gnu/games/chess/gnuchess.h | 99 | ||||
-rw-r--r-- | gnu/games/chess/move.c | 361 | ||||
-rw-r--r-- | gnu/games/chess/move.h | 83 | ||||
-rw-r--r-- | gnu/games/chess/nondsp.c | 794 | ||||
-rw-r--r-- | gnu/games/chess/pathnames.h | 37 | ||||
-rw-r--r-- | gnu/games/chess/uxdsp.c | 936 |
18 files changed, 9525 insertions, 0 deletions
diff --git a/gnu/games/Makefile b/gnu/games/Makefile new file mode 100644 index 00000000000..1636cccfc50 --- /dev/null +++ b/gnu/games/Makefile @@ -0,0 +1,5 @@ +# $NetBSD: Makefile,v 1.3 1995/04/23 07:52:53 cgd Exp $ + +SUBDIR= chess + +.include <bsd.subdir.mk> diff --git a/gnu/games/Makefile.inc b/gnu/games/Makefile.inc new file mode 100644 index 00000000000..c4759564925 --- /dev/null +++ b/gnu/games/Makefile.inc @@ -0,0 +1,10 @@ +# from: @(#)Makefile.inc 5.1 (Berkeley) 5/11/90 +# $Id: Makefile.inc,v 1.1 1995/10/18 08:41:10 deraadt Exp $ + +BINOWN?= games +.if defined(HIDEGAME) +BINDIR?= /usr/games/hide +BINMODE?= 4700 +.else +BINDIR?= /usr/games +.endif diff --git a/gnu/games/chess/DOCUMENTATION/ARTICLE b/gnu/games/chess/DOCUMENTATION/ARTICLE new file mode 100644 index 00000000000..b2ab331d21d --- /dev/null +++ b/gnu/games/chess/DOCUMENTATION/ARTICLE @@ -0,0 +1,66 @@ +[This article was reproduced from a GNU Bulletin.] + + GNU Chess + by Stuart Cracraft + copyright 1987 Stuart Cracraft + + + GNU Chess is a communal chess program. Contributors donate their +time and effort in order to make it a stronger, better, sleeker program. +Contributions take many forms: interfaces to high-resolution displays, +opening book treatises, speedups of the underlying algorithms, additions +of extra heuristics. These contributions are then distributed to the +large user-base so that all may enjoy the fruits of our labor. The +original and continuing purpose of this project is to permanently end +the rampant hoarding of computer chess software that has been the +case for the past 20 years. + + Many people have contributed to GNU Chess. Their contributions have +improved the program from being a patzer (weak program) to being a +grandpatzer (decently strong program). In its growth since initial +release, GNU Chess has gone from approximately class D to expert +strength. It beats the Fidelity Excel commercial unit rather handily. + + GNU Chess's structure is a hybrid of the Shannon Type-A and +Type-B methods. It conducts a full-width search to a fixed-depth +and then continues with a quiescence search for many more ply. +This quiescence search helps the program find positions which +can be safely evaluated and which are not too turbulent. If +a terminal position is too turbulent, the evaluation will be +highly inaccurate. Additional searching by investigating series +of captures, checks, and other potentially imbalance-producing +moves is quite helpful. + + GNU Chess will sacrifice pieces in order to reach known winning +endings. Also, it uses a trade-down bonus to encourage the stronger +side to trade off certain types of pieces thus reaching a more +simplified and therefore ostensibly "clearer" position. + + GNU Chess has certain types of knowledge regarding easier endgames. +This allows it to play these endings somewhat better than might be +expected. + + GNU Chess has time heuristics that it uses to improve its handling +of time-controls and hasten its making of "obvious" moves. + + GNU Chess is interfaced to the SUN Windows and X Windows +display protocols and can display its pieces in elaborate format, +similar to chess diagrams. + + GNU Chess has an opening book which consists of many variations +from MCO (Modern Chess Openings). + + For comparison purposes, GNU Chess running on a VAX 8650 is +stronger than the famous Chess 4.5 running on a CDC 6400. + + We wish to acknowledge the contributions of the following +individuals: (in alphabetical order) Jim Aspnes, Wayne Christopher, +Steve Dougherty, David Goldberg, Richard Greenblatt, David Kittinger, +Richard Stallman, John Stanback, and Ken Thompson. + + Contact information: The author may be reached by a variety of +methods. Via U.S. mail: Stuart Cracraft, 5 Via Amistosa, Suite G, +Rancho Santa Margarita, Ca. 92688 USA. + By Internet: 'cracraft at wheaties.ai.mit.edu' +The author may also be contacted via the Free Software Foundation, Inc. +675 Massachusetts Ave.,Cambridge MA 02139. diff --git a/gnu/games/chess/DOCUMENTATION/ARTICLE.2 b/gnu/games/chess/DOCUMENTATION/ARTICLE.2 new file mode 100644 index 00000000000..031ae18f9e4 --- /dev/null +++ b/gnu/games/chess/DOCUMENTATION/ARTICLE.2 @@ -0,0 +1,123 @@ + + + GNU Chess: Experiences Learned + with Communal Sharing + by Stuart Cracraft + (and contributors to the GNU Project) + + +Limited sharing has characterized the computer chess community +for the past two decades. Occasional research articles give hints +and suggestions for useful features, but rarely reveal the real +details of the critically important advances. We will here +describe an effort underway (titled "GNU Chess") to create a more +open and friendly environment of sharing. + +GNU Chess is part of Project GNU, a large-scale effort in which +the philosophical goals are far-reaching. We will not go into any +great depth about these goals as they relate to the larger pro- +ject, because these are described elsewhere [1]. However, we will +mention the basic issues and the changes we hope to encourage. + +The start of the GNU Chess project was a natural result of the +experiences gleaned in writing a chess program. While the author +was at a progressive academic location [2], he was able to con- +ceive the idea of a communal chess program only after much heart- +ache. During the period of writing the initial version (which +has since undergone many improvements and whole revisions), it +became clear that the best features and most useful hints, the +very best of the heuristics, were hidden and difficult to find in +the literature. + +Sprinkled across many books, research papers, magazine articles, +accumulated in the community, during the past 25 years, there was +literally a void of true, empirical programs. Locating usable +programs was difficult. Many programs were the result of academic +work in "ivory towers", and hence were inaccessible to the common +man. Other programs were sequestered in research think-tanks. Na- +turally, developers of commercial programs carefully guarded +their source in order to protect their investment. On the other +hand, a few chess program source listings had actually been pub- +lished, but these were not really very strong, often written in a +non-general language, and frequently more pedantic than practi- +cal. + +The idea of a reasonably strong communal program solidified. +When we refer to a communal program, we do not regard this as +public-domain software. Rather, we refer to a program which is +under the shared authority of a number of individuals, the prin- +cipal contributors. These individuals have experienced and real- +ized the positive results of a sharing community and the rapid +improvements that come through contributing in such a community. +Further, these individuals devote time and energy to coordinating +the contributions of other individuals. While they exercise a +certain editorial right, this is usually not exercised arbitrari- +ly; instead, a discussion is often undertaken. + +Eventually, a working C program that played chess was available. +The coordinating institution for Project GNU [3], accepted our +suggestion of inclusion of a chess program in the GNU distribu- +tion. Initial distribution of GNU Chess commenced in October of +1986. Interest in the project increased rapidly. + +Contributions came in from many places and people. Interfaces to +X-windows and SUN-windows were donated, thus allowing very fancy +chess fonts on bit-mapped screens. Also, contributions involving +large portions of opening books such as MCO and collections of +master games were added to the distribution. Additionally, +tree-search modifications and heuristics were provided, and occa- +sionally even entire rewrites. + +The program advanced in strength by several USCF class intervals +during a period of less than one year. During this time, many +unusual features and enhancements were added to the program, usu- +ally under the coordination of two or more people, with one work- +ing in a distant-advisory capacity to the other. Frequently, gra- +duate students would give up significant time from their thesis +work to devote energy to contributing. Their corporate counter- +parts would often give up project time to make their donation. + +Contributors would often enter the project in a very forceful way +and then having made their contribution, learn the viability of +communal sharing once others had stepped in and contributed to +them, thus providing considerable reinforcement. Frequently, con- +tributors would then go into "hibernation" for a long period of +time, but most of them remained open to contributing and were +helpful when asked to reprogram their particular contribution in +a more recent version. + +GNU Chess has made great strides in relatively little time. It +has run on many different hardware architectures and has been +compiled by a number of C compilers [4]. A sampling of the com- +puters on which the program has run is: National 32032, Vax +11/750, 8550, 8600, 8650, Motorola 68020, CCI 5/32, CCI 6/32 +(tahoe), Cray XMP. + +It is our belief that GNU Chess will stimulate graduate research +in computer chess theory and practice. When students are able to +easily obtain a state-of-the-art program in order to test out +their ideas, they will no longer need to reinvent the wheel. The +students will be able to investigate their research areas much +more thoroughly, because they will spend more time on the specif- +ic research areas they are concerned about. Basically, GNU Chess +"frees up" time in order to get on to more fundamental issues. + +We also feel that as other researchers gain trust in the GNU +Chess project, they will be more likely to release their results +directly and rapidly, through journal articles, or directly to +the GNU project, and in fact become contributors and join the +present list [5]. At the very least, a communal, ever-growing +program will encourage the few "closeted" researchers to be some- +what more open in their approach to disseminating advances. + +In whatever form it takes, the progress toward elaboration of +machine chess is ongoing, and we hope that GNU chess will be +helpful to the community. Copies of GNU Chess source and "book", +as well as additional experimental code are available from the +Free Software Foundation [3] or the author [6]. + + +[1] The GNU Manifesto, Richard Stallman, Free Software Foundation, Inc. + +[2] University of Southern California, Information Sciences Institute. + diff --git a/gnu/games/chess/DOCUMENTATION/CHANGES b/gnu/games/chess/DOCUMENTATION/CHANGES new file mode 100644 index 00000000000..9866075ab8a --- /dev/null +++ b/gnu/games/chess/DOCUMENTATION/CHANGES @@ -0,0 +1,362 @@ + GNU CHESS HISTORY + (#include "../version.h") + +August 1, 1989 -- Jay Scott +He proofread the opening book and made +corrections. + +June 21, 1989 -- Hes @log-se.sv +He contributed new move generation routines (move.c move.h) to speedup +move generation and the overall program, by about 15-30% + +June 9, 1989 -- Tim Radzy (unet!nplab4!radz@ames.arc.nasa.gov) +He fixed a bug in xchess/board.c. In a post-game new-game situation, +castling wouldn't be permitted under circumstances. Tim made +it possible to castle again. + +May 12, 1989 -- Joe Garbarini (garbarini%kegger@circus.llnl.gov) +Recommended changes to documentation vis a vis chesstool usage. + +May 5, 1989 -- Jouko Holopainen (jhol@tolsun.oulu.fi) +Wrote code to support underpromotion. +Changed interface to accept ECO/Informator style moves. + +April 30, 1989 -- Various GNU contributors +setlinebuf() modification for xchess/chesstool. +check for zero division in time printout. + +January 17, 1989 -- Anders Thulin +Provided extensive addition to the opening book for his +favorite opening the Vienna Game. This was drawn from ECO. + +November 23, 1988 -- Stuart Cracraft +Installed new version of Xchess that is better debugged, works on +the next version of X. Thanks to Wayne Christopher and Arturo Perez. + +August 28, 1988 -- Stuart Cracraft +Removed a sacrifice line from the Giuoco Piano entry in the opening +book; the program didn't seem to like the positions it got from this line. + +December 30, 1987 -- John Stanback +Wrote a short blurb on the heuristics contained in GNU Chess. It resides +in the subdirectory DOCUMENTATION as the file HEURISTICS. + +December 17, 1987 -- John Stanback +Modified criteria for positional evaluation in quiescence search +to include positions in which the estimated score lies within +the alpha-beta window; fixed a bug in the king proximity to pawns heuristic; +fixed a bug involving passed pawn heuristics; + +December 16, 1987 -- Stuart Cracraft +Added automatic 'list' upon exit (both in display, non-display, and +chesstool mode); command-line setting of tournament time controls +bug fixed. + +December 14, 1987 -- John Stanback +GNU defeated the commercial product 'Fidelity Excellence' 5.5-4.5 in +a 10-game match. It was running at about 500 nodes per second (typical +of its speed on a VAX 8650) and this would indicate its strength +would be about USCF 1875-1900. + +December 4, 1987 -- John Stanback +Man page added. Command line arguments now specify regular clock +settings if so desired (useful for SUN players). Thinking +on opponent's time is now disabled by default. Estimated +rating is 1850 at 500 nodes per second. + +October 20, 1987 -- Stuart Cracraft +Fixed GNU/SUN interaction. Chesstool and its features now +seem to fully work. + +October 5, 1987 -- Ken Thompson +GNU beat Belle (actually drew due to a bug, but +Ken kept GNU playing through to the win) while +running on a Cray XMP-48. In this 3-1 time handicap game +Belle outsearched Cray GNU by 10-1 (even with the handicap). + +September 26, 1987 -- John Stanback at HP +Hash table functioning. Thinking on opponent's +time functioning. + +August 20, 1987 -- Mike Meyer at Berkeley +Mike ran GNU Chess on a Cray 1 supercomputer. +The system was very heavily loaded, so the +program was not as speedy as with the Cray below. + +August 16, 1987 -- David Goldberg at SUN +He added "chesstool" support so that this +version of GNU Chess can run under the +display manager "chesstool". + +August 15, 1987 -- John Stanback at HP +Hash tables, more heuristics, a modified +search which is more efficient. He also +discovered a bug in the piece-exchanger. This +would cause the program to exchange pieces suboptimally. +With this fix, the program should play much +more strongly. + +August 13, 1987 -- Ken Thompson at Bell Labs +Ken ran GNU Chess on a Cray XMP supercomputer + (among other processors). The program got + about 3000-4000 chess positions per second + which is comprable to today's fastest bit-slice + commercial machines. Also, he had GNU Chess + play two games against Belle. + +July 19, 1987 -- Jay Scott & John Stanback + Many positional heuristics have been added. + +July 18, 1987 -- Stuart Cracraft + Improvements have been made to the opening + book. It is mostly an MCO book, containing + major variations from many of the major openings + and particularly in-depth on Sicilian. + +May 11, 1987 -- John Stanback at HP + He donated his chess program, a fairly mature + and strong program. + +May 1, 1987 -- Stuart Cracraft + He added several bug fixes various people + had reported. He also changed makemove() so that + the calling syntax is makemove(movelist,index,board) + rather than makemove(move,board). Having the latter + tickled a bug in at least one manufacturer's C-compiler, + so rather than write fancy code, we simplified it. + +April 25, 1987-- Jim Aspnes at MIT +He added all sorts of useful capabilities, +including positional evaluation in the tree +search using a table-driven algorithm, +modifying transposition table code in order +to work properly, though it doesn't improve +speed too much, checkmates/stalemates detected +in the search, en passant captures allowed, +detect repeated positions, iterative deepening, +quicker quiescence search, tournament time controls, +sqattacked sped up by a factor of 4, compile-time +debugging options. + +January 2, 1987 -- Stuart Cracraft + He added a few more Tal games to the collection. + +January 2, 1987 -- Jim Aspnes at MIT + He contributed MCO variations for the Catalan, + Queen's Indian, and Reti openings. + +December 29, 1986 -- Jim Aspnes at MIT + He contributed all MCO variations of the Najdorf + to the opening book. He also contributed a LISP + macro (written in GNU Emacs Lisp) to convert + xchess game formats to GNU Chess opening book + format. + +December 14, 1986 -- Ken Thompson at Bell Labs + He contributed almost 200 games by Tal to + our collection of Tal-games, bringing the + total number of Tal positions in the book + to 10,692. Total book positions now 13,207. + These reside in bookin, bookin.bdg, bookin.tal. + Note that presently, only bookin and bookin.tal + can be used. The new Tal positions came in a + slightly different format, which we have chosen + to adopt as our standard format. All book + games in bookin and bookin.bdg will gradually + change into the new standard format. + +December 11, 1986 -- Stuart Cracraft + Added "averages" for node-count per move, + cpu per move, rate per move to list_history + and write_history. + New version of Xchess installed. + Started typing in Tal games into "bookin.tal". + Added "total book positions" printout to "book" + and "enter" statistics printout. + +December 10, 1986 -- Stuart Cracraft + Implemented aspiration search in normal + alpha-beta search. Speedups of 3% to 40% + have been noticed in most positions. + Occasionally a slower search will result, + but it is thought these are worth the + usual speedups. + +December 9, 1986 -- Stuart Cracraft + Fixed minor bug in write_history() + Added another Tal game, 2nd game of 1st world + championship match with Botvinnik, a Benoni. + +December 9, 1986 -- Stuart Cracraft + Enhanced parallelism. All parallel processors + now communicate via a shared data file and + are kept running (in idle loops watching the + shared data file). This saves us a few seconds + on each move since the 'rsh' need not be invoked + more than once (at the beginning). Since the + shared data file is now implemented, we will + next work towards a "parallel anarchy" in which + any processor can use any other processor in + order to reduce its search. The current scheme + with the program being only as fast as its slowest + processor, is quite inefficient. + +December 1, 1986 -- Jim Aspnes at MIT + Added a couple of Master games from + Modern Chess Openings 12 (a Fischer game, + and a Matanovic game). + +November 30, 1986 -- Stuart Cracraft + Added parallelism. Can now handle multiple + processors (sharing same disk). Later we will + add the capability to use processors not sharing + the same disk. Modified README and MAN-PAGE. + +November 26, 1986 -- Stuart Cracraft + Fixed a few bugs in book-mailing mechanism. + Fixed a bug regarding situations where only + one move is available. + Fixed a bug in read_history() that caused + Black queenside castles to be mishandled. + +November 25, 1986 -- Stuart Cracraft + Added two pawn heuristics. Reward pawns moving into + a phalanx of pawns. A phalanx is two or more + horizontally-connected pawns. Likewise, penalize + pawns leaving a phalanx of pawns. The penalty for + leaving is a little more than the reward for + entering. + +November 24, 1986 -- Stuart Cracraft + A user reported an unbelievable bug. Investigation + of this bug led to the discovery that GNU Chess was + not picking the move judged best by the tree search + in all cases. This resulted in the bug showing + itself which further showed that the program was + selecting an inferior move. This may result in an + improvement to the program's play. + +November 24, 1986 -- Stuart Cracraft + Added two heuristics. Penalize king moves if + the king hasn't castled yet. Also, penalize pawn + moves which produce doubled pawns. Should + probably have something for isolated pawns + too. + +November 23, 1986 -- Wayne Christopher at Berkeley + New version of X chess display front-end. + Fixed bugs include multiple pieces, runs + on SUNS & Bobcats, loads saved games. + +November 23, 1986 -- Stuart Cracraft + Cleaned up some minor bugs regarding history. + Added "Illegal command" error message at Wayne's + request. + +November 22, 1986 -- David Goldberg at SUN Microsystems + He complained that GNU Chess was memory-hungry. + A few minor modifications to hash.c reduced + uninitialized data space 87% and text space + 12%. This should make it easier for GNU Chess + to run on small computers. + +November 22, 1986 -- Stuart Cracraft + "read" command was working, but needed + additional tweaking so that history + array would be printed by list_history(). + +November 19, 1986 -- Stuart Cracraft + Added "read" command which reads a history + file (game listing) and restores the board + to as if the person was still playing that. + particular game. Generally cleaned up + history mechanism, made it more orthogonal. + Revised README. Added doc to MAN-PAGE. + +November 16, 1986 -- Stuart Cracraft + More opening book bugs found and fixed. + Added capability to accept abbreviated-algebraic notation + for entering "book" games from files. + Added approximately 2500 new positions to + opening book from games involving the + opening called Blackmar-Diemer Gambit, + a hoary line developed by Diemer in + Germany years ago. + +November 15, 1986 -- Wayne Christopher at Berkeley + He modified the move generator, resulting in + a 28% speedup. + +November 14, 1986 -- Stuart Cracraft + He documented a lot of the GNU Chess modules + with brief comments for each function. More + extensive internal documentation may go in + later. + +November 14, 1986 -- Wayne Christopher at Berkeley + He created the Xchess interface for + GNU Chess to have windowing with X windows. + +November 14, 1986 -- Stuart Cracraft + He added a "randomization" feature to + the opening book. This will cause the + program to select randomly from alternate + variations whenever -DBEST is removed + from Makefile's CFLAGS. If this is not + removed, the opening play selects the + first move found in the book as it appears + "in order" in the human-readable book. + +November 14, 1986 -- David Goldberg at SUN Microsystems + He responded to a query about dbm(3) which + eventually resulted in the fixing of a subtle + bug in the book code which was causing the + program to sometimes hash to the incorrect + address and thereby produce a book move which + didn't even exist in the book. Thanks David! + +November 14, 1986 -- Stuart Cracraft + He added the "oboard" routine in util.c. This + is the reverse of the already extant "iboard" + (same module). These two routines translate + between GNU Chess internal format and + Forsythe notation. + +November 10, 1986 -- Stuart Cracraft + He added the "enter" command. This causes + the current game to be entered in the book. + Then, GNU Chess tries to mail this new entry + to the book maintainers (for inclusion in + the master copy of the book). + +November 9, 1986 -- Stuart Cracraft +He added code for an opening book. MAN-PAGE +and README were modified accordingly. + +November 8, 1986 -- Stuart Cracraft +Checks and mates are now noticed at ply-1. +This is a more complete fix to the Oct 31 fix. + +October 31, 1986 -- Stuart Cracraft +First attempt at fix to bug which causes +program to check human's king when program +itself is in check. + +October 31, 1986 -- Mly at MIT +Reported a bug which caused program to crash +when an illegal human move was played. Fixed. +Also, program was unable to play as White. Fixed. + +October 22, 1986 -- Stuart Cracraft +Pps now rewards moves which liberate bishops. + +October 19, 1986 -- Stuart Cracraft +Added bitmapper routines to distribution. +Added version notice. + +October 19, 1986 -- David Goldberg at SUN Microsystems +Interfaced GNU Chess with SUN's chesstool. + +October 18, 1986 -- Initial release date. + + diff --git a/gnu/games/chess/DOCUMENTATION/COPYING b/gnu/games/chess/DOCUMENTATION/COPYING new file mode 100644 index 00000000000..17847b71307 --- /dev/null +++ b/gnu/games/chess/DOCUMENTATION/COPYING @@ -0,0 +1,123 @@ + GNU CHESS GENERAL PUBLIC LICENSE + + Copyright (C) 1986,1987 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license, but changing it is not allowed. + + The license agreements of most software companies keep you at the +mercy of those companies. By contrast, our general public license is +intended to give everyone the right to share GNU Chess. To make +sure that you get the rights we want you to have, we need to make +restrictions that forbid anyone to deny you these rights or to ask you +to surrender the rights. Hence this license agreement. + + Specifically, we want to make sure that you have the right to give +away copies of GNU Chess, that you receive source code or else can get it +if you want it, that you can change GNU Chess or use pieces of it in new +free programs, and that you know you can do these things. + + To make sure that everyone has such rights, we have to forbid you to +deprive anyone else of these rights. For example, if you distribute +copies of GNU Chess, you must give the recipients all the rights that you +have. You must make sure that they, too, receive or can get the +source code. And you must tell them their rights. + + Also, for our own protection, we must make certain that everyone +finds out that there is no warranty for GNU Chess. If GNU Chess is +modified by someone else and passed on, we want its recipients to know +that what they have is not what we distributed, so that any problems +introduced by others will not reflect on our reputation. + + Therefore the Free Software Foundation, Inc. makes the following +terms which say what you must do to be allowed to distribute or change +GNU Chess. + + COPYING POLICIES + + 1. You may copy and distribute verbatim copies of GNU Chess source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each file a valid copyright notice +"Copyright (C) 1986,1987 Free Software Foundation, Inc.", containing the +year of last change for the file in question; keep intact the notices +on all files that refer to this License Agreement and to the absence +of any warranty; and give any other recipients of the GNU Chess +program a copy of this License Agreement along with the program. + + 2. You may modify your copy or copies of GNU Chess source code or +any portion of it, and copy and distribute such modifications under +the terms of Paragraph 1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating + who last changed such files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, + that in whole or in part contains or is a derivative of GNU Chess + or any part thereof, to be freely distributed + and licensed to all third parties on terms identical to those + contained in this License Agreement (except that you may choose + to grant more extensive warranty protection to third parties, + at your option). + + c) if the modified program serves as a text editor, cause it + when started running in the simplest and usual way, to print + an announcement including a valid copyright notice ("Copyright + (C)", the year of authorship, and all copyright owners' names), + saying that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of + this License Agreement. + + 3. You may copy and distribute GNU Chess or any portion of it in +compiled, executable or object code form under the terms of Paragraphs +1 and 2 above provided that you do the following: + + a) cause each such copy of GNU Chess to be accompanied by the + corresponding machine-readable source code; or + + b) cause each such copy of GNU Chess to be accompanied by a + written offer, with no time limit, to give any third party + free (except for a nominal shipping charge) machine readable + copy of the corresponding source code; or + + c) in the case of a recipient of GNU Chess in compiled, executable + or object code form (without the corresponding source code) you + shall cause copies you distribute to be accompanied by a copy + of the written offer of source code which you received along + with the copy of GNU Chess. + + 4. You may not copy, sublicense, distribute or transfer GNU Chess +except as expressly provided under this License Agreement. Any attempt +otherwise to copy, sublicense, distribute or transfer GNU Chess is void and +your rights to use GNU Chess under this License agreement shall be +automatically terminated. However, parties who have received computer +software programs from you with this License Agreement will not have +their licenses terminated so long as such parties remain in full compliance. + +Your comments and suggestions about our licensing policies and our +software are welcome! Please contact the Free Software Foundation, Inc., +1000 Mass Ave, Cambridge, MA 02138, or call (617) 876-3296. + + NO WARRANTY + + BECAUSE GNU CHESS IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY +NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT +WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, +AND/OR OTHER PARTIES PROVIDE GNU CHESS "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE GNU CHESS PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL FREE SOFTWARE +FOUNDATION, INC., AND/OR ANY OTHER PARTY WHO MAY MODIFY AND +REDISTRIBUTE GNU CHESS AS PERMITTED ABOVE, BE LIABLE TO YOU FOR +DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, +INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA +BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY +FREE SOFTWARE FOUNDATION, INC.) THE PROGRAM, EVEN IF YOU HAVE BEEN +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY +OTHER PARTY. +====================================================================== diff --git a/gnu/games/chess/DOCUMENTATION/GENERAL b/gnu/games/chess/DOCUMENTATION/GENERAL new file mode 100644 index 00000000000..aafb7ed335e --- /dev/null +++ b/gnu/games/chess/DOCUMENTATION/GENERAL @@ -0,0 +1,34 @@ + GNU Chess + +Copyright (C) 1987 Stuart Cracraft + (Copying permission notice at the end.) + +GNU Chess is your program (as long as you follow the copyright and +licensing rules listed in the file COPYING). Your contributioinspire current and future software +developers. + +This document +------------- +This document is not meant to be a an introduction to computer chess. +The following books are excellent introductions and treatises. +They are listed in order of difficulty: + + Computer Chess (2nd edition), by David Welsh and Boris Bazcynski + The Joy of Computer Chess, by David Levy + Chess Skill in Man and Machine (2nd edition), by Peter Frey + + +Current Distribution +-------------------- +The most recent distribution of GNU Chess contains the following +main-level files and directories: + + Filename Purpose + ------------------------------------------------------ + README Pointer to main README below. + gnuchess.c Most recent version of GNU Chess + nondsp.c Non-display interface, and chesstool/xchess interface + uxdsp.c Unix (curses) display interface + ansidsp.c ANSI display interface + gnuchess.book Most recent version of opening book + diff --git a/gnu/games/chess/DOCUMENTATION/HEURISTICS b/gnu/games/chess/DOCUMENTATION/HEURISTICS new file mode 100644 index 00000000000..254b34472ab --- /dev/null +++ b/gnu/games/chess/DOCUMENTATION/HEURISTICS @@ -0,0 +1,122 @@ +This file contains a description of GNU's heuristics. + Copyright (C) 1986, 1987 Free Software Foundation, Inc. + +This file is part of CHESS. + +CHESS is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY. No author or distributor +accepts responsibility to anyone for the consequences of using it +or for whether it serves any particular purpose or works at all, +unless he says so in writing. Refer to the CHESS General Public +License for full details. + +Everyone is granted permission to copy, modify and redistribute +CHESS, but only under the conditions described in the +CHESS General Public License. A copy of this license is +supposed to have been given to you along with CHESS so you +can know your rights and responsibilities. It should be in a +file named COPYING. Among other things, the copyright notice +and this notice must be preserved on all copies. */ + + -- requested by main author +Heuristic descriptions for CHESS. + +Revision: 12-16-87 + +Copyright (c) 1987 by John Stanback + + Here is a brief description of the heuristics used in the positional + evaluator of the GNU Chess program. Many heuristics are functions of the + stage of the game which is based on the total non-pawn material remaining + for both sides. + + +PAWNS + The material value of a pawn is 100 points. Isolated pawns get a + penalty depending on which file they occupy: + (12,14,16,20,20,16,14,12) for files (a..h). + Doubled pawns (which are not also isolated) get a penalty of 12 + points. Backward pawns (defined simply as not being defended by a + pawn with the square in front also not defended by a a pawn) are + penalized 6 points. A 4 point penalty is also invoked for each attack + by the opponent to a backward pawn and for a backward pawn on a + half-open file. Pawn Advancement in the centre is given a bonus of + about 4 points per rank in the opening increasing to about 8 points + per rank in the ending. Advancement on the edges is given a lower + bonus. Pawns on the e and d files and on the 2nd rank are given a 10 + point penalty. An additional penalty of 15 points is invoked if these + pawns are also blocked. Pawns within 2 squares of the king are given + a 10 point bonus. Passed pawns are given a bonus for increasing rank + which is a function of stage of the game and of whether the opponent + blocks or attacks one or more squares in front of the pawn or if the + opponents king is in the square of the pawn. This bonus ranges from + about 15 points for a pawn on the second rank up to about 300 points + for a passed pawn on the 7th rank which can't be stopped from + queening. + + +KNIGHTS + The material value of a knight is 330 points. The main heuristic for + knights is a bonus for proximity to the centre. This varies from 0 + points in the corners to 30 points in the centre. Knights are also + given a bonus for being within 2 squares of each enemy piece. This + bonus is a function of the stage of the game, equalling 4 points in + the end game. A penalty of 1 point per square is given for distance + from either king. A bonus of up to 8 points (depends on stage) is + given for knights which can't be driven away by enemy pawns. + + +BISHOPS + The material value of a bishop is 330 points. Bishops are given a + bonus as material falls off the board equalling 10 points in the end + game. Bishops get a bonus for mobility and Xray mobility thru pieces + but not pawns. This bonus ranges from -4 points for a totally blocked + bishop up to 18 points for a bishop attacking 12 or more squares. + Xray attacks on an enemy R,Q,K or any undefended piece are given an 8 + point bonus. Bishops are given a bonus of 14 points if they lie on + the edge of the board up to 22 points if the lie in the centre. A + bishop is given a bonus of up to 5 points for each attack to a square + adjacent to the enemy king. + + +ROOKS + The material value of a rook is 520 points. Rook mobility is handled + similiarly to bishops with a bonus of 0 points if blocked up to 20 + points if attacking 12 squares or more. A bonus of 8 points for Xray + attacks is handled as it is for bishops. Rooks are given a bonus of + 10 points for occupying a file with no friendly pawns and a bonus of + 4 points if no enemy pawns lie on that file. After the opening Rooks + are penalized slightly depending on "taxicab" distance to the enemy + king. + + +QUEENS + The material value of a queen is 980 points. The only heuristic for a + queen is that after the opening it is penalized slightly for + "taxicab" distance to the enemy king. + + +KINGS + Kings are given a penalty for proximity to the centre in the opening + and a bonus for proximity to the centre in the endgame. The penalty + is about 24 points for being in the centre in the opening with a + bonus of about 36 points for being in the centre in the endgame. + Kings are penalized for lying on an open or half-open file or if the + adjacent file closest to the corner is open or half-open. This + penalty is up to 23 points in the opening and goes to zero in the end + game. The King is penalized up to 8 points if there are no pawns + immediately adjacent. A penalty is invoked depending on the number of + "safe" checks available by the opponent. This penalty ranges from 6 + points for one such check to 50 points for 4 or more. Depending on + game stage, Kings are given up to 10 points for castling and a + penalty of up to 40 points for moving before castling. + + +SPECIAL + If more than one piece is "hung" (attacked and not defended or + attacked by an enemy piece of lower value) an extra penalty of 10 + points is invoked for that side and the search may be extended one + ply. Pinned or trapped pieces are treated similarly. A special mating + routine is used if one side has only a king and the other has mating + material. + diff --git a/gnu/games/chess/DOCUMENTATION/MAN-PAGE b/gnu/games/chess/DOCUMENTATION/MAN-PAGE new file mode 100644 index 00000000000..bbf0aa4abf9 --- /dev/null +++ b/gnu/games/chess/DOCUMENTATION/MAN-PAGE @@ -0,0 +1,161 @@ +.TH Chess GNU +.SH NAME +Chess \- GNU Chess +.SH SYNOPSIS +.B Chess +[ +.B arg1 arg2 +] +.SH DESCRIPTION +.I Chess +plays a game of chess against the user or it plays against itself. +.PP +.I Chess +has a simple alpha-numeric board display or it can be compiled for +use with the CHESSTOOL program on a SUN workstation. +The program gets its opening moves from the file gnuchess.book which +should be located in the same directory as gnuchess. +To invoke the prgram, type 'gnuchess' or type 'chesstool gnuchess' +on a SUN workstation where 'CHESSTOOL' is installed. +The 'gnuchess' command can be followed by up to 2 command line arguments. +If one argument is given it determines the programs search time in +seconds. If two arguments are given, they will be used to set tournament +time controls with the first argument being the number of moves and the second +being the total clock time in minutes. Thus, entering 'chess 60 5' will set +the clocks for 5 minutes (300 seconds) for the first 60 moves. +If no argument is given the program will prompt the user for level of +play. +For use with CHESSTOOL, see the documentation on that program. +.PP +Once +.I Chess +is invoked, the program will display the board and prompt the user +for a move. To enter a move, use the notation 'e2e4' where the first +letter-number pair indicates the origination square +and the second letter-number pair indicates the destination square. +An alternative is to use the notation 'nf3' where +the first letter indicates the piece type (p,n,b,r,q,k). +To castle, type the origin and destination squares +of the king just as you would do for a regular move, or type +"o-o" for kingside castling and "o-o-o" for queenside. +.SH COMMANDS +.PP +In addition to legal moves, the following commands are available as responses. +.PP +.I beep +-- causes the program to beep after each move. +.PP +.I bd +-- updates the current board position on the display. +.PP +.I book +-- turns off use of the opening library. +.PP +.I both +-- causes the computer to play both sides of a chess game. +.PP +.I black +-- causes the computer to take the black pieces with the move +and begin searching. +.PP +.I level +-- allows the user to set time controls such as +60 moves in 5 minutes etc. In tournament mode, the program will +vary the time it takes for each +move depending on the situation. If easy mode is disabled (using +the 'easy' command), the program +will often respond with its move immediately, saving time on +its clock for use later on. +.PP +.I depth +-- allows the user to change the +search depth of the program. The maximum depth is 29 ply. +Normally the depth is set to 29 and the computer terminates +its search based on elapsed time rather than depth. +Using the depth command allows setting depth to say +4 ply and setting response time to a large number such as +9999 seconds. The program will then search until all moves +have been examined to a depth of 4 ply (with extensions up +to 11 additional ply for sequences of checks and captures). +.PP +.I easy +-- toggles easy mode (thinking on opponents time) +on and off. The default is easy mode ON. If easy mode is disabled, +the user must enter a 'break' or '^C' to get the programs +attention before entering each move. +.PP +.I edit +-- allows the user to set up a board position. +In this mode, the '#' command will clear the board, the 'c' +command will toggle piece color, and the '.' command will exit +setup mode. Pieces are entered by typing a letter (p,n,b,r,q,k) for +the piece followed by the coordinate. For example "pb3" would +place a pawn on square b3. +.PP +.I force +-- allows the user to enter moves for both +sides. To get the program to play after a sequence of moves +has been entered use the 'white' or 'black' commands. +.PP +.I get +-- retrieves a game from disk. The program will +prompt the user for a file name. +.PP +.I help +-- displays a short description of the commands. +.PP +.I hint +-- causes the program to supply the user with +its predicted move. +.PP +.I list +-- writes the game moves and some statistics +on search depth, nodes, and time to the file 'chess.lst'. +.PP +.I new +-- starts a new game. +.PP +.I post +-- causes the program to display the principle +variation and the score during the search. A score of +100 is equivalent to a 1 pawn advantage for the computer. +.PP +.I random +-- causes the program to randomize its move +selection slightly. +.PP +.I reverse +-- causes the board display to be reversed. That +is, the white pieces will now appear at the top of the board. +.PP +.I quit +-- exits the game. +.PP +.I save +-- saves a game to disk. The program will prompt +the user for a file name. +.PP +.I switch +-- causes the program to switch places with +the opponent and begin searching. +.PP +.I undo +-- undoes the last move whether it was the computer's +or the human's. You may also type "remove". This is equivalent +to two "undo's" (e.g. retract one move for each side). +.PP +.I white +-- causes the computer to take the white pieces +with the move and begin searching. +.SH BUGS +.PP +Pawn promotion to pieces other than a queen is not allowed. +En-Passant does not work properly with CHESSTOOOL. +The transposition table may not work properly in some +positions so the default is to turn this off. +.fi +.SH SEE ALSO +.nf +chesstool(6) +.fi + diff --git a/gnu/games/chess/Makefile b/gnu/games/chess/Makefile new file mode 100644 index 00000000000..611a02d2980 --- /dev/null +++ b/gnu/games/chess/Makefile @@ -0,0 +1,21 @@ +# from: @(#)Makefile 5.4 (Berkeley) 5/11/90 +# $Id: Makefile,v 1.1 1995/10/18 08:41:10 deraadt Exp $ + +PROG= chess +SRCS= gnuchess.c uxdsp.c move.c +CFLAGS+=-DNEWMOVE=12 +MAN= chess.6 +DPADD= ${LIBCURSES} ${LIBTERM} /usr/lib/libgnumalloc.a +LDADD= -lcurses -ltermlib -lgnumalloc +HIDEGAME=hidegame +CLEANFILES += chess.6 + +chess.6: + /bin/rm -rf ${.OBJDIR}/chess.6 + ln -s ${.CURDIR}/DOCUMENTATION/MAN-PAGE ${.OBJDIR}/chess.6 + +beforeinstall: + install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/gnuchess.book \ + ${DESTDIR}/usr/share/games + +.include <bsd.prog.mk> diff --git a/gnu/games/chess/gnuchess.book b/gnu/games/chess/gnuchess.book new file mode 100644 index 00000000000..7e8a3b5d756 --- /dev/null +++ b/gnu/games/chess/gnuchess.book @@ -0,0 +1,3878 @@ +! +! Opening Library for CHESS +! +! Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. +! Copyright (c) 1987 by Stuart Cracraft and John Stanback +! +! This file is part of CHESS. +! +! CHESS is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY. No author or distributor +! accepts responsibility to anyone for the consequences of using it +! or for whether it serves any particular purpose or works at all, +! unless he says so in writing. Refer to the CHESS General Public +! License for full details. +! +! Everyone is granted permission to copy, modify and redistribute +! CHESS, but only under the conditions described in the +! CHESS General Public License. A copy of this license is +! supposed to have been given to you along with CHESS so you +! can know your rights and responsibilities. It should be in a +! file named COPYING. Among other things, the copyright notice +! and this notice must be preserved on all copies. +! +! +! +! Four Knight's Game +e2e4 e7e5 +g1f3 b8c6 +b1c3 g8f6 +f1b5 f8b4 +o-o o-o +d2d3 b4c3 +b2c3 d7d6 +c1g5 d8e7 +f1e1 c6d8 +d3d4 d8e6 +! Giuoco Piano +e2e4 e7e5 +g1f3 b8c6 +f1c4 f8c5 +d2d3 g8f6 +b1c3 d7d6 +c1g5 h7h6 +g5f6 d8f6 +c3d5 f6d8 +! Two Knights Defence +e2e4 e7e5 +g1f3 b8c6 +f1c4 g8f6 +f3g5 d7d5 +e4d5 c6a5 +c4b5 c7c6 +d5c6 b7c6 +b5e2 h7h6 +! Two Knights Defence -- Max Lange Attack +e2e4 e7e5 +g1f3 b8c6 +f1c4 g8f6 +d2d4 e5d4 +o-o f8c5 +e4e5 d7d5 +e5f6 d5c4 +f6g7 h8g8 +! Petrov's Defence +e2e4 e7e5 +g1f3 g8f6 +f3e5 d7d6 +e5f3 f6e4 +d2d4 d6d5 +f1d3 f8d6 +o-o o-o +c2c4 c8g4 +c4d5 f7f5 +b1c3 b8d7 +! Petrov's Defence +e2e4 e7e5 +g1f3 g8f6 +d2d4 e5d4 +e4e5 f6e4 +d1d4 d7d5 +! +! Vienna Game +e2e4 e7e5 +b1c3 f8c5 +g1f3 d7d6 +d2d4 e5d4 +f3d4 g8f6 +c1g5 h7h6 +g5h4 b1c3 +! +e2e4 e7e5 +b1c3 b8c6 +g1f3 g7g6 +d2d4 e5d4 +c3d5 f8g7 +c1g5 c6e7 +f3d4 c7c6 +d5c3 h7h6 +! - - - - - - +! ECO C25/1-2 +e2e4 e7e5 +b1c3 f8c5 +f1c4 d7d6 +d2d3 c8e6 +c4e6 f7f6 +d1h5 e7d7 +c1e3 c5b6 +g1e2 b8c6 +o-o g8f6 +h5h3 d8e8 +! +e2e4 e7e5 +b1c3 f8c5 +g1f3 d7d6 +d2d4 e5d4 +f3d4 g8f6 +c1g5 h7h6 +g5h4 b8c6 +d4c6 b7c6 +f1d3 e8e7 +o-o g7g5 +! ECO C25/3-9 +e2e4 e7e5 +b1c3 b8c6 +f2f4 e5f4 +g1f3 g7g5 +h2h4 g5g4 +f3g5 h7h6 +g5f7 e7f7 +d2d4 d7d5 +c1f4 f8b4 +f1e2 b4c3 +b2c3 g8f6 +! +e2e4 e7e5 +b1c3 b8c6 +f2f4 e5f4 +g1f3 g7g5 +d2d4 g5g4 +f1c4 g4f3 +o-o d7d5 +e4d5 c8g4 +d1d2 c6e7 +d2f4 g8h6 +! +e2e4 e7e5 +b1c3 b8c6 +f2f4 e5f4 +d2d4 d8h4 +e1e2 d7d5 +e4d5 c8g4 +g1f3 o-o-o +d5c6 f8c5 +d1e1 h4h5 +c6b7 e8b8 +e2d2 g4f3 +! +e2e4 e7e5 +b1c3 b8c6 +f2f4 e5f4 +d2d4 d8h4 +e1e2 d7d6 +g1f3 c8g4 +c1f4 o-o-o +e2e3 h4h5 +f1e2 g7g5 +f3g5 f7f5 +h2h3 g4e2 +! +e2e4 e7e5 +b1c3 b8c6 +g2g3 f8c5 +f1g2 a7a6 +g1e2 d7d6 +d1d3 c8g4 +h2h3 g4e6 +o-o g8e7 +c3d5 o-o +c2c3 c5a7 +g1h2 f7f6 +! +e2e4 e7e5 +b1c3 b8c6 +g2g3 f8c5 +f1g2 d7d6 +c3a4 g8e7 +a4c5 d6c5 +d2d3 o-o +g2e3 b7b6 +d1d2 c8e6 +g1e2 d8d7 +o-o a8d8 +! +e2e4 e7e5 +b1c3 b8c6 +f1c4 f8c5 +d1g4 g7g6 +d4f3 g8f6 +g1e2 d7d6 +d2d3 c8g4 +f3g3 h7h6 +f2f4 d7e7 +c3d5 f6d5 +g3g4 d5e3 +! ECO C26/1-10 +e2e4 e7e5 +b1c3 g8f6 +g2g3 c7c6 +f1g2 d7d6 +g1e2 b7b5 +o-o b8d7 +h2h3 d8c7 +g3g4 b5b4 +c3b1 a7a5 +a2a3 c8a6 +a3b4 a5b4 +! +e2e4 e7e5 +b1c3 g8f6 +g2g3 d7d5 +e4d5 f6d5 +f1g2 c8e6 +g1f3 b8c6 +o-o f8e7 +f1e1 e7f6 +c3e4 o-o +d2d3 f6e7 +a2a3 d5b6 +! +e2e4 e7e5 +b1c3 g8f6 +g2g3 d7d5 +e4d5 f6d5 +f1g2 d5c3 +b2c3 f8d6 +g1f3 o-o +o-o b8d7 +d2d3 a1b8 +a2a4 b7b6 +a4a5 c8b7 +! +e2e4 e7e5 +b1c3 g8f6 +g2g3 f8b4 +f1g2 c7c6 +g1e2 o-o +o-o d7d5 +e4d5 c6d5 +d2d4 e5d4 +e2d4 b8c6 +c1g5 b4e7 +f1e1 h7h6 +! +e2e4 e7e5 +b1c3 g8f6 +g2g3 f8c5 +f1g2 b8c6 +g1e2 d7d6 +o-o o-o +d2d3 c8e6 +c3d5 e6d5 +e4d5 c6e7 +c1g5 f6d7 +d3d4 e5d4 +! +e2e4 e7e5 +b1c3 g8f6 +g2g3 f8c5 +f1g2 b8c6 +g1f3 d7d6 +d2d3 a7a6 +o-o o-o +c1g5 h7h6 +g5e3 c5e3 +f2e3 d6d5 +e4d5 f6d5 +! +e2e4 e7e5 +b1c3 g8f6 +g2g3 f8c5 +f1g2 o-o +d2d3 f8e8 +g1e2 c7c6 +o-o d7d5 +e5d5 f6d5 +g1h1 c8g4 +h2h3 g4e6 +c3e4 c5e7 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 f8b4 +g1e2 o-o +d2d3 c7c6 +o-o d7d5 +c4b3 d5e4 +c3e4 b8d7 +e2g3 f6e4 +d3e4 d7c5 +d1h5 c5b3 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 f8c5 +d2d3 d7d6 +c1g5 c8e6 +d1d2 b8d7 +g1e2 e6c4 +d3c4 h7h6 +g5e3 d8e7 +e2g3 c5e3 +f2e3 g7g6 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 f8c5 +d2d3 d7d6 +f2f4 b8c6 +f4f5 b6d4 +g1f3 c7c6 +f3d4 c5d4 +d1f3 b7b5 +c4b3 a7a5 +a2a3 a5a4 +! ECO C27/1-2 +e2e4 e7e5 +b1c3 g8f6 +f1c4 f6e4 +d1h5 e4d6 +h5e5 d8e7 +e5e7 f8e7 +c4b3 d6f5 +c3d5 e7d8 +d5e3 f5d4 +b3c4 c7c6 +g1e2 d4e2 +c4e2 d7d5 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 f6e4 +d1h5 e4d6 +c4b3 b8c6 +c3b5 g7g6 +h5f3 f7f6 +b5c7 d8c7 +f3f6 b7b6 +g1f3 c8a6 +f3e5 c6e5 +f6e5 e8d8 +! ECO C27/3-5 +e2e4 e7e5 +b1c3 g8f6 +f1c4 f6e4 +d1h5 e4d6 +c4b3 b8c6 +c3b5 g7g6 +h5f3 f7f5 +f3d5 d8e7 +b5c7 e8d8 +c7a8 b7b6 +d2d3 c8b7 +h2h4 f5f4 +d5f3 f8h6 +b3d5 b7a8 +f3g4 h8f8 +g1e2 e5e4 +c1f4 h6f4 +e2f4 e7e5 +g4g5 e5g5 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 f6e4 +d1h5 e4d6 +c4b3 b8c6 +c3b5 g7g6 +h5f3 f7f5 +f3d5 d8e7 +b5c7 e8d8 +c7a8 b7b6 +g1f3 c8b7 +d3d4 c6d4 +c1g5 d4f3 +d5f3 e7g5 +b3d5 e5e4 +f3b3 b7a6 +b3a4 f8h6 +a4d4 h8e8 +g2g3 g5g4 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 f6e4 +d1h5 e4d6 +c4b3 b8c6 +c3b5 g7g6 +h5f3 f7f5 +f3d5 d8e7 +b5c7 e8d8 +c7a8 b7b6 +a8b6 a7b6 +d5f3 c8b7 +d2d3 c6d4 +f3h3 e5e4 +c1e3 e4d3 +o-o-o d4c2 +e3b6 d8e8 +h3d3 f8h6 +c1b1 b7e4 +! ECO C27/6-7 +e2e4 e7e5 +b1c3 g8f6 +f1c4 f6e4 +d1h5 e4d6 +c4b3 f8e7 +g1f3 b8c6 +f3e5 o-o +o-o c6d4 +c3d5 d4b3 +a2b3 d6e8 +h5e2 e8f6 +e5c6 d7c6 +d5e7 g8h8 +e7c8 d8c8 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 f6e4 +d1h5 e4d6 +c4b3 f8e7 +g1f3 o-o +h2h4 b8c6 +f3g5 h7h6 +h5g6 e7g5 +h4g5 d8g5 +d2d3 d6f5 +c1g5 c6d4 +c3d5 d4b3 +! ECO C28/1-7 +e2e4 e7e5 +b1c3 g8f6 +f1c4 b8c6 +f2f3 f6e4 +g1f3 e4c3 +d2c3 d8e7 +b2b4 d7d6 +o-o c8e6 +c4e6 e7e6 +b4b5 c6d8 +f4e5 d6e5 +f3e5 f8d6 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 b8c6 +d2d3 c6a5 +g1e2 a5c4 +d3c4 d7d6 +o-o c8e6 +b2b3 c7c6 +e2g3 g7g6 +h2h3 h7h5 +d1d3 f8e7 +c1e3 d8d7 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 b8c6 +d2d3 f8c5 +c1g5 h7h6 +g5h4 d7d6 +c3a4 c8e6 +a4c5 d6c5 +b2b3 e6c4 +b3c4 d8d6 +g1e2 c6d4 +h4f6 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 b8c6 +d2d3 f8b4 +g1e2 d7d5 +e4d5 f6d5 +c4d5 d8d5 +o-o d5d8 +f2f4 e5f4 +c1f4 o-o +d1e1 b4d6 +e1g3 b6f4 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 b8c6 +d2d3 f8b4 +c1g5 d7d6 +g1e2 c8e6 +o-o h7h6 +g5f6 d8f6 +c3d5 e6d5 +c4d5 b4c5 +c2c3 o-o +g1h1 c6e7 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 b8c6 +d2d3 f8b4 +c1g5 h7h6 +g5f6 b4c3 +b2c3 d8f6 +g1e2 d7d6 +d1d2 c1e6 +c4b5 f6g5 +e2g3 o-o +b5c6 b7c6 +! +e2e4 e7e5 +b1c3 g8f6 +f1c4 b8c6 +d2d3 f8b4 +g1f3 d7d6 +o-o b4c3 +b2c3 c6a5 +c4b3 a5b3 +a2b3 o-o +c3c4 b7b6 +d1e2 f6d7 +c1g5 f7f6 +! ECO C29/1 +e2e4 e7e5 +b1c3 g8f6 +f1f4 d7d5 +d2d3 e5f4 +e4d5 f6d5 +c3d5 d8d5 +c1f4 f8d6 +f4d6 d5d6 +d1d2 o-o +g1f3 c8g4 +f1e2 g4f3 +! ECO C29/2-12 +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +d1f3 b8c6 +f1b5 e4c3 +b2c3 f8e7 +d2d4 o-o +b5d3 f7f6 +f3h5 g7g6 +d3g6 h7g6 +h5g6 g8h8 +g6h6 h8g8 +! +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +d1f3 f7f5 +d2d3 e4c3 +b2c3 d5d4 +f3g3 b8c6 +f1e2 c8e6 +e2f3 d8d7 +g1e2 f8c5 +c3c4 o-o +o-o e6c4 +! +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +d2d3 d8h4 +g2g3 e4g3 +g1f3 h4h5 +c3d5 c8g4 +f1g2 g3h1 +d5c7 e8d7 +c7h8 b8c6 +c1e3 f7f6 +d3d4 f6e5 +! +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +d2d3 f1b4 +d3e4 d8h4 +e1e2 b8c6 +g1f3 c8g4 +c3d5 o-o-o +c2c3 f7f5 +e5f6 h8e8 +c3b4 e8e4 +c1e3 g7f6 +! +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +d2d3 e4c3 +b2c3 d5d4 +g1f3 b8c6 +c3d4 f8b4 +c1d2 b4d2 +d1d2 c6d4 +c2c3 d4f3 +g2f3 d8h4 +d2f2 h4f2 +! +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +g1f3 f1b4 +d1e2 b4c3 +b2c3 o-o +e2e3 b8c6 +f1d3 f7f5 +o-o c8e6 +c1a3 f8e8 +a1b1 a8b8 +a3b5 e6d7 +! +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +g1f3 b8c6 +f1b5 f8c5 +d2d4 c5b4 +c1d2 b4c3 +b2c3 o-o +o-o c1g4 +d1e1 f7f6 +d2e3 g4d7 +e5f6 d8f6 +! +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +g1f3 f8c5 +d1e2 c5f2 +e1d1 e4c3 +d2c3 f2b6 +c3g5 d8d7 +d1d2 o-o +a1d1 d7a4 +a2a3 c7c5 +d2c1 c8e6 +! +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +g1f3 c8g4 +d1e2 e4g5 +h2h4 g5f3 +g2f3 g4e6 +d2d4 b8c6 +c1e3 f8e7 +e2f2 d8d7 +o-o-o o-o-o +f1b5 a7a6 +! +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +g1f3 f8e7 +d1e2 e4c3 +d2c3 o-o +c1f4 c7c5 +o-o-o d8a5 +c1b1 b8c6 +a4b5 c8e6 +b5a5 f3g5 +! +e2e4 e7e5 +b1c3 g8f6 +f2f4 d7d5 +f4e5 f6e4 +g1f3 f8e7 +d2d4 o-o +f1d3 f7f6 +e5f6 e7f6 +o-o b8c6 +c3e4 d5e4 +d3e4 c6d4 +f3g5 c8f5 +c2c3 f7g5 +! +! Vienna Game +e2e4 e7e5 +b1c3 f8c5 +g1f3 d7d6 +d2d4 e5d4 +f3d4 g8f6 +c1g5 h7h6 +g5h4 b1c3 +! Three Knights Game +e2e4 e7e5 +b1c3 b8c6 +g1f3 g7g6 +d2d4 e5d4 +c3d5 f8g7 +c1g5 c6e7 +f3d4 c7c6 +d5c3 h7h6 +! Bishop's Opening +e2e4 e7e5 +f1c4 g8f6 +d2d4 e5d4 +g1f3 f6e4 +d1d4 e4c5 +o-o c5e6 +f1e1 c7c6 +b1c3 d7d5 +c4d3 f8e7 +! Ruy Lopez -- Classical Defence +e2e4 e7e5 +g1f3 b8c6 +f1b5 f8c5 +c2c3 g8f6 +d2d4 e5d4 +e4e5 f6e4 +o-o d7d5 +! Ruy Lopez -- Birds Defence +e2e4 e7e5 +g1f3 b8c6 +f1b5 c6d4 +b5a4 f8c5 +o-o d4f3 +d1f3 g8e7 +d2d3 o-o +c1e3 c5b6 +b1c3 d7d6 +! Ruy Lopez -- Schliemann Defence +e2e4 e7e5 +g1f3 b8c6 +f1b5 f7f5 +b1c3 f5e4 +c3e4 d7d5 +f3e5 d5e4 +e5c6 d8d5 +c2c4 d5d6 +c6a7 c8d7 +! Ruy Lopez -- Old Steinitz Defence +e2e4 e7e5 +g1f3 b8c6 +f1b5 d7d6 +d2d4 c8d7 +b1c3 g8f6 +o-o f8e7 +f1e1 e5d4 +f3d4 o-o +d4f5 f8e8 +! Ruy Lopez -- Old Steinitz Defence +e2e4 e7e5 +g1f3 b8c6 +f1b5 d7d6 +d2d4 c8d7 +b1c3 g8f6 +b5c6 d7c6 +d1d3 e5d4 +f3d4 f8e7 +c1g5 c6d7 +! Ruy Lopez -- Modern Steinitz Defence +e2e4 e7e5 +g1f3 b8c6 +f1b5 a7a6 +b5a4 d7d6 +d2d4 b7b5 +a4b3 c6d4 +f3d4 e5d4 +c2c3 d4c3 +b1c3 c8b7 +! Ruy Lopez -- Open Defence +e2e4 e7e5 +g1f3 b8c6 +f1b5 a7a6 +b5a4 g8f6 +o-o f6e4 +d2d4 b7b5 +a4b3 d7d5 +d4e5 c8e6 +c2c3 f8c5 +b1d2 o-o +! Ruy Lopez -- Open Defence +e2e4 e7e5 +g1f3 b8c6 +f1b5 a7a6 +b5a4 g8f6 +o-o f8e7 +f1e1 b7b5 +a4b3 d7d6 +c2c3 o-o +h2h3 c6a5 +b3c2 c2c4 +d2d4 d8c7 +! Ruy Lopez +e2e4 e7e5 +g1f3 b8c6 +f1b5 a7a6 +b5c6 d7c6 +d2d4 e5d4 +d1d4 d8d4 +f3d4 c8d7 +c1e3 o-o-o +b1d2 g8e7 +! Scotch Game +e2e4 e7e5 +g1f3 b8c6 +d2d4 e5d4 +f3d4 f8c5 +c1e3 d8f6 +c2c3 g8e7 +b1d2 d7d6 +e3c5 d6c5 +! Philidor's Defence +e2e4 e7e5 +g1f3 d7d6 +d2d4 g8f6 +b8c6 b1d2 +f8c5 f1e2 +o-o o-o +d1e2 c7c6 +! Alekhine's Defence +e2e4 g8f6 +e4e5 f6d5 +c2c4 d5b6 +d2d4 d7d6 +f2f4 d6e5 +f4e5 b8c6 +c1e3 c8f5 +b1c3 e7e6 +g1f3 f8e7 +! Alekhine's Defence +e2e4 g8f6 +e4e5 f6d5 +d2d4 d7d6 +g1f3 c8g4 +f1e2 e7e6 +o-o f8e7 +h2h3 g4h5 +c2c4 d5b6 +! Kings Gambit Accepted +e2e4 e7e5 +f2f4 e5f4 +g1f3 d7d6 +f1c4 h7h6 +d2d4 g7g5 +o-o f8g7 +c2c3 b8c6 +d1b3 d8e7 +! Ponziani's Opening +e2e4 e7e5 +g1f3 b8c6 +c2c3 d7d5 +d1a4 g8f6 +f3e5 f8d6 +e5c6 b7c6 +d2d3 o-o +c1g5 h7h6 +! Caro-Kann Defence +e2e4 c7c6 +d2d4 d7d5 +e4d5 c6d5 +c2c4 g8f6 +b1c3 b8c6 +c1g5 e7e6 +c4c5 f8e7 +f1b5 o-o +g1f3 f6e4 +! Caro-Kann Defence +e2e4 c7c6 +d2d4 d7d5 +e4e5 c8f5 +f1d3 f5d3 +d1d3 e7e6 +b1c3 d8b6 +b1d2 c6c5 +d4c5 f8c5 +! Caro-Kann Defence +e2e4 c7c6 +b1c3 d7d5 +g1f3 c8g4 +h2h3 g4f3 +d1f3 e7e6 +d2d4 g8f6 +f1d3 d5e4 +c3e4 d8d4 +c2c3 d4d8 +! French Defence -- Classical +e2e4 e7e6 +d2d4 d7d5 +b1c3 g8f6 +c1g5 f8e7 +e4e5 f6d7 +g5e7 d8e7 +d1d2 o-o +f2f4 c7c5 +g1f3 b8c6 +o-o-o c5c4 +! French Defence -- MacCutcheon +e2e4 e7e6 +d2d4 d7d5 +b1c3 g8f6 +c1g5 c8g4 +e4e5 h7h6 +g5d2 g4f3 +g2f3 f6e4 +d1g4 e8f8 +h2h4 c7c5 +! French Defence -- Rubenstein +e2e4 e7e6 +d2d4 d7d5 +b1c3 d5e4 +c3e4 b8d7 +g1f3 g8f6 +e4f6 d7f6 +f1d3 b7b6 +d1e2 c8b7 +c1g5 f8e7 +! French Defence -- Winawer +e2e4 e7e6 +d2d4 d7d5 +b1c3 f8b4 +e4e5 c7c5 +a2a3 b4c3 +b2c3 b8d7 +d1g4 o-o +g1f3 b8c6 +f1e3 f7f5 +! French Defence -- Tarrasch +e2e4 e7e6 +d2d4 d7d5 +b1d2 b8c6 +g1f3 g8f6 +e4e5 f6d7 +d2b3 f7f6 +f1b5 f8e7 +c1f4 o-o +! Sicilian Defence -- Dragon Variation +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +f1e2 g7g6 +c1e3 f8g7 +o-o o-o +d4b3 c8e6 +f2f4 c6a5 +f4f5 e6c4 +! Sicilian Defence -- Dragon Variation +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g7g6 +b1c3 f8g7 +c1e3 g8f6 +f1c4 o-o +! Sicilian Defence -- Boleslavsky Variation +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +f1e2 e7e5 +d4b3 f8e7 +o-o o-o +c1e3 c8e6 +! Sicilian Defence -- Najdorf +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +d1d2 f8e7 +o-o-o o-o +! Sicilian Defence -- Najdorf +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +f1e2 e7e5 +d4b3 f8e7 +o-o o-o +f2f4 b7b5 +a2a3 c8b7 +! Sicilian Defence -- Najdorf +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +g2g3 e7e5 +d4e2 c8e6 +f1g2 b7b5 +o-o b8d7 +! Sicilian Defence -- Closed +e2e4 c7c5 +b1c3 b8c6 +g2g3 g7g6 +f1g2 f8g7 +d2d3 e7e6 +c1e3 d7d6 +g1e2 c6d4 +d1d2 d8h4 +o-o g8d7 +! Nimzowitsch Defence +e2e4 b8c6 +d2d4 d7d5 +e4e5 f7f6 +g1f3 c1g4 +f1e2 e7e6 +e5f6 g8f6 +c2c3 f8d6 +c1g5 d8d7 +! Queens Gambit Accepted +d2d4 d7d5 +c2c4 d5c4 +g1f3 g8f6 +e2e3 e7e6 +f1c4 c7c5 +o-o a7a6 +d1e2 b7b5 +c4d3 c5d4 +e3d4 b8c6 +! Queens Gambit -- Catalan +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 f8e7 +f1g2 o-o +o-o f6d7 +d1c2 c7c6 +b1d2 b7b6 +e2e4 c8b7 +b2b3 a8c8 +! Queens Gambit Declined -- Orthodox +d2d4 d7d5 +c2c4 e7e6 +b1c3 g8f6 +c1g5 f8e7 +e2e3 o-o +g1f3 b8d7 +a1c1 c7c6 +f8d3 d5c4 +f1c4 f6d5 +! Queens Gambit Declined -- Cambridge Springs +d2d4 d7d5 +c2c4 e7e6 +b1c3 g8f6 +c1g5 b8d7 +e2e3 c7c6 +g1f3 d8a5 +f3d2 f8b4 +d1c2 o-o +g5h4 c6c5 +! Queens Gambit Declined -- Exchange Var. +d2d4 d7d5 +c2c4 e7e6 +b1c3 g8f6 +c1g5 b8d7 +c4d5 e6d5 +e2e3 c7c6 +f1d3 f8e7 +d1c2 o-o +g1e2 f8e8 +! Queens Gambit Declined -- Semi-Tarrasch +d2d4 d7d5 +c2c4 e7e6 +b1c3 g8f6 +g1f3 c7c5 +c4d5 c5d4 +d1d4 e6d5 +e2e4 b8c6 +f1b5 f6e4 +! Queens Gambit Declined -- Tarrasch +d2d4 d7d5 +c2c4 e7e6 +b1c3 c7c5 +c4d5 e6d5 +g1f3 b8c6 +g2g3 g8f6 +f1g2 f8e7 +o-o o-o +! Queens Gambit Declined -- Vienna +d2d4 d7d5 +c2c4 e7e6 +g1f3 g8f6 +f1b5 f8b4 +b1c3 d5c4 +e2e4 c7c5 +e4e5 c5d4 +d1a4 b8c6 +o-o-o c1d2 +! Queens Gambit Declined -- Slav (Marshall Gambit) +d2d4 d7d5 +c2c4 c7c6 +b1c3 e7e6 +e2e4 d4e4 +c3e4 f8b4 +c1d2 d8d4 +d2b4 d4e4 +f1e2 b8a6 +b4d6 b7b6 +! Queens Gambit --Slav (Krause) +d2d4 d7d5 +c2c4 c7c6 +g1f3 g8f6 +b1c3 d5c4 +a2a4 c8f5 +f3e5 e7e6 +f2f3 f8b4 +c1g5 h7h6 +g5f6 d8f6 +e2e4 f5h7 +! Modern Benoni Counter Gambit +d2d4 g8f6 +c2c4 c7c5 +d4d5 e7e6 +b1c3 e6d5 +c4d5 d7d6 +e2e4 g7g6 +f1d3 f8g7 +g1e2 o-o +o-o a7a6 +a2a4 d8c7 +! Queens Pawn Game +d2d4 d7d5 +g1f3 g8f6 +c1f4 c7c5 +e2e3 b8c6 +c2c3 d8b6 +d1c1 c8f5 +d4c5 b6c5 +b1d2 a8c8 +f3d4 c6d4 +e3d4 c5b6 +! Pirc-Robatsch Defence +d2d4 d7d6 +e2e4 g8f6 +b1c3 g7g6 +c1g5 f8g7 +d1d2 b8d7 +o-o-o e7e5 +d4e5 d6e5 +g1f3 h7h6 +g5h4 g6g5 +h4g3 d8e7 +! Pirc-Robatsch Defence +d2d4 d7d6 +e2e4 g8f6 +b1c3 g7g6 +f1c4 c7c6 +d1e2 f8g7 +g1f3 o-o +c1g5 b7b5 +c4d3 d8c7 +! Queens Indian Defence +d2d4 g8f6 +c2c4 e7e6 +g1f3 b7b6 +g2g3 c8b7 +f1g2 f8e7 +o-o o-o +b1c3 f6e4 +d1c2 e4c3 +c2c3 d7d6 +c3c2 f7f5 +! Queens Indian Defence +d2d4 g8f6 +c2c4 e7e6 +g1f3 b7b6 +e2e3 c8b7 +f1d3 f8e7 +b1c3 d7d5 +o-o o-o +d1e2 b8d7 +! Nimzo-Indian Defence +d2d4 g8f6 +c2c4 e7e6 +b1c3 f8b4 +d1c2 d7d5 +a2a3 b4c3 +c2c3 b8c6 +g1f3 f6e4 +c3b3 c6a5 +b3a4 c7c6 +! Nimzo-Indian Defence (Rubenstein) +d2d4 g8f6 +c2c4 e7e6 +b1c3 f8b4 +e2e3 o-o +f1d3 d7d5 +g1f3 c7c5 +o-o b8c6 +a2a3 b4c3 +b2c3 d5c4 +d3c4 d8c7 +! Nimzo-Indian Defence -- Samisch +d2d4 g8f6 +c2c4 e7e6 +b1c3 f8b4 +a2a3 b4c3 +b2c3 o-o +f2f3 d7d5 +c4d5 e6d5 +e2e3 c8f5 +g1e2 b8d7 +e2g3 f5g6 +! Nimzo-Indian Defence +d2d4 g8f6 +c2c4 e7e6 +b1c3 f8b4 +c1d2 o-o +e2e3 d7d5 +g1f3 c7c5 +a2a3 b4c3 +d2c3 f6e4 +a1c1 e4c3 +c1c3 c5d4 +! Grunfeld Defence +d2d4 g8f6 +c2c4 g7g6 +b1c3 d7d5 +c4d5 f6d5 +e2e4 d5c3 +b2c3 c7c5 +f1c4 f8g7 +g1e2 o-o +o-o c5d4 +c3d4 b8c6 +! Grunfeld Defence -- Smyslov +d2d4 g8f6 +c2c4 g7g6 +b1c3 d7d5 +g1f3 f8g7 +d1b3 d5c4 +b3c4 o-o +e2e4 c8g4 +c1e3 f6d7 +o-o-o b8c6 +! Grunfeld Defence +d2d4 g8f6 +c2c4 g7g6 +b1c3 d7d5 +c1f4 f8g7 +d2d3 o-o +c4d5 f6d5 +c3d5 d8d5 +f4c7 b8c6 +! Kings Indian Defence -- Classical +d2d4 g8f6 +c2c4 g7g6 +b1c3 f8g7 +e2e4 d7d6 +g1f3 o-o +f1e2 e7e5 +o-o b8c6 +c1e3 f8e8 +d4e5 d6e5 +! Kings Indian Defence -- 4 pawns attack +d2d4 g8f6 +c2c4 g7g6 +b1c3 f8g7 +e2e4 d7d6 +f2f4 c7c5 +g1f3 o-o +d4d5 e7e6 +f1d3 e6d5 +c4d5 d8b6 +! Kings Indian Defence -- Samisch +d2d4 g8f6 +c2c4 g7g6 +b1c3 f8g7 +e2e4 d7d6 +f2f3 o-o +c1e3 e7e5 +d4d5 c7c6 +g1e2 c6d5 +c3d5 f6d5 +! Kings Indian Defence -- Main Line +d2d4 g8f6 +c2c4 g7g6 +g2g3 f8g7 +f1g2 o-o +b1c3 d7d6 +g1f3 b8d7 +o-o e7e5 +e2e4 c7c6 +h2h3 d8b6 +! Kings Indian Defence +d2d4 g8f6 +c2c4 g7g6 +b1c3 f8g7 +g1f3 o-o +c1f4 d7d6 +h2h3 b8d7 +e2e3 c7c6 +! Dutch Defence +d2d4 f7f5 +g2g3 e7e6 +f1g2 g8f6 +g1f3 f8e7 +o-o o-o +c2c4 d7d6 +b1c3 d8e8 +d1c2 e8h5 +b2b3 b8c6 +c1a3 a7a5 +! English Opening +c2c4 e7e5 +b1c3 g8f6 +g1f3 b8c6 +e2e4 f8b4 +d2d3 d7d6 +f1e2 o-o +o-o b4c3 +b2c3 d8e7 +! English Opening +c2c4 g8f6 +b1c3 d7d5 +c4d5 f6d5 +e2e4 d5f4 +f1c4 c8e6 +c4e6 f7e6 +! English Opening +c2c4 e7e5 +b1c3 g8f6 +g1f3 b8c6 +g2g3 d7d5 +c4d5 f6d5 +f1g2 d5b6 +o-o f8e7 +d2d3 o-o +c1e3 f7f5 +! Reti -- Accepted +g1f3 d7d5 +c2c4 d5c4 +e2e3 c7c5 +f1c4 e7e6 +o-o g8f6 +b2b3 b8c6 +c1b2 a7a6 +a2a4 f8e7 +! Reti -- Neo Catalan +g1f3 d7d5 +c2c4 e7e6 +g2g3 g8f6 +f1g2 f8e7 +o-o o-o +b2b3 c7c5 +c4d5 f6d5 +c1b2 b8c6 +d2d4 b7b6 +b1c3 d5c3 +! Reti -- Barcza +g1f3 d7d5 +g2g3 g8f6 +f1g2 g7g6 +o-o f8g7 +d2d3 o-o +b1d2 b8c6 +e2e4 e7e5 +c2c3 a7a5 +f1e1 d5e4 +d3e4 f6d7 +! Sicilian Najdorf +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d1d2 b6b2 +a1b1 b2a3 +e4e5 d6e5 +f4e5 f6d7 +c3e4 h7h6 +g5h4 a3a2 +b1b3 b8c6 +d4c6 b7c6 +e4d6 f8d6 +e5d6 a6a5 +f1e2 a5a4 +b3c3 a2a1 +e2d1 a4a3 +o-o a3a2 +d2e3 o-o +! # Sicilian Defense col. 2f p. 176 MCO 12. (Incomplete game) +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d1d2 b6b2 +a1b1 b2a3 +e4e5 d6e5 +f4e5 f6d7 +f1c4 f8b4 +b1b3 a3a5 +o-o o-o +g5f6 d7f6 +e5f6 f8d8 +b3b4 a5b4 +d2g5 g7g6 +f1f4 b7b6 +f4h4 b4f8 +g1f1 a8a7 +! # Sicilian Defense col. 3g p. 176 MCO (Incomplete Game) +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d1d2 b6b2 +a1b1 b2a3 +e4e5 d6e5 +f4e5 f6d7 +f1c4 a3a5 +c4e6 f7e6 +d4e6 d7e5 +c3d5 a5d2 +e1d2 e8d7 +e6c7 a8a7 +h1e1 e5c4 +! # Parma vs. Fischer, Havana 1965. Sicilian Defense col. 4j p. 176 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d1d2 b6b2 +a1b1 b2a3 +g5f6 g7f6 +f1e2 f8g7 +o-o f6f5 +f1d1 b8c6 +d4c6 g7c3 +d2e3 b7c6 +b1b3 a3c5 +e3c5 d6c5 +b3c3 f5e4 +c3c5 c8d7 +c5e5 f7f5 +g2g4 h8g8 +g1g2 f5g4 +e5e4 h7h5 +g2g3 e8e7 +! # Matanovic, Sicilian Defense col. 5k p. 176 MCO (partial game) +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d1d2 b6b2 +a1b1 b2a3 +g5f6 g7f6 +f1e2 b8c6 +d4c6 b7c6 +o-o a3a5 +g1h1 f8e7 +f4f5 e6f5 +e4f5 c8f5 +e2a6 a5a6 +f1f5 d6d5 +b1e1 a6b7 +d2h6 o-o-o +h6h3 b7d7 +c3a4 +! # col. 6a +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d1d2 b6b2 +a1b1 b2a3 +f4f5 b8c6 +f5e6 f7e6 +d4c6 b7c6 +e4e5 d6e5 +g5f6 g7f6 +c3e4 f8e7 +f1e2 h7h6 +c2c4 f6f5 +b1b3 a3a4 +o-o f5e4 +g1h1 c6c5 +d2c3 a4c6 +c3e5 h8f8 +! # col. 7d +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d1d2 b6b2 +a1b1 b2a3 +f4f5 b8c6 +f5e6 f7e6 +d4c6 b7c6 +e4e5 f6d5 +c3d5 c6d5 +f1e2 d6e5 +o-o a8a7 +g1h1 a3c5 +c2c4 d5d4 +e2h5 g7g6 +h5d1 f8e7 +d1a4 e8d8 +f1f7 h7h6 +g5h6 e5e4 +! # col. 8 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d1d2 b6b2 +d4b3 b8d7 +g5f6 g7f6 +f1e2 h7h5 +o-o b2a3 +a1d1 f8e7 +g1h1 d7c5 +e2f3 a8a7 +b3c5 a3c5 +! # col. 9g; Minic-Barczay, Varna 1967 (partial game) +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d1d2 b6b2 +d4b3 b8c6 +f1d3 d6d5 +g5f6 g7f6 +c3a4 b2a3 +a4b6 d5d4 +o-o a8b8 +f4f5 a3b4 +d2b4 f8b4 +b6c8 b8c8 +f5e6 f7e6 +f1f6 e8e7 +a1f1 c6e5 +! # col. 10i; Matulovic-Kavalek, Sousse 1967 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d1d2 b6b2 +d4b3 b8c6 +a1b1 b2a3 +g5f6 g7f6 +f1d3 f8g7 +o-o o-o +f1f3 g8h8 +f3h3 c6e7 +f4f5 e6f5 +e4f5 c8f5 +d3f5 e7f5 +c3d5 +! # col. 11b; Joppen-Bronstein, Belgrade 1954 (partial game) +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d4b3 b6e3 +d1e2 e3e2 +f1e2 b8d7 +a2a4 f8e7 +o-o-o h7h6 +g5h4 e6e5 +f4f5 b7b6 +e2f3 c8b7 +! # col. 12e; Rajkovic-Udovcic, Yugoslav Chp. 1962 (partial game) +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 d8b6 +d4b3 b8d7 +d1f3 f8e7 +o-o-o b6c7 +f1d3 h7h6 +g5h4 g7g5 +f4g5 d7e5 +f3e2 f6g4 +b3d4 h6g5 +h4g3 c8d7 +d4f3 c7c5 +! # col. 13i; Fischer-Vukovic (partial game) +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 f8e7 +d1f3 d8c7 +o-o-o b8d7 +g2g4 b7b5 +g5f6 d7f6 +g4g5 f6d7 +a2a3 a8b8 +h2h4 b5b4 +a3b4 b8b4 +f1h3 o-o +d4e6 f7e6 +h3e6 g8h8 +c3d5 c7c4 +e6f5 f8f5 +e4f5 c8b7 +h1e1 e7f8 +! # col. 14m Parma-Tatai, Athens 1968 (partial game) +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 b7b5 +e4e5 d6e5 +f4e5 d8c7 +e5f6 c7e5 +f1e2 e5g5 +d1d3 a8a7 +c3e4 g5e5 +d4f3 e5b2 +o-o a7d7 +d3e3 c8b7 +a1b1 b2c2 +f3g5 c2c6 +f6g7 f8g7 +! # col. 15; slight advantage for white. +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +f2f4 h7h6 +g5h4 d8b6 +d1d3 b6b2 +a1b1 b2a3 +e4e5 f6d5 +c3d5 a3d3 +f1d3 e6d5 +e5e6 +! # col. 16c; Fichtl-Dolezal, CSSR 1954 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +d1f3 b8d7 +o-o-o d8c7 +f3g3 b7b5 +f1b5 a6b5 +d4b5 c7b8 +b5d6 f8d6 +g3d6 b8d6 +d1d6 h7h6 +g5f6 d7f6 +h1d1 c8b7 +f2f3 +! # col. 17e; Vasyukov-Zukharov, USSR 1960 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 e7e6 +d1d2 b8c6 +o-o-o h7h6 +g5h4 f6e4 +d2f4 e4g5 +d4c6 b7c6 +f4a4 d8b6 +f2f4 g5h7 +f4f5 a8b8 +f5e6 c8e6 +f1c4 +! # col. 18g (somewhat questionable) +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1g5 b8d7 +f1c4 d8a5 +d1d2 e7e6 +o-o-o b7b5 +c4b3 c8b7 +h1e1 a8c8 +e4e5 d7e5 +d4e6 f7e6 +e1e5 d6e5 +g5f6 +! # col. 19m; Yanofsky-Bolbochan, Stockholm 1962 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +f1e2 e7e5 +d4b3 f8e7 +o-o o-o +f2f4 b7b5 +a2a3 c8b7 +e2f3 b8d7 +g2g3 a8c8 +d1e1 d7b6 +g1h1 b6c4 +b3d2 d8d7 +d2c4 c8c4 +c1d2 d6d5 +! # col. 20p +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +f1e2 e7e5 +d4b3 f8e7 +o-o o-o +c1e3 b8d7 +a2a4 b7b6 +d1d2 c8b7 +f2f3 d8c7 +f1d1 f8c8 +b3c1 +! # col. 21b +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +g2g3 e7e5 +d4e2 f8e7 +f1g2 o-o +o-o b7b5 +h2h3 c8b7 +c3d5 f6d5 +e4d5 b8d7 +a2a4 d7c5 +e2c3 d8d7 +a4b5 a6b5 +a1a8 f8a8 +! # col. 22 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +f2f4 e7e6 +d1f3 d8b6 +d4b3 b8c6 +f1d3 f8e7 +c1e3 b6c7 +o-o o-o +a1e1 c6b4 +! # col. 23f +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +c1e3 e7e5 +d4b3 c8e6 +d1d2 b8d7 +f2f3 f8e7 +g2g4 b7b5 +g4g5 f6h5 +o-o-o o-o +h1g1 a8c8 +c3e2 +! # col. 24k; Kotkov-Polugayevski, USSR 1959 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +f1c4 e7e6 +o-o f8e7 +c4b3 o-o +f2f4 b7b5 +a2a3 c8b7 +f4f5 e6e5 +d4e2 b8d7 +e2g3 d7c5 +b3d5 b7d5 +e4d5 a8c8 +c1g5 c5d7 +g5f6 d7f6 +c3e4 c8c4 +! # col. 25o; Ciocaltea-Minic, Bucharest 1966 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 a7a6 +f1c4 e7e6 +c4b3 b7b5 +f2f4 c8b7 +f4f5 e6e5 +d4e2 b8d7 +o-o f8e7 +e2g3 a8c8 +c1g5 o-o +! # col. 26e +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +c1e3 f8g7 +f2f3 o-o +d1d2 b8c6 +o-o-o d6d5 +e4d5 f6d5 +d4c6 b7c6 +c3d5 c6d5 +d2d5 d8c7 +d5a8 c8f5 +a8f8 g8f8 +d1d2 h7h5 +f1e2 f8g8 +a2a3 c7b8 +! # col. 27i; Bikhovski-Gik, Moscow 1968 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +c1e3 f8g7 +f2f3 o-o +d1d2 b8c6 +f1c4 c8d7 +o-o-o d8a5 +c4b3 f8c8 +g2g4 c6e5 +h2h4 e5c4 +b3c4 c8c4 +d4b3 a5a6 +h4h5 c4c3 +b2c3 d7e6 +c1b1 a8c8 +e3d4 c8c4 +h5g6 h7g6 +! # col. 28k +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +c1e3 f8g7 +f2f3 o-o +d1d2 b8c6 +f1c4 c8d7 +o-o-o d8a5 +c4b3 f8c8 +h2h4 c6e5 +h4h5 f6h5 +e3h6 e5d3 +c1b1 d3b2 +b1b2 g7h6 +d2h6 c8c3 +g2g4 h5f6 +g4g5 f6h5 +! # col. 29m; Ostojic-Honfi, Monte Carlo 1968 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +c1e3 f8g7 +f2f3 o-o +d1d2 b8c6 +f1c4 c8d7 +o-o-o d8a5 +c4b3 f8c8 +c1b1 c6e5 +h2h4 e5c4 +b3c4 c8c4 +d4b3 a5c7 +h4h5 c4c3 +d2c3 c7c3 +b2c3 f6h5 +e3d4 d7e6 +h1e1 h5f6 +e4e5 d6e5 +d4e5 f6d5 +b1b2 a8c8 +! # col. 30p; Karpov-Korchnoi, 2nd match game 1974. +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +c1e3 f8g7 +f2f3 o-o +d1d2 b8c6 +f1c4 c8d7 +h2h4 a8c8 +c4b3 c6e5 +h4h5 f6h5 +o-o-o e5c4 +b3c4 c8c4 +g2g4 h5f6 +d4e2 d8a5 +e3h6 g7h6 +d2h6 f8c8 +d1d3 c4c5 +g4g5 c5g5 +d3d5 g5d5 +c3d5 c8e8 +e2c3 d7c6 +e4e5 c6d5 +e5f6 e7f6 +h6h7 g8f8 +h7h8 f8e7 +c3d5 +! # col. 31 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +g2g3 b8c6 +f1g2 c6d4 +d1d4 f8g7 +o-o o-o +d4d3 c8e6 +c3d5 f6d5 +e4d5 e6f5 +! # col. 32c; Pulsen-Cortlever, Buenos Aires 1939. +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +c1g5 f8g7 +d1d2 b8c6 +o-o-o o-o +d4b3 f8e8 +f2f3 a7a6 +c1b1 b7b5 +h2h4 c8e6 +g2g4 c6e5 +! # col. 33h +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f2f4 b8c6 +d4c6 b7c6 +e4e5 d6e5 +d1d8 e8d8 +f4e5 f6g4 +c1f4 c8e6 +c3e4 f8g7 +e4g5 g7e5 +o-o-o d8c7 +g5e6 f7e6 +f4e5 g4e5 +d1e1 c7d6 +g2g3 e5g4 +f1c4 e6e5 +e1e2 +! # col. 34j +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f2f4 b8c6 +f1b5 d8c7 +c3d5 f6d5 +e4d5 a7a6 +b5c6 b7c6 +d4c6 c8b7 +c1e3 f8g7 +e3d4 g7d4 +d1d4 o-o +o-o b7c6 +! # col. 35l +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f2f4 b8d7 +f1e2 f8g7 +c1e3 o-o +e2f3 d7b6 +d1e2 e7e5 +d4b3 f6g4 +f3g4 d8h4 +g2g3 h4g4 +e2g4 c8g4 +! # col. 36a +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f1e2 f8g7 +c1e3 b8c6 +o-o o-o +d4b3 c8e6 +f2f4 c6a5 +f4f5 e6c4 +b3a5 c4e2 +d1e2 d8a5 +g2g4 a8c8 +g4g5 c8c3 +g5f6 c3e3 +e2e3 g7f6 +c2c3 f8c8 +a2a3 c8c4 +a1e1 b7b5 +! # col. 37c; Domnitz-Kraidman, Tel Aviv 1964 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f1e2 f8g7 +c1e3 b8c6 +o-o o-o +d4b3 c8e6 +f2f4 d8c8 +d1e1 f6g4 +e2g4 e6g4 +f4f5 g6f5 +h2h3 g4h3 +g2h3 f5e4 +e1h4 f7f5 +g1h1 f8f7 +f1g1 c6e5 +c3d5 c8d7 +b3d4 e5g6 +g1g6 h7g6 +a1g1 e7e5 +g1g6 d7d8 +e3g5 d8a5 +d5f6 g8f8 +d4e6 +! # col. 38f; Unzicker-Geller, W. Germany-USSR 1960 (drawn) +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f1e2 f8g7 +c1e3 b8c6 +o-o o-o +d1d2 f6g4 +e2g4 c8g4 +f2f4 c6d4 +e3d4 e7e5 +d4e3 e5f4 +f1f4 g4e6 +f4f2 g7e5 +e3d4 a8c8 +a1d1 d8a5 +a2a3 c8c4 +c3e2 a5d2 +d1d2 +! # col. 39 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f1e2 f8g7 +c1e3 b8c6 +o-o o-o +f2f4 d8b6 +d1d3 f6g4 +c3d5 g7d4 +e2g4 d4e3 +d3e3 b6b2 +g4c8 a8c8 +a1b1 b2a2 +b1b7 e7e6 +! # col. 40h +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f1e2 f8g7 +c1e3 b8c6 +o-o o-o +f2f4 d8b6 +e4e5 d6e5 +f4e5 c6e5 +d4f5 b6b2 +f5e7 g8h8 +e3d4 b2b4 +d4e5 b4e7 +d1d4 f6e8 +e5g7 e8g7 +e2d3 c8e6 +! # col. 41b; Smyslov-Botvinnik, match 1958 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f1e2 f8g7 +c1e3 b8c6 +h2h4 h7h5 +f2f3 o-o +d1d2 d6d5 +d4c6 b7c6 +e4e5 f6e8 +f3f4 f7f6 +o-o-o f6e5 +f4e5 g7e5 +g2g4 c8g4 +e2g4 h5g4 +h4h5 g6g5 +! # col. 42d; Van den Burg-Rajkovic, Orebro 1966 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f1e2 f8g7 +c1e3 b8c6 +d4b3 o-o +f2f4 c6a5 +g2g4 b7b6 +g4g5 f6d7 +o-o c8b7 +e2d3 a8c8 +b3a5 b6a5 +d1e1 d7c5 +f4f5 g7e5 +e1h4 e7e6 +f5f6 h7h5 +d3e2 g8h7 +e2h5 f8h8 +! # col. 43f +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f1e2 f8g7 +c1e3 b8c6 +d4b3 o-o +f2f4 c6a5 +g2g4 c8e6 +g4g5 f6d7 +e3d4 f7f6 +h2h4 f6g5 +d4g7 g8g7 +b3d4 e6g8 +f4f5 d8b6 +! # col. 44 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f1e2 f8g7 +o-o b8c6 +d4b3 o-o +f2f4 b7b5 +e2f3 b5b4 +c3d5 f6d5 +e4d5 c6a5 +b3a5 d8a5 +f1e1 f8e8 +! # col. 45i; Smyslov-Korchnoi, Moscow 1960 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 g7g6 +f1e2 f8g7 +d4b3 b8c6 +g2g4 b7b6 +f2f4 c8b7 +e2f3 o-o +h2h4 a7a5 +a2a4 c6b4 +h4h5 d6d5 +e4e5 f6g4 +b3d4 g4h6 +h5g6 f7g6 +d4e6 d8d7 +e6f8 a8f8 +c3b5 d5d4 +! # col. 46 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +f3d4 g8f6 +f2f3 e7e5 +f1b5 c8d7 +b5d7 b8d7 +d4f5 d6d5 +e4d5 d8a5 +b1c3 d7b6 +! # col. 47h; Schweber-Najdorf, Buenos Aires 1970 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +d1d4 b8c6 +f1b5 c8d7 +b5c6 d7c6 +c2c4 g8f6 +b1c3 e7e6 +c1g5 f8e7 +o-o o-o +f1e1 h7h6 +g5h4 a7a6 +a1d1 d8a5 +d4d2 a5b6 +f3d4 a8c8 +e1e3 f8e8 +! # col. 48i +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +d1d4 a7a6 +c1e3 g8f6 +b1c3 b8c6 +d4b6 d8b6 +e3b6 g7g6 +o-o-o f8h6 +c1b1 o-o +f3d4 c8d7 +f2f3 c6e5 +d4b3 f8c8 +b3a5 d7c6 +c3d5 c6d5 +e4d5 f6d7 +b6d4 b7b6 +! # col. 49m; Fischer-Korchnoi, Buenos-Aires 1960 +e2e4 c7c5 +g1f3 d7d6 +d2d4 c5d4 +c2c3 d4c3 +b1c3 b8c6 +f1c4 e7e6 +o-o a7a6 +d1e2 g8f6 +f1d1 d8c7 +c1g5 f8e7 +a1c1 o-o +c4b3 h7h6 +g5f4 e6e5 +f4e3 c7d8 +c3d5 f6d5 +b3d5 c8d7 +! # col. 50 +e2e4 c7c5 +g1f3 d7d6 +d2d4 g8f6 +d4c5 f6e4 +c5d6 e7e6 +d1d3 e4d6 +b1c3 b8c6 +c1f4 f7f6 +o-o-o e6e5 +c3b5 +! # col. 51c; Pfeiffer-Kottnauer, Helsinki 1952 +e2e4 c7c5 +g1f3 d7d6 +c2c3 g8f6 +f1d3 b8c6 +d3c2 c8g4 +h2h3 g4h5 +d2d3 d6d5 +d1e2 e7e6 +b1d2 f8e7 +d2f1 d8a5 +! # col. 52d; Brasket-Evans, U.S. Open Chp. 1960 +e2e4 c7c5 +g1f3 d7d6 +c2c3 g8f6 +d2d3 g7g6 +g2g3 f8g7 +b1d2 o-o +f1g2 e7e5 +o-o b8c6 +a2a4 h7h6 +d2b1 d8a5 +! # col. 53h; Ciocaltea-Fischer, Varna 1962 +e2e4 c7c5 +g1f3 d7d6 +g2g3 g7g6 +f1g2 f8g7 +o-o b8c6 +c2c3 e7e5 +d2d3 g8e7 +f3h4 o-o +f2f4 e5f4 +g3f4 f7f5 +b1d2 g8h8 +d2f3 +! # col. 54k; Tarjan-Mednis, U.S. Chp. 1973 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 e7e6 +f1e2 g7g6 +d4b3 +! e2e4 c7c5 +g1f3 d7d6 +b1c3 g8f6 +e4e5 d6e5 +f3e5 a7a6 +f1e2 e7e6 +o-o d8c7 +e5c4 b7b5 +c4e3 f8d6 +h2h3 b8c6 +a2a4 b5b4 +c3b1 c8b7 +d2d3 c6d4 +b1d2 o-o +d2f3 d4e2 +d1e2 f8e8 +e3c4 e6e5 +f3g5 e5e4 +c4d6 c7d6 +g5e4 f6e4 +d3e4 b7e4 +c1e3 d6c6 +! # col. 55o; Medina-Pomar, Santander 1947 +e2e4 c7c5 +g1f3 d7d6 +b2b4 c5b4 +d2d4 g8f6 +f1d3 d6d5 +b1d2 d5e4 +d2e4 b8d7 +e4g5 d8c7 +c2c4 h7h6 +g5h3 g7g5 +h3g1 f8g7 +g1e2 e7e5 +e2g3 e5e4 +d1e2 o-o +! # col. 56e; del Corral-Benko, Mallorca 1968 +e2e4 c7c5 +g1f3 d7d6 +f1b5 c8d7 +b5d7 d8d7 +o-o b8c6 +f1e1 g8f6 +c2c3 e7e6 +d2d3 f8e7 +a2a4 o-o +b1d2 d7c7 +! # col. 57g; Radovich-Lombardy, Leipzig 1960 +e2e4 c7c5 +g1f3 d7d6 +f1b5 b8c6 +o-o a7a6 +b5c6 b7c6 +d2d4 c5d4 +d1d4 e7e5 +d4d3 f7f6 +c2c4 c8e6 +b1c3 d8c7 +! # col. 58j; Gurgenidze-Osnos, Alma Ata 1969 +e2e4 c7c5 +g1f3 b8c6 +f1b5 e7e6 +b1c3 g8e7 +o-o a7a6 +b5c6 e7c6 +d2d4 c5d4 +f3d4 d7d6 +d4c6 b7c6 +d1g4 g7g6 +e4e5 d6d5 +c1g5 f8e7 +! # col. 59m +e2e4 c7c5 +g1f3 b8c6 +f1b5 g7g6 +o-o f8g7 +c2c3 g8f6 +f1e1 o-o +d2d4 c5d4 +c3d4 d7d5 +e4e5 f6e4 +b1c3 e4c3 +b2c3 c6a5 +c1g5 c8f5 +f3d2 f8e8 +! # col. 60o +e2e4 c7c5 +g1f3 b8c6 +f1b5 g7g6 +o-o f8g7 +f1e1 e7e5 +f1e1 o-o +d2d4 c5d4 +c3d4 d7d5 +e4e5 f6e4 +b1c3 e4c3 +b2c3 c6a5 +c1g5 c8f5 +f3d2 f8e8 +! # col. 61c; Barczay-Szilagyi, Hungarian Chp. 1969 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +g5f6 g7f6 +d4b3 h8g8 +g2g3 f6f5 +d1d2 f8g7 +e4f5 d7f5 +f1g2 d8d7 +o-o g7c3 +b2c3 f5h3 +g2h3 d7h3 +! # col. 62e +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +d4b3 h7h6 +g5h4 a8c8 +f1e2 g7g5 +h4g3 h6h5 +h2h4 g5g4 +g3f4 c6e5 +d1d4 e5g6 +f4g5 f8g7 +o-o +! # col. 63g; Matulovic-Masic, Sombor 1968 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +f2f4 d8b6 +d4b3 f6g4 +d1e2 c6d4 +c3d5 d4e2 +d5b6 a7b6 +e1e2 h7h6 +g5h4 g7g5 +h4g3 g5f4 +g3f4 f8g7 +c2c3 d7c6 +! # col. 64j; Liberzo-Stein, USSR Chp. 1969-70. Complete game (draw). +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +d1d3 c6d4 +d3d4 d8a5 +f2f4 e7e5 +d4d3 f8e7 +o-o-o d7c6 +c1b1 e5f4 +g5f4 o-o +f1e2 f8e8 +e2f3 e7f8 +c3d5 f6d7 +d3d2 a5d2 +d1d2 a8c8 +h1d1 d7e5 +b2b3 +! # col. 65m; Bronstein-Stein, USSR 1969 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +d1d3 c6d4 +d3d4 d8a5 +f1e2 e7e5 +d4d3 a5c7 +e2g4 f8e7 +g5f6 e7f6 +o-o-o f6e7 +c3b5 d7b5 +d3b5 c7c6 +b5d5 c6d5 +d1d5 +! # col. 66b; Benko-R. Byrne, US Open Chp. 1968 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +d1d2 a8c8 +o-o-o c6d4 +d2d4 d8a5 +g5d2 a7a6 +f1c4 a5c5 +d4c5 c8c5 +c4b3 g7g6 +d2e3 c5c8 +e3d4 f8g7 +c3d5 f6h5 +d4g7 h5g7 +e4e5 c8c6 +d5b4 c6b6 +! # col. 66b alternate; Polgar-Nagy, Hungarian Chp. 1972 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +d1d2 a8c8 +o-o-o c6d4 +d2d4 d8a5 +g5d2 e7e5 +d4d3 a7a6 +c1b1 h7h6 +f2f3 a5c7 +g2g3 f8e7 +h2h4 b7b5 +! # col. 67c; Suetin-Gheorghiu, Hastings 1967/8. Draw. +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +d1d2 a8c8 +o-o-o c6d4 +d2d4 d8a5 +g5e3 a7a6 +f2f3 e7e6 +d4b6 a5b6 +e3b6 d7c6 +f1c4 c6e4 +c4e6 f7e6 +c3e4 f6e4 +f3e4 f8e7 +h1f1 e7g5 +c1b1 e8e7 +c2c3 h8f8 +b1c2 f8f1 +d1f1 c8f8 +! # col. 68d +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +d1d2 a8c8 +o-o-o c6d4 +d2d4 d8a5 +f2f4 e7e6 +e4e5 d6e5 +f4e5 c8c3 +g5d2 a5a2 +d2c3 g7g6 +! # col. 69fA1; Janosevic-Larsen, Belgrade 1964 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +d1d2 a8c8 +o-o-o c6d4 +d2d4 d8a5 +f2f4 c8c3 +b2c3 e7e5 +d4b4 a5b4 +c3b4 f6e4 +f1c4 b7b5 +c4d5 e4c3 +f4e5 h7h6 +g5h4 g7g5 +h4g3 c3e2 +c1b2 e2g3 +h2g3 f8g7 +! # col. 70g; Bednarski-Simagin, Polanica Zdroj 1968 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 c8d7 +d1d2 a8c8 +o-o-o c6d4 +d2d4 c8c3 +d4c3 f6e4 +c3e3 e4g5 +e3g5 d8b6 +f1c4 e7e6 +g5g3 g7g6 +c4b3 f8e7 +h2h4 h7h5 +h1e1 b6b4 +g3e3 a7a5 +e3d4 +! # col. 71d +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d2 f8e7 +o-o-o c6d4 +d2d4 o-o +f2f4 h7h6 +g5h4 d8a5 +f1c4 e6e5 +f4e5 d6e5 +d4d3 a5c5 +h4f6 e7f6 +! # col. 72g +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d2 f8e7 +o-o-o c6d4 +d2d4 o-o +f2f4 d8a5 +f1c4 c8d7 +c4b3 d7c6 +h1f1 b7b5 +g5f6 e7f6 +d4d6 f6c3 +d6c6 a8c8 +c6d7 c8d8 +d7e7 c3d2 +c1b1 d2f4 +d1d8 a5d8 +! # col. 73i +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d2 f8e7 +o-o-o o-o +d4b3 d8b6 +f2f3 a7a6 +g2g4 f8d8 +g5e3 b6c7 +h2h4 b7b5 +g4g5 f6d7 +g5g6 f7g6 +h4h5 g6h5 +h1h5 d7f6 +h5g5 c6e5 +d2g2 e7f8 +f3f4 e5c4 +f1c4 b5c4 +b3d4 a8b8 +d1g1 b8b7 +! # col. 74; Tal-Larsen, match 1969 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d2 f8e7 +o-o-o o-o +d4b3 a7a6 +g5f6 g7f6 +f1e2 g8h8 +e2h5 c8d7 +f2f4 b7b5 +c1b1 +! # col. 75k +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d2 f8e7 +o-o-o o-o +d4b5 d8a5 +g5f6 e7f6 +b5d6 f8d8 +f2f4 e6e5 +d2d5 a5c7 +f4f5 c6d4 +d6b5 c7a5 +d5c4 c8f5 +b2b4 a5a6 +! # col. 76b; Spasski-Larsen, Santa Monica 1966 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d2 f8e7 +o-o-o o-o +f2f4 h7h6 +g5h4 e6e5 +d4f5 c8f5 +e4f5 d8a5 +c1b1 a8d8 +h4f6 e7f6 +c3d5 a5d2 +d5f6 g7f6 +d1d2 e5f4 +! # col. 77e; Kujpers-Minev, Halle 1967 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d2 f8e7 +o-o-o o-o +f2f4 d6d5 +e4e5 f6d7 +h2h4 d7b6 +d2e3 c8d7 +g5e7 d8e7 +h4h5 c6a5 +d4b3 a5c4 +e3d4 f8c8 +c1b1 a7a5 +f4f5 a5a4 +f5f6 e7f8 +h1h3 c4b2 +b1b2 b6c4 +f1c4 c8c4 +d4d2 +! # col. 78h +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d2 a7a6 +o-o-o c8d7 +f2f4 h7h6 +g5h4 f6e4 +d2e1 e4f6 +d4f5 d8a5 +f5d6 f8d6 +d1d6 o-o-o +d6d1 e6e5 +f1c4 e5f4 +c3e4 d7e6 +c4e6 f7e6 +e4d6 c8b8 +e1e6 h8f8 +! # col. 79j; O'Kelly-Simagin corr. 1964 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d2 a7a6 +o-o-o h7h6 +g5h4 f6e4 +d2f4 e4g5 +d4c6 b7c6 +f4a4 d8b6 +f2f4 g5h7 +f4f5 f8e7 +c3e4 a8b8 +a4a3 b6b5 +! # col. 80k; Di Camillo-R. Byrne, US Open Chp. 1958 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d2 h7h6 +g5f6 g7f6 +o-o-o a7a6 +f2f4 c8d7 +f1e2 h6h5 +c1b1 d8b6 +d4b3 o-o-o +h1f1 f8e7 +c3a4 b6a7 +c2c4 c6d4 +! # col. 81b +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d4c6 b7c6 +e4e5 d6e5 +d1f3 f8e7 +f3c6 c8d7 +c6f3 e5e4 +c3e4 f6e4 +g5e7 d8a5 +! # col. 82e +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1g5 e7e6 +d1d3 f8e7 +a1d1 o-o +f1e2 c8d7 +o-o c6d4 +d3d4 d7c6 +g1h1 d8a5 +f2f4 f8e8 +! # col. 83 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +h2h3 g7g6 +c1e3 f8g7 +d1d2 o-o +o-o-o c6d4 +e3d4 d8a5 +c1b1 e7e5 +d4e3 c8e6 +! # BAD! -- col. 84i; Karaklajic-Taimanov, Yugoslavia-USSR, match 1956 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +c1e3 f6g4 +f1b5 g4e3 +f2e3 c8d7 +o-o e7e6 +5c6 b7c6 +e4e5 f8e7 +d1h5 o-o +e5d6 e7d6 +c3e4 d6e7 +a1d1 d8c7 +d4b3 h7h6 +! # col. 85 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +d4e2 e7e6 +g2g3 d6d5 +e4d5 f6d5 +f1g2 d5c3 +d1d8 e8d8 +e2c3 c8d7 +c1d2 f8e7 +! # col. 86c; Carcia-Pomar, Havana 1969 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +f1c4 e7e5 +d4e2 c8e6 +c4e6 f7e6 +o-o f8e7 +f2f4 o-o +e2g3 e5f4 +f1f4 d8b6 +g1h1 a8d8 +b2b3 d6d5 +e4d5 f6d5 +f4f8 e7f8 +c3d5 d8d5 +d1e1 c6d4 +c1e3 f8c5 +! # col. 87 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +f1c4 d8b6 +d4b3 e7e6 +o-o f8e7 +c1e3 b6c7 +f2f4 o-o +c4d3 a7a6 +d1f3 +! # col. 88 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +f1c4 e7e6 +c1e3 d8c7 +d1e2 a7a6 +c4b3 c6a5 +g2g4 b7b5 +g4g5 f6d7 +o-o-o d7c5 +! # col. 89mA; Spasjevic-Ostojic, Belgrade 1966 (draw) +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +f1c4 e7e6 +c1e3 f8e7 +d1e2 a7a6 +o-o-o o-o +c4b3 d8c7 +g2g4 c6d4 +d1d4 e6e5 +d4c4 c7d8 +g4g5 f6e8 +h1g1 c8d7 +c3d5 d7b5 +e3b6 d8d7 +e2g4 e7d8 +g4d7 b5d7 +c4c3 d7e6 +b6d8 a8d8 +d5e3 d8d7 +b3a4 d7c7 +! # col. 90o; Bogdanovic-Shamkovich, Sarajevo 1963 +e2e4 c7c5 +g1f3 b8c6 +d2d4 c5d4 +f3d4 g8f6 +b1c3 d7d6 +f1c4 e7e6 +c1e3 f8e7 +d1e2 o-o +o-o-o c6d4 +e3d4 d8a5 +e4e5 d6e5 +d4e5 b7b6 +c3b5 c8a6 +e5c3 a5a4 +d1d4 a6b5 +c4b5 a4a2 +h1d1 f8d8 +d4a4 d8d1 +e2d1 a2d5 +d1d5 f6d5 +c3d4 e7g5 +c1b1 h7h5 +b5c6 a8d8 +a4a7 d5b4 +c6d7 b4c6 +! # Queen's Catalan, col. 1c; Kramer-Fichtl, Varna Olympics 1962 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 f8e7 +f1g2 o-o +o-o b8d7 +b1c3 c7c6 +b2b3 b7b6 +c1b2 c8b7 +d1c2 a8c8 +a1d1 d8c7 +e2e4 d5e4 +c3e4 f6e4 +c2e4 c6c5 +d4d5 e7f6 +e4c2 e6d5 +c4d5 f6b2 +c2b2 c8d8 +! # col. 2f +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 f8e7 +f1g2 o-o +o-o b8d7 +b1c3 d5c4 +e2e4 c7c6 +a2a4 a7a5 +d1e2 d7b6 +f1d1 e7b4 +f3e5 d8e7 +c1e3 c8d7 +e5c4 b6c4 +e2c4 e6e5 +d4e5 f6g4 +! # col. 3i; Geller-Medina, Beverwijk 1965 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 f8e7 +f1g2 o-o +o-o b8d7 +d1c2 b7b6 +c4d5 f6d5 +b1c3 c8b7 +c3d5 b7d5 +e2e4 d5b7 +f1d1 c7c5 +d4d5 e6d5 +e4d5 e7f6 +h2h4 h7h6 +! # col. 4k; Geller-Bisguier, Bled 1961 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 f8e7 +f1g2 o-o +o-o b8d7 +d1c2 c7c6 +b2b3 b7b6 +c1b2 c8b7 +b1c3 a8c8 +a1d1 b6b5 +c4c5 b5b4 +c3b1 f6e4 +f3e1 f7f5 +e1d3 a7a5 +d3f4 f8f6 +f2f3 e4g5 +! # col. 5m; Benko-Pachman, Budapest 1948 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 f8e7 +f1g2 o-o +o-o b8d7 +d1c2 c7c6 +b1d2 b7b6 +e2e4 c8b7 +b2b3 a8c8 +f1d1 d8c7 +c1b2 f8d8 +a1c1 c7b8 +c2b1 a7a5 +f3e5 b8a8 +! # col. 6 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 f8e7 +f1g2 o-o +o-o c7c6 +b1c3 b7b6 +f3e5 a7a5 +d1c2 c8a6 +f1d1 b6b5 +! # col. 7d; Evans-Poschel, US Jr. Chp. 1947 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 c7c5 +c4d5 f6d5 +f1g2 c5d4 +o-o f8c5 +f3d4 o-o +a2a3 b8c6 +d4c6 b7c6 +b2b4 c5e7 +c1b2 e7f6 +d1c2 f6b2 +c2b2 a7a5 +! # col. 8g; O'Kelly-Euwe, New York 1951 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 d5c4 +f1g2 c7c5 +o-o b8c6 +d1a4 f6d7 +d4c5 f8c5 +a4c4 o-o +b1c3 a7a6 +c3e4 c5e7 +c1e3 d7b6 +c4b3 b6d5 +f1d1 d8c7 +! # col. 9 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 d5c4 +f1g2 b7b5 +a2a4 c7c6 +o-o c8b7 +f3e5 d8c8 +b2b3 c4b3 +d1b3 b5b4 +a4a5 f6d7 +! # col. 10l; Keres-Korchnoi, Curacao 1962 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +g1f3 d5c4 +d1a4 b8d7 +f1g2 a7a6 +a4c4 c7c5 +d4c5 f8c5 +o-o b7b5 +c4h4 c8b7 +b1d2 c5e7 +d2b3 a8c8 +h4d4 o-o +c1d2 d7c5 +! # col. -- Accelerated Catalan +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +f1g2 d5c4 +d1a4 b8d7 +b1d2 c7c6 +a4c4 e6e5 +g1f3 d7b6 +c4d3 e5d4 +f3d4 f8e7 +o-o o-o +! # col. 12e; Muller-Ratzek, Vienna 1951 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +f1g2 d5c4 +d1a4 c8d7 +a4c4 d7c6 +g1f3 c6d5 +c4d3 c7c5 +b1c3 d5c6 +o-o b8d7 +f1d1 d8b6 +e2e4 c5d4 +f3d4 f8c5 +d4c6 c5f2 +g1f1 b7c6 +c3a4 b6a5 +f1f2 a5a4 +d3d6 +! # col. 13f; Smyslov-Kere, USSR Chp. 1948 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +f1g2 d5c4 +d1a4 c8d7 +a4c4 d7c6 +g1f3 b8d7 +b1c3 d7b6 +c4d3 f8b4 +o-o o-o +f1d1 h7h6 +c1d2 d8e7 +a2a3 b4c3 +d3c3 f8d8 +! # col. 14g +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +b1c3 d5c4 +d1a4 b8c6 +f1g2 c8d7 +a4c4 c6b4 +c4b3 c7c5 +g1f3 c5d4 +f3d4 e6e5 +d4f3 d7e6 +b3a4 e6d7 +! # col. 15; Stoltz-Vidmar, Groningen 1946 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +b1c3 f8e7 +f1g2 o-o +g1f3 d5c4 +d1a4 a7a6 +a4c4 b7b5 +c4d3 c8b7 +! # col. 16 +d2d4 d7d5 +c2c4 e7e6 +g2g3 g8f6 +b1d2 c7c5 +d4c5 f8c5 +f1g2 b8c6 +g1f3 o-o +o-o a7a5 +c4d5 e6d5 +d2b3 c5b6 +! # col. 17d; Mikenas-Aronin, USSR Chp. 1963 +d2d4 d7d5 +c2c4 e7e6 +g2g3 c7c5 +c4d5 e6d5 +g1f3 b8c6 +f1g2 g8f6 +o-o f8e7 +d4c5 e7c5 +b1d2 o-o +d2b3 c5b6 +b3d4 f8e8 +b2b3 c6d4 +f3d4 b6d4 +d1d4 e8e2 +! # col. 18e +d2d4 d7d5 +c2c4 e7e6 +g2g3 d5c4 +d1a4 c8d7 +a4c4 c7c5 +d4c5 d7c6 +g1f3 b8d7 +c1e3 g8f6 +f1g2 d8c7 +o-o c6d5 +c4a4 f8c5 +e3c5 c7c5 +b1c3 d5c6 +! # col. 19 +d2d4 d7d5 +c2c4 e7e6 +g2g3 f8b4 +c1d2 b4d2 +d1d2 g8f6 +g1f3 o-o +f1g2 d8e7 +o-o b8c6 +f1c1 +! # col. 20 +d2d4 d7d5 +c2c4 e7e6 +g2g3 f8b4 +c1d2 b4e7 +f1g2 g8f6 +g1f3 o-o +d1b3 b7b6 +c4d5 e6d5 +b1c3 c8b7 +o-o +! # col. 21 +d2d4 g8f6 +c2c4 e7e6 +g2g3 e6e5 +g1f3 e5d4 +f3d4 d7d5 +f1g2 d5c4 +d1a4 c7c6 +a4c4 f8e7 +o-o o-o +f1d1 +! # col. 22 +d2d4 g8f6 +c2c4 e7e6 +g2g3 c7c5 +g1f3 c5d4 +f3d4 d7d5 +f1g2 e6e5 +d4f3 d5d4 +o-o b8c6 +e2e3 f8e7 +e3d4 e5d4 +! # col. 23g +d2d4 g8f6 +c2c4 e7e6 +g2g3 c7c5 +g1f3 c5d4 +f3d4 b8c6 +f1g2 d8b6 +d4c2 f8c5 +e2e3 o-o +b1c3 b6a6 +d1d2 f8d8 +a2a3 d7d5 +b2b4 d5d4 +c3e4 +! # col. 24j; Smyslov-Petrosian, Moscow 1967 +d2d4 g8f6 +c2c4 e7e6 +g2g3 f8b4 +b1d2 c7c5 +d4c5 b4c5 +f1g2 b8c6 +g1f3 b7b6 +o-o c8b7 +a2a3 o-o +b2b4 c5e7 +c1b2 a8c8 +d1b1 +! # col. 25 +d2d4 g8f6 +c2c4 e7e6 +g2g3 f8b4 +c1d2 b4d2 +d1d2 f6e4 +d2c2 f7f5 +f2f3 e4f6 +e2e4 f5e4 +f3e4 e6e5 +! # Alternate openings leading to the Catalan, line C +g1f3 d7d5 +c2c4 e7e6 +g2g3 g8f6 +d2d4 +! # line D +c2c4 g8f6 +d2d4 e7e6 +g2g3 d7d5 +! # line E +d2d4 g8f6 +c2c4 e7e6 +g2g3 d7d5 +! # The Reti Opening, col. 1c; Muller-Lilenthal, Budapest 1933 +g1f3 d7d5 +c2c4 c7c6 +b2b3 g8f6 +g2g3 c8f5 +c1b2 e7e6 +f1g2 b8d7 +o-o f8d6 +d2d3 o-o +b1c3 d8e7 +f1e1 e6e5 +c4d5 c6d5 +e2e4 d5e4 +d3e4 f5g6 +! # col. 2g; Bilek-Geller, Sousse 1967 +g1f3 d7d5 +c2c4 c7c6 +b2b3 g8f6 +g2g3 c8g4 +f1g2 e7e6 +c1b2 b8d7 +o-o f8e7 +d2d3 o-o +b1d2 a7a5 +a2a3 d8b6 +d1c2 h7h6 +b2c3 f8c8 +f1e1 b6d8 +e2e4 d8f8 +! # col. 3k; Botvinnik-Fine, Nottingham 1936 +g1f3 d7d5 +c2c4 d5c4 +b1a3 c7c5 +a3c4 b8c6 +g2g3 e7e5 +f1g2 f7f6 +b2b3 g8e7 +c1b2 e7d5 +o-o f8e7 +f3h4 o-o +d1b1 f8f7 +h4f5 c8e6 +f2f4 e5f4 +g3f4 d5b6 +g2e4 e6c4 +! # col. 4n; Katetov-Alekhin, Prague 1943 +g1f3 d7d5 +c2c4 d5d4 +e2e3 b8c6 +e3d4 c6d4 +f3d4 d8d4 +b1c3 e7e5 +d2d3 f8c5 +c1e3 d4d6 +c3b5 d6e7 +e3c5 e7c5 +d3d4 e5d4 +d1d4 c5d4 +b5d4 c8g4 +! # col. 5o +g1f3 d7d5 +c2c4 d5d4 +e2e3 c7c5 +e3d4 c5d4 +g2g3 b8c6 +f1g2 g7g6 +d2d3 f8g7 +o-o e7e5 +f1e1 f7f6 +b2b4 c6b4 +d1a4 b4c6 +f3d4 d8d4 +g2c6 c8d7 +! # col. 6 +g1f3 d7d5 +c2c4 e7e6 +g2g3 g8f6 +f1g2 f8e7 +o-o o-o +b2b3 c7c5 +c4d5 f6d5 +c1b2 b8c6 +d2d4 d5b4 +a2a3 b4a6 +d4c5 d8d1 +! # col. 7 +g1f3 d7d5 +c2c4 e7e6 +g2g3 g8f6 +f1g2 f8e7 +b1c3 o-o +b2b3 c7c5 +c1b2 b8c6 +c4d5 e6d5 +a1c1 c8e6 +o-o a8c8 +d2d4 f8e8 +! # col. 8g; Kashdan-Horowitz, New York 1931 +g1f3 d7d5 +c2c4 e7e6 +g2g3 g8f6 +f1g2 b8d7 +b2b3 c7c6 +o-o f8d6 +c1b2 o-o +b1c3 b7b6 +d2d3 c8b7 +e2e4 d5e4 +d3e4 d8c7 +d1e2 f8d8 +f1d1 +! # col. 9h; Abroshin-Krykov corr. 1960 +g1f3 d7d5 +c2c4 e7e6 +g2g3 g8f6 +f1g2 d5c4 +d1a4 c8d7 +a4c4 d7c6 +o-o c6d5 +c4a4 d8d7 +a4c2 b8c6 +b1c3 d5f3 +g2f3 c6d4 +c2d3 c7c6 +! # col. 10m; Teti-Tartakover, Semmering 1926 +g1f3 d7d5 +c2c4 e7e6 +g2g3 d5c4 +d1a4 c8d7 +a4c4 c7c5 +f3e5 b8c6 +e5d7 d8d7 +f1g2 g8f6 +d2d3 f8e7 +o-o c6d4 +b1c3 a8d8 +a2a4 f6d5 +! # Barcza System, col. 11 +g1f3 d7d5 +g2g3 g8f6 +f1g2 c8f5 +o-o c7c6 +c2c4 d5c4 +b1a3 e7e5 +a3c4 e5e4 +f3e1 f8c5 +d2d3 o-o +c1e3 b8d7 +! # col. 12d; Benko-Petrosian, Curacao 1962 +g1f3 d7d5 +g2g3 g8f6 +f1g2 c8f5 +o-o c7c6 +d2d3 b8d7 +b1d2 h7h6 +d1e1 e7e6 +e2e4 f5h7 +e1e2 f8e7 +e4e5 f6g8 +d2b3 e7f8 +c2c4 g8e7 +b3d4 e7f5 +d4f5 h7f5 +c4d5 c6d5 +d3d4 a7a5 +c1e3 f8e7 +f1c1 o-o +! # col. 13f; Bronstein-O'Kelly, Beverwijk 1963 +g1f3 d7d5 +g2g3 g8f6 +f1g2 c7c5 +o-o e7e6 +d2d3 b8c6 +b1d2 f8e7 +e2e4 o-o +f1e1 d8c7 +e4e5 f6d7 +d1e2 b7b5 +h2h4 a7a5 +d2f1 c8a6 +f1h2 c6b4 +h4h5 +! # col. 14i; Evans-Olafsson, Dallas 1957 +g1f3 d7d5 +g2g3 g8f6 +f1g2 g7g6 +o-o f8g7 +d2d3 o-o +b1d2 b8c6 +e2e4 e7e5 +c2c3 a7a5 +f1e1 d5e4 +d3e4 f6d7 +d1e2 b7b6 +d2c4 c8a6 +g2f1 d8f6 +! # col. 15 +g1f3 d7d5 +g2g3 g8f6 +f1g2 g7g6 +d2d4 f8g7 +o-o c7c6 +b2b3 b8d7 +c1b2 e7e5 +d4e5 f6g4 +b1d2 d7e5 +f3e5 g4e5 +! # col. 16d; Larsen-Mecking, Mallorca 1969 +g1f3 d7d5 +g2g3 c7c5 +f1g2 b8c6 +o-o e7e6 +d2d3 g7g6 +b1c3 f8g7 +a2a3 g8e7 +a1b1 o-o +c1d2 a8b8 +b2b4 c5b4 +a3b4 b7b5 +e2e4 a7a5 +! # col. 17h; Benko-Bisguier, US Chp. 1963 +g1f3 d7d5 +g2g3 c8g4 +f1g2 b8d7 +c2c4 c7c6 +c4d5 c6d5 +b1c3 e7e6 +d1b3 d8b6 +b3b6 d7b6 +d2d3 a8c8 +c1e3 f8d6 +c3b5 d6b8 +o-o g8e7 +f1c1 c8c1 +a1c1 e7c6 +f3d4 e8d7 +! # col. 18j; Keene-Basman, Hastings 1966-7 +g1f3 d7d5 +g2g3 c8g4 +f1g2 g8f6 +c2c4 c7c6 +c4d5 g4f3 +g2f3 c6d5 +d1b3 d8d7 +b1c3 e7e6 +o-o b8c6 +f3g2 f8e7 +d2d3 o-o +! # col. 19k +g1f3 d7d5 +g2g3 c8g4 +f1g2 g8f6 +c2c4 c7c6 +d1c2 e7e6 +o-o f8e7 +b2b3 b8d7 +c1b2 o-o +d2d3 a7a5 +b1d2 a5a4 +b2c3 a4b3 +a2b3 d8b6 +! # col. 20m +g1f3 d7d5 +g2g3 c8g4 +f1g2 g8f6 +o-o c7c6 +c2c4 e7e6 +c4d5 g4f3 +g2f3 c6d5 +b1c3 b8c6 +d2d3 f8e7 +f3g2 +! # col. 21b; Savon-Aronin, USSR 1963 +g1f3 d7d5 +g2g3 b8c6 +d2d4 c8f5 +f1g2 c6b4 +b1a3 e7e6 +o-o g8f6 +f3h4 f5g4 +c2c4 c7c6 +a3c2 b4c2 +d1c2 f8e7 +h2h3 g4h5 +f2f3 h5g6 +h4g6 h7g6 +! # col. 22d; Fischer-Ivkov, Santa Monica 1966 +g1f3 d7d5 +g2g3 e7e6 +f1g2 c7c5 +o-o b8c6 +d2d3 f8d6 +e2e4 g8e7 +b1d2 o-o +f3h4 b7b6 +f2f4 d5e4 +d3e4 c8a6 +f1e1 c5c4 +c2c3 +! # col. 23 +g1f3 d7d5 +g2g3 b8d7 +c2c4 e7e6 +f1g2 g8f6 +b1c3 f8e7 +o-o o-o +d2d3 c7c5 +c4d5 e6d5 +c1g5 b7b6 +! # col. 24g; Benko-Bisguier, US Chp. 1976-7 +g1f3 d7d5 +g2g3 g8f6 +f1g2 b7b6 +c2c4 e7e6 +c4d5 e6d5 +o-o f8d6 +d2d4 o-o +b1c3 c7c6 +f3e5 c8b7 +c1g5 h7h6 +g5f6 d8f6 +f2f4 f8d8 +e2e4 +! # col. 25; Rabinovich-Rauser, Moscow 1934 +g1f3 d7d5 +b2b3 c8g4 +c1b2 b8d7 +c2c4 e7e6 +e2e3 g8f6 +f1e2 c7c6 +f3d4 g4e2 +d1e2 f8d6 +f2f4 o-o +! # col. 26e; Evans-Najdorf, Dallas 1967 +g1f3 c7c5 +g2g3 b8c6 +f1g2 g7g6 +o-o f8g7 +e2e4 d7d6 +c2c3 e7e5 +d2d3 g8h6 +f3e1 o-o +f2f4 e5f4 +c1f4 h6g4 +b1a3 g4e5 +g1h1 d8b6 +d1d2 c8e6 +! # col. 27h; Van den Pol-Barden, Holland v. England 1960 +g1f3 f7f5 +g2g3 g8f6 +f1g2 g7g6 +d2d3 f8g7 +b1d2 d7d6 +e2e4 e7e5 +d2c4 o-o +e4f5 g6f5 +c1e3 b8c6 +d3d4 e5e4 +! # col. 28m; Gufeld-Bokuchava, USSR Chp. prelims 1968 +g1f3 f7f5 +g2g3 g8f6 +f1g2 e7e6 +c2c4 f8e7 +o-o o-o +d2d3 d7d6 +b1c3 b8c6 +a1b1 a7a5 +a2a3 d8e8 +b2b4 a5b4 +a3b4 e6e5 +! # col. 29p; Lundin-Tartakover, Groningen 1946 +g1f3 f7f5 +g2g3 g8f6 +f1g2 e7e6 +c2c4 f8e7 +o-o o-o +b2b3 c7c5 +c1b2 b8c6 +b1c3 e6e5 +e2e3 d7d6 +d2d4 +! # col. 30 +g1f3 g7g6 +g2g3 f8g7 +f1g2 e7e5 +d2d3 b8c6 +e2e4 d7d6 +b1c3 g8e7 +c1e3 o-o +d1d2 c6d4 +o-o +! # King's Indian attack, col. 31a +g1f3 g8f6 +g2g3 b7b5 +h2h4 b5b4 +d2d3 c8b7 +e2e4 d7d6 +f1g2 b8d7 +o-o e7e6 +h4h5 a8b8 +b1d2 f8e7 +d2c4 o-o +! # col. 32d +g1f3 g8f6 +g2g3 g7g6 +b2b4 f8g7 +c1b2 o-o +f1g2 d7d5 +o-o c8g4 +c2c4 c7c6 +b1a3 b8d7 +a1c1 a7a5 +b4b5 a5a4 +d2d3 e7e5 +! # col. 33e; Olafsson-Kavalek, Wijik aan Zee 1969 +g1f3 g8f6 +g2g3 g7g6 +b2b3 f8g7 +c1b2 o-o +f1g2 d7d6 +d2d4 f6d7 +b1c3 e7e5 +d1d2 f8e8 +d4e5 d7e5 +f3e5 g7e5 +! # col. 34h +g1f3 g8f6 +g2g3 g7g6 +c2c4 d7d6 +f1g2 f8g7 +o-o o-o +b1c3 b8d7 +d2d3 e7e5 +c1d2 d7c5 +b2b4 c5e6 +a1b1 f6e8 +a2a4 c7c6 +a4a5 e8c7 +! # col. 35 +g1f3 g8f6 +c2c4 g7g6 +b2b3 f8g7 +c1b2 o-o +e2e3 d7d6 +f1e2 e7e5 +o-o f8e8 +b1c3 b8d7 +d2d3 c7c6 +! # col. 36d +g1f3 g8f6 +c2c4 g7g6 +b1c3 d7d5 +c4d5 f6d5 +d1a4 c8d7 +a4b3 d5b6 +d2d4 f8g7 +c1f4 d7e6 +b3c2 b8c6 +a1d1 +! # col. 37f +g1f3 g8f6 +c2c4 b7b6 +g2g3 c8b7 +f1g2 c7c5 +o-o g7g6 +b2b3 f8g7 +c1b2 o-o +b1c3 d7d5 +c3d5 f6d5 +b2g7 g8g7 +c4d5 d8d5 +d2d4 b8a6 +! # col. 38h; Geller-Kholmov, Moscow 1969 +g1f3 g8f6 +c2c4 b7b6 +g2g3 c8b7 +f1g2 e7e6 +o-o f8e7 +b2b3 o-o +c1b2 d7d5 +e2e3 b8d7 +b1c3 f6e4 +c4d5 e4c3 +b2c3 e6d5 +! # col. 39 +g1f3 g8f6 +b2b3 g7g6 +c2c4 f8g7 +c1b2 o-o +g2g3 c7c5 +f1g2 b7b6 +o-o c8b7 +b1c3 e7e6 +a1b1 d8e7 +! # col. 40o; Lombardy-Burger, US Chp. 1969-70 +g1f3 g8f6 +b2b3 d7d5 +c1b2 e7e6 +e2e3 f8e7 +c2c4 o-o +d2d4 b7b6 +f1d3 c8b7 +o-o b8d7 +b1d2 c7c5 +d1e2 f6e4 +a1c1 a8c8 +! diff --git a/gnu/games/chess/gnuchess.c b/gnu/games/chess/gnuchess.c new file mode 100644 index 00000000000..4a363e21176 --- /dev/null +++ b/gnu/games/chess/gnuchess.c @@ -0,0 +1,2310 @@ +/* + C source for CHESS + + Revision: 4-25-88 + + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. + Copyright (c) 1988 John Stanback + + This file is part of CHESS. + + CHESS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the CHESS General Public + License for full details. + + Everyone is granted permission to copy, modify and redistribute + CHESS, but only under the conditions described in the + CHESS General Public License. A copy of this license is + supposed to have been given to you along with CHESS so you + can know your rights and responsibilities. It should be in a + file named COPYING. Among other things, the copyright notice + and this notice must be preserved on all copies. +*/ + +#ifndef lint +static char rcsid[] = "$Id: gnuchess.c,v 1.1 1995/10/18 08:41:10 deraadt Exp $"; +#endif /* not lint */ + +#include <stdio.h> +#include <ctype.h> + +#ifdef MSDOS +#include <stdlib.h> +#include <time.h> +#include <alloc.h> +#define ttblsz 4096 +#else +#include <sys/param.h> +#include <sys/times.h> +#define ttblsz 16384 +#define huge +#endif MSDOS + +#include "move.h" + +#define neutral 2 +#define white 0 +#define black 1 +#define no_piece 0 +#define pawn 1 +#define knight 2 +#define bishop 3 +#define rook 4 +#define queen 5 +#define king 6 +#define valueP 100 +#define valueN 350 +#define valueB 355 +#define valueR 550 +#define valueQ 1100 +#define valueK 1200 +#define ctlP 0x4000 +#define ctlN 0x2800 +#define ctlB 0x1800 +#define ctlR 0x0400 +#define ctlQ 0x0200 +#define ctlK 0x0100 +#define ctlBQ 0x1200 +#define ctlRQ 0x0600 +#define ctlNN 0x2000 +#define pxx " PNBRQK" +#define qxx " pnbrqk" +#define rxx "12345678" +#define cxx "abcdefgh" +#define check 0x0001 +#define capture 0x0002 +#define draw 0x0004 +#define promote 0x0008 +#define cstlmask 0x0010 +#define epmask 0x0020 +#define exact 0x0040 +#define pwnthrt 0x0080 +#define truescore 0x0001 +#define lowerbound 0x0002 +#define upperbound 0x0004 +#define maxdepth 30 +#define true 1 +#define false 0 +#define absv(x) ((x) < 0 ? -(x) : (x)) +#if (NEWMOVE < 1) +#define taxicab(a,b) (abs(column[a]-column[b]) + abs(row[a]-row[b])) +#endif +struct leaf + { + short f,t,score,reply; + unsigned short flags; + }; +struct GameRec + { + unsigned short gmove; + short score,depth,time,piece,color; + long nodes; + }; +struct TimeControlRec + { + short moves[2]; + long clock[2]; + }; +struct BookEntry + { + struct BookEntry *next; + unsigned short *mv; + }; +struct hashval + { + unsigned long bd; + unsigned short key; + }; +struct hashentry + { + unsigned long hashbd; + unsigned short mv,flags; + short score,depth; + }; + +char mvstr1[5],mvstr2[5]; +struct leaf Tree[2000],*root; +short TrPnt[maxdepth],board[64],color[64]; +short row[64],column[64],locn[8][8],Pindex[64],svalue[64]; +short PieceList[2][16],PieceCnt[2],atak[2][64],PawnCnt[2][8]; +short castld[2],kingmoved[2],mtl[2],pmtl[2],emtl[2],hung[2]; +short c1,c2,*atk1,*atk2,*PC1,*PC2,EnemyKing; +short mate,post,opponent,computer,Sdepth,Awindow,Bwindow,dither; +long ResponseTime,ExtraTime,Level,et,et0,time0,cputimer,ft; +long NodeCnt,evrate,ETnodes,EvalNodes,HashCnt; +short quit,reverse,bothsides,hashflag,InChk,player,force,easy,beep; +short wking,bking,FROMsquare,TOsquare,timeout,Zscore,zwndw,xwndw,slk; +short INCscore; +short HasPawn[2],HasKnight[2],HasBishop[2],HasRook[2],HasQueen[2]; +short ChkFlag[maxdepth],CptrFlag[maxdepth],PawnThreat[maxdepth]; +short Pscore[maxdepth],Tscore[maxdepth],Threat[maxdepth]; +struct GameRec GameList[240]; +short GameCnt,Game50,epsquare,lpost,rcptr,contempt; +short MaxSearchDepth; +struct BookEntry *Book; +struct TimeControlRec TimeControl; +short TCflag,TCmoves,TCminutes,OperatorTime; +short otherside[3]={1,0,2}; +short rank7[3]={6,1,0}; +short map[64]= + {0,1,2,3,4,5,6,7, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, + 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67, + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77}; +short unmap[120]= + {0,1,2,3,4,5,6,7,-1,-1,-1,-1,-1,-1,-1,-1, + 8,9,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1, + 16,17,18,19,20,21,22,23,-1,-1,-1,-1,-1,-1,-1,-1, + 24,25,26,27,28,29,30,31,-1,-1,-1,-1,-1,-1,-1,-1, + 32,33,34,35,36,37,38,39,-1,-1,-1,-1,-1,-1,-1,-1, + 40,41,42,43,44,45,46,47,-1,-1,-1,-1,-1,-1,-1,-1, + 48,49,50,51,52,53,54,55,-1,-1,-1,-1,-1,-1,-1,-1, + 56,57,58,59,60,61,62,63}; +short Dcode[120]= + {0,1,1,1,1,1,1,1,0,0,0,0,0,0,0x0E,0x0F, + 0x10,0x11,0x12,0,0,0,0,0,0,0,0,0,0,0,0x0F,0x1F, + 0x10,0x21,0x11,0,0,0,0,0,0,0,0,0,0,0x0F,0,0, + 0x10,0,0,0x11,0,0,0,0,0,0,0,0,0x0F,0,0,0, + 0x10,0,0,0,0x11,0,0,0,0,0,0,0x0F,0,0,0,0, + 0x10,0,0,0,0,0x11,0,0,0,0,0x0F,0,0,0,0,0, + 0x10,0,0,0,0,0,0x11,0,0,0x0F,0,0,0,0,0,0, + 0x10,0,0,0,0,0,0,0x11}; +short Stboard[64]= + {rook,knight,bishop,queen,king,bishop,knight,rook, + pawn,pawn,pawn,pawn,pawn,pawn,pawn,pawn, + 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, + pawn,pawn,pawn,pawn,pawn,pawn,pawn,pawn, + rook,knight,bishop,queen,king,bishop,knight,rook}; +short Stcolor[64]= + {white,white,white,white,white,white,white,white, + white,white,white,white,white,white,white,white, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + black,black,black,black,black,black,black,black, + black,black,black,black,black,black,black,black}; +short sweep[7]= {false,false,false,true,true,true,false}; +short Dpwn[3]={4,6,0}; +short Dstart[7]={6,4,8,4,0,0,0}; +short Dstop[7]={7,5,15,7,3,7,7}; +short Dir[16]={1,0x10,-1,-0x10,0x0F,0x11,-0x0F,-0x11, + 0x0E,-0x0E,0x12,-0x12,0x1F,-0x1F,0x21,-0x21}; +short Pdir[34]={0,0x38,0,0,0,0,0,0,0,0,0,0,0,0,0x02,0x35, + 0x38,0x35,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0x02, + 0,0x02}; +short pbit[7]={0,0x01,0x02,0x04,0x08,0x10,0x20}; +unsigned short killr0[maxdepth],killr1[maxdepth],killr2[maxdepth]; +unsigned short killr3[maxdepth],PrVar[maxdepth]; +unsigned short PV,hint,Swag0,Swag1,Swag2,Swag3,Swag4; +unsigned short hashkey; +unsigned long hashbd; +struct hashval hashcode[2][7][64]; +struct hashentry huge *ttable,*ptbl; +unsigned char history[8192]; + +short Mwpawn[64],Mbpawn[64],Mknight[2][64],Mbishop[2][64]; +short Mking[2][64],Kfield[2][64]; +short value[7]={0,valueP,valueN,valueB,valueR,valueQ,valueK}; +short control[7]={0,ctlP,ctlN,ctlB,ctlR,ctlQ,ctlK}; +short PassedPawn0[8]={0,60,80,120,200,360,600,800}; +short PassedPawn1[8]={0,30,40,60,100,180,300,800}; +short PassedPawn2[8]={0,15,25,35,50,90,140,800}; +short PassedPawn3[8]={0,5,10,15,20,30,140,800}; +short ISOLANI[8] = {-12,-16,-20,-24,-24,-20,-16,-12}; +short BACKWARD[8] = {-6,-10,-15,-21,-28,-28,-28,-28}; +short BMBLTY[14] = {-2,0,2,4,6,8,10,12,13,14,15,16,16,16}; +short RMBLTY[14] = {0,2,4,6,8,10,11,12,13,14,14,14,14,14}; +short Kthreat[16] = {0,-8,-20,-36,-52,-68,-80,-80,-80,-80,-80,-80, + -80,-80,-80,-80}; +short KNIGHTPOST,KNIGHTSTRONG,BISHOPSTRONG,KATAK,KBNKsq; +short PEDRNK2B,PWEAKH,PADVNCM,PADVNCI,PAWNSHIELD,PDOUBLED,PBLOK; +short RHOPN,RHOPNX,KHOPN,KHOPNX,KSFTY; +short ATAKD,HUNGP,HUNGX,KCASTLD,KMOVD,XRAY,PINVAL; +short stage,stage2,Zwmtl,Zbmtl,Developed[2],PawnStorm; +short PawnBonus,BishopBonus,RookBonus; +short KingOpening[64]= + { 0, 0, -4,-10,-10, -4, 0, 0, + -4, -4, -8,-12,-12, -8, -4, -4, + -12,-16,-20,-20,-20,-20,-16,-12, + -16,-20,-24,-24,-24,-24,-20,-16, + -16,-20,-24,-24,-24,-24,-20,-16, + -12,-16,-20,-20,-20,-20,-16,-12, + -4, -4, -8,-12,-12, -8, -4, -4, + 0, 0, -4,-10,-10, -4, 0, 0}; +short KingEnding[64]= + { 0, 6,12,18,18,12, 6, 0, + 6,12,18,24,24,18,12, 6, + 12,18,24,30,30,24,18,12, + 18,24,30,36,36,30,24,18, + 18,24,30,36,36,30,24,18, + 12,18,24,30,30,24,18,12, + 6,12,18,24,24,18,12, 6, + 0, 6,12,18,18,12, 6, 0}; +short DyingKing[64]= + { 0, 8,16,24,24,16, 8, 0, + 8,32,40,48,48,40,32, 8, + 16,40,56,64,64,56,40,16, + 24,48,64,72,72,64,48,24, + 24,48,64,72,72,64,48,24, + 16,40,56,64,64,56,40,16, + 8,32,40,48,48,40,32, 8, + 0, 8,16,24,24,16, 8, 0}; +short KBNK[64]= + {99,90,80,70,60,50,40,40, + 90,80,60,50,40,30,20,40, + 80,60,40,30,20,10,30,50, + 70,50,30,10, 0,20,40,60, + 60,40,20, 0,10,30,50,70, + 50,30,10,20,30,40,60,80, + 40,20,30,40,50,60,80,90, + 40,40,50,60,70,80,90,99}; +short pknight[64]= + { 0, 4, 8,10,10, 8, 4, 0, + 4, 8,16,20,20,16, 8, 4, + 8,16,24,28,28,24,16, 8, + 10,20,28,32,32,28,20,10, + 10,20,28,32,32,28,20,10, + 8,16,24,28,28,24,16, 8, + 4, 8,16,20,20,16, 8, 4, + 0, 4, 8,10,10, 8, 4, 0}; +short pbishop[64]= + {14,14,14,14,14,14,14,14, + 14,22,18,18,18,18,22,14, + 14,18,22,22,22,22,18,14, + 14,18,22,22,22,22,18,14, + 14,18,22,22,22,22,18,14, + 14,18,22,22,22,22,18,14, + 14,22,18,18,18,18,22,14, + 14,14,14,14,14,14,14,14}; +short PawnAdvance[64]= + { 0, 0, 0, 0, 0, 0, 0, 0, + 4, 4, 4, 0, 0, 4, 4, 4, + 6, 8, 2,10,10, 2, 8, 6, + 6, 8,12,16,16,12, 8, 6, + 8,12,16,24,24,16,12, 8, + 12,16,24,32,32,24,16,12, + 12,16,24,32,32,24,16,12, + 0, 0, 0, 0, 0, 0, 0, 0}; + + +main(argc,argv) +int argc; char *argv[]; +{ +#ifdef MSDOS + ttable = (struct hashentry huge *)farmalloc(ttblsz * + (unsigned long)sizeof(struct hashentry)); +#else + ttable = (struct hashentry *)malloc(ttblsz * + (unsigned long)sizeof(struct hashentry)); +#endif + Level = 0; TCflag = false; OperatorTime = 0; + if (argc == 2) Level = atoi(argv[1]); + if (argc == 3) + { + TCmoves = atoi(argv[1]); TCminutes = atoi(argv[2]); TCflag = true; + } + Initialize(); + NewGame(); +#if (NEWMOVE > 0) + Initialize_dist(); +#if (NEWMOVE > 1) + Initialize_moves(); +#endif +#endif + while (!(quit)) + { + if (bothsides && !mate) SelectMove(opponent,1); else InputCommand(); + if (!(quit || mate || force)) SelectMove(computer,1); + } + ExitChess(); +} + + + +/* ............ INTERFACE ROUTINES ........................... */ + +int VerifyMove(s,iop,mv) +char s[]; +short iop; +unsigned short *mv; + +/* + Compare the string 's' to the list of legal moves available for the + opponent. If a match is found, make the move on the board. +*/ + +{ +static short pnt,tempb,tempc,tempsf,tempst,cnt; +static struct leaf xnode; +struct leaf *node; + + *mv = 0; + if (iop == 2) + { + UnmakeMove(opponent,&xnode,&tempb,&tempc,&tempsf,&tempst); + return(false); + } + cnt = 0; + MoveList(opponent,2); + pnt = TrPnt[2]; + while (pnt < TrPnt[3]) + { + node = &Tree[pnt++]; + algbr(node->f,node->t,(short) node->flags & cstlmask); + if (strcmp(s,mvstr1) == 0 || strcmp(s,mvstr2) == 0) + { + cnt++; xnode = *node; + } + } + if (cnt == 1) + { + MakeMove(opponent,&xnode,&tempb,&tempc,&tempsf,&tempst); + if (SqAtakd(PieceList[opponent][0],computer)) + { + UnmakeMove(opponent,&xnode,&tempb,&tempc,&tempsf,&tempst); + ShowMessage("Illegal Move!!"); + return(false); + } + else + { + if (iop == 1) return(true); + if (xnode.flags & epmask) UpdateDisplay(0,0,1,0); + else UpdateDisplay(xnode.f,xnode.t,0,xnode.flags & cstlmask); + if (xnode.flags & cstlmask) Game50 = GameCnt; + else if (board[xnode.t] == pawn || (xnode.flags & capture)) + Game50 = GameCnt; + GameList[GameCnt].depth = GameList[GameCnt].score = 0; + GameList[GameCnt].nodes = 0; + ElapsedTime(1); + GameList[GameCnt].time = (short)et; + TimeControl.clock[opponent] -= et; + --TimeControl.moves[opponent]; + *mv = (xnode.f << 8) + xnode.t; + algbr(xnode.f,xnode.t,false); + return(true); + } + } + if (cnt > 1) ShowMessage("Ambiguous Move!"); + return(false); +} + + +NewGame() + +/* + Reset the board and other variables to start a new game. +*/ + +{ +short l,r,c,p; + + mate = quit = reverse = bothsides = post = false; + hashflag = force = PawnStorm = false; + beep = rcptr = easy = true; + lpost = NodeCnt = epsquare = et0 = 0; + dither = 0; + Awindow = 90; + Bwindow = 90; + xwndw = 90; + MaxSearchDepth = 29; + contempt = 0; + GameCnt = -1; Game50 = 0; + Zwmtl = Zbmtl = 0; + Developed[white] = Developed[black] = false; + castld[white] = castld[black] = false; + kingmoved[white] = kingmoved[black] = 0; + PawnThreat[0] = CptrFlag[0] = Threat[0] = false; + Pscore[0] = 12000; Tscore[0] = 12000; + opponent = white; computer = black; + for (r = 0; r < 8; r++) + for (c = 0; c < 8; c++) + { + l = 8*r+c; locn[r][c] = l; + row[l] = r; column[l] = c; + board[l] = Stboard[l]; color[l] = Stcolor[l]; + } + for (c = white; c <= black; c++) + for (p = pawn; p <= king; p++) + for (l = 0; l < 64; l++) + { + hashcode[c][p][l].key = (unsigned short)rand(); + hashcode[c][p][l].bd = ((unsigned long)rand() << 16) + + (unsigned long)rand(); + } + ClrScreen(); + if (TCflag) SetTimeControl(); + else if (Level == 0) SelectLevel(); + UpdateDisplay(0,0,1,0); + InitializeStats(); + time0 = time((long *)0); + ElapsedTime(1); + GetOpenings(); +} + + +algbr(f,t,iscastle) +short f,t,iscastle; +{ + mvstr1[0] = cxx[column[f]]; mvstr1[1] = rxx[row[f]]; + mvstr1[2] = cxx[column[t]]; mvstr1[3] = rxx[row[t]]; + mvstr2[0] = qxx[board[f]]; + mvstr2[1] = mvstr1[2]; mvstr2[2] = mvstr1[3]; + mvstr1[4] = '\0'; mvstr2[3] = '\0'; + if (iscastle) + if (t > f) strcpy(mvstr2,"o-o"); + else strcpy(mvstr2,"o-o-o"); +} + + +/* ............ MOVE GENERATION & SEARCH ROUTINES .............. */ + +SelectMove(side,iop) +short side,iop; + +/* + Select a move by calling function search() at progressively deeper + ply until time is up or a mate or draw is reached. An alpha-beta + window of -90 to +90 points is set around the score returned from the + previous iteration. If Sdepth != 0 then the program has correctly + predicted the opponents move and the search will start at a depth of + Sdepth+1 rather than a depth of 1. +*/ + +{ +static short i,alpha,beta,score,tempb,tempc,tempsf,tempst,xside,rpt; + + timeout = false; + xside = otherside[side]; + if (iop != 2) player = side; + if (TCflag) + { + if (((TimeControl.moves[side] + 3) - OperatorTime) != 0) + ResponseTime = (TimeControl.clock[side]) / + (TimeControl.moves[side] + 3) - + OperatorTime; + else ResponseTime = 0; + ResponseTime += (ResponseTime*TimeControl.moves[side])/(2*TCmoves+1); + } + else ResponseTime = Level; + if (iop == 2) ResponseTime = 999; + if (Sdepth > 0 && root->score > Zscore-zwndw) ResponseTime -= ft; + else if (ResponseTime < 1) ResponseTime = 1; + ExtraTime = 0; + ExaminePosition(); + ScorePosition(side,&score); + ShowSidetomove(); + + if (Sdepth == 0) + { + ZeroTTable(); + SearchStartStuff(side); + for (i = 0; i < 8192; i++) history[i] = 0; + FROMsquare = TOsquare = -1; + PV = 0; + if (iop != 2) hint = 0; + for (i = 0; i < maxdepth; i++) + PrVar[i] = killr0[i] = killr1[i] = killr2[i] = killr3[i] = 0; + alpha = score-90; beta = score+90; + rpt = 0; + TrPnt[1] = 0; root = &Tree[0]; + MoveList(side,1); + for (i = TrPnt[1]; i < TrPnt[2]; i++) pick(i,TrPnt[2]-1); + if (Book != NULL) OpeningBook(); + if (Book != NULL) timeout = true; + NodeCnt = ETnodes = EvalNodes = HashCnt = 0; + Zscore = 0; zwndw = 20; + } + + while (!timeout && Sdepth < MaxSearchDepth) + { + Sdepth++; + ShowDepth(' '); + score = search(side,1,Sdepth,alpha,beta,PrVar,&rpt); + for (i = 1; i <= Sdepth; i++) killr0[i] = PrVar[i]; + if (score < alpha) + { + ShowDepth('-'); + ExtraTime = 10*ResponseTime; + ZeroTTable(); + score = search(side,1,Sdepth,-9000,beta,PrVar,&rpt); + } + if (score > beta && !(root->flags & exact)) + { + ShowDepth('+'); + ExtraTime = 0; + ZeroTTable(); + score = search(side,1,Sdepth,alpha,9000,PrVar,&rpt); + } + score = root->score; + if (!timeout) + for (i = TrPnt[1]+1; i < TrPnt[2]; i++) pick(i,TrPnt[2]-1); + ShowResults(score,PrVar,'.'); + for (i = 1; i <= Sdepth; i++) killr0[i] = PrVar[i]; + if (score > Zscore-zwndw && score > Tree[1].score+250) ExtraTime = 0; + else if (score > Zscore-3*zwndw) ExtraTime = ResponseTime; + else ExtraTime = 3*ResponseTime; + if (root->flags & exact) timeout = true; + if (Tree[1].score < -9000) timeout = true; + if (4*et > 2*ResponseTime + ExtraTime) timeout = true; + if (!timeout) + { + Tscore[0] = score; + if (Zscore == 0) Zscore = score; + else Zscore = (Zscore+score)/2; + } + zwndw = 20+abs(Zscore/12); + beta = score + Bwindow; + if (Zscore < score) alpha = Zscore - Awindow - zwndw; + else alpha = score - Awindow - zwndw; + } + + score = root->score; + if (rpt >= 2 || score < -12000) root->flags |= draw; + if (iop == 2) return(0); + if (Book == NULL) hint = PrVar[2]; + ElapsedTime(1); + + if (score > -9999 && rpt <= 2) + { + MakeMove(side,root,&tempb,&tempc,&tempsf,&tempst); + algbr(root->f,root->t,(short) root->flags & cstlmask); + } + else mvstr1[0] = '\0'; + OutputMove(); + if (score == -9999 || score == 9998) mate = true; + if (mate) hint = 0; + if (root->flags & cstlmask) Game50 = GameCnt; + else if (board[root->t] == pawn || (root->flags & capture)) + Game50 = GameCnt; + GameList[GameCnt].score = score; + GameList[GameCnt].nodes = NodeCnt; + GameList[GameCnt].time = (short)et; + GameList[GameCnt].depth = Sdepth; + if (TCflag) + { + TimeControl.clock[side] -= (et + OperatorTime); + if (--TimeControl.moves[side] == 0) SetTimeControl(); + } + if ((root->flags & draw) && bothsides) quit = true; + if (GameCnt > 238) quit = true; + player = xside; + Sdepth = 0; + fflush(stdin); + return(0); +} + + +OpeningBook() + +/* + Go thru each of the opening lines of play and check for a match with + the current game listing. If a match occurs, generate a random number. + If this number is the largest generated so far then the next move in + this line becomes the current "candidate". After all lines are + checked, the candidate move is put at the top of the Tree[] array and + will be played by the program. Note that the program does not handle + book transpositions. +*/ + +{ +short j,pnt; +unsigned short m,*mp; +unsigned r,r0; +struct BookEntry *p; + + srand((unsigned)time0); + r0 = m = 0; + p = Book; + while (p != NULL) + { + mp = p->mv; + for (j = 0; j <= GameCnt; j++) + if (GameList[j].gmove != *(mp++)) break; + if (j > GameCnt) + if ((r=rand()) > r0) + { + r0 = r; m = *mp; + hint = *(++mp); + } + p = p->next; + } + + for (pnt = TrPnt[1]; pnt < TrPnt[2]; pnt++) + if ((Tree[pnt].f<<8) + Tree[pnt].t == m) Tree[pnt].score = 0; + pick(TrPnt[1],TrPnt[2]-1); + if (Tree[TrPnt[1]].score < 0) Book = NULL; +} + + +#define UpdateSearchStatus\ +{\ + if (post) ShowCurrentMove(pnt,node->f,node->t);\ + if (pnt > TrPnt[1])\ + {\ + d = best-Zscore; e = best-node->score;\ + if (best < alpha) ExtraTime = 10*ResponseTime;\ + else if (d > -zwndw && e > 4*zwndw) ExtraTime = -ResponseTime/3;\ + else if (d > -zwndw) ExtraTime = 0;\ + else if (d > -3*zwndw) ExtraTime = ResponseTime;\ + else if (d > -9*zwndw) ExtraTime = 3*ResponseTime;\ + else ExtraTime = 5*ResponseTime;\ + }\ +} + +int search(side,ply,depth,alpha,beta,bstline,rpt) +short side,ply,depth,alpha,beta,*rpt; +unsigned short bstline[]; + +/* + Perform an alpha-beta search to determine the score for the current + board position. If depth <= 0 only capturing moves, pawn promotions + and responses to check are generated and searched, otherwise all + moves are processed. The search depth is modified for check evasions, + certain re-captures and threats. Extensions may continue for up to 11 + ply beyond the nominal search depth. +*/ + +#define prune (cf && score+node->score < alpha) +#define ReCapture (rcptr && score > alpha && score < beta &&\ + ply > 2 && CptrFlag[ply-1] && CptrFlag[ply-2]) +#define MateThreat (ply < Sdepth+4 && ply > 4 &&\ + ChkFlag[ply-2] && ChkFlag[ply-4] &&\ + ChkFlag[ply-2] != ChkFlag[ply-4]) + +{ +register short j,pnt; +short best,tempb,tempc,tempsf,tempst; +short xside,pbst,d,e,cf,score,rcnt; +unsigned short mv,nxtline[maxdepth]; +struct leaf *node,tmp; + + NodeCnt++; + xside = otherside[side]; + if (depth < 0) depth = 0; + + if (ply <= Sdepth+3) repetition(rpt); else *rpt = 0; + if (*rpt >= 2) return(0); + + score = evaluate(side,xside,ply,alpha,beta); + if (score > 9000) + { + bstline[ply] = 0; + return(score); + } + + if (depth > 0) + { + if (InChk || PawnThreat[ply-1] || ReCapture) ++depth; + } + else + { + if (score >= alpha && + (InChk || PawnThreat[ply-1] || Threat[ply-1])) ++depth; + else if (score <= beta && MateThreat) ++depth; + } + + if (depth > 0 && hashflag && ply > 1) + { + ProbeTTable(side,depth,&alpha,&beta,&score); + bstline[ply] = PV; + bstline[ply+1] = 0; + if (beta == -20000) return(score); + if (alpha > beta) return(alpha); + } + + if (Sdepth == 1) d = 7; else d = 11; + if (ply > Sdepth+d || (depth < 1 && score > beta)) return(score); + + if (ply > 1) + if (depth > 0) MoveList(side,ply); + else CaptureList(side,xside,ply); + + if (TrPnt[ply] == TrPnt[ply+1]) return(score); + + cf = (depth < 1 && ply > Sdepth+1 && !ChkFlag[ply-2] && !slk); + + if (depth > 0) best = -12000; else best = score; + if (best > alpha) alpha = best; + + for (pnt = pbst = TrPnt[ply]; + pnt < TrPnt[ply+1] && best <= beta; + pnt++) + { + if (ply > 1) pick(pnt,TrPnt[ply+1]-1); + node = &Tree[pnt]; + mv = (node->f << 8) + node->t; + nxtline[ply+1] = 0; + + if (prune) break; + if (ply == 1) UpdateSearchStatus; + + if (!(node->flags & exact)) + { + MakeMove(side,node,&tempb,&tempc,&tempsf,&tempst); + CptrFlag[ply] = (node->flags & capture); + PawnThreat[ply] = (node->flags & pwnthrt); + Tscore[ply] = node->score; + PV = node->reply; + node->score = -search(xside,ply+1,depth-1,-beta,-alpha, + nxtline,&rcnt); + if (abs(node->score) > 9000) node->flags |= exact; + else if (rcnt == 1) node->score /= 2; + if (rcnt >= 2 || GameCnt-Game50 > 99 || + (node->score == 9999-ply && !ChkFlag[ply])) + { + node->flags |= draw; node->flags |= exact; + if (side == computer) node->score = contempt; + else node->score = -contempt; + } + node->reply = nxtline[ply+1]; + UnmakeMove(side,node,&tempb,&tempc,&tempsf,&tempst); + } + if (node->score > best && !timeout) + { + if (depth > 0) + if (node->score > alpha && !(node->flags & exact)) + node->score += depth; + best = node->score; pbst = pnt; + if (best > alpha) alpha = best; + for (j = ply+1; nxtline[j] > 0; j++) bstline[j] = nxtline[j]; + bstline[j] = 0; + bstline[ply] = mv; + if (ply == 1) + { + if (best == alpha) + { + tmp = Tree[pnt]; + for (j = pnt-1; j >= 0; j--) Tree[j+1] = Tree[j]; + Tree[0] = tmp; + pbst = 0; + } + if (Sdepth > 2) + if (best > beta) ShowResults(best,bstline,'+'); + else if (best < alpha) ShowResults(best,bstline,'-'); + else ShowResults(best,bstline,'&'); + } + } + if (NodeCnt > ETnodes) ElapsedTime(0); + if (timeout) return(-Tscore[ply-1]); + } + + node = &Tree[pbst]; + mv = (node->f<<8) + node->t; + if (hashflag && ply <= Sdepth && *rpt == 0 && best == alpha) + PutInTTable(side,best,depth,alpha,beta,mv); + if (depth > 0) + { + j = (node->f<<6) + node->t; if (side == black) j |= 0x1000; + if (history[j] < 150) history[j] += 2*depth; + if (node->t != (GameList[GameCnt].gmove & 0xFF)) + if (best <= beta) killr3[ply] = mv; + else if (mv != killr1[ply]) + { + killr2[ply] = killr1[ply]; + killr1[ply] = mv; + } + if (best > 9000) killr0[ply] = mv; else killr0[ply] = 0; + } + return(best); +} + + +evaluate(side,xside,ply,alpha,beta) +short side,xside,ply,alpha,beta; + +/* + Compute an estimate of the score by adding the positional score from + the previous ply to the material difference. If this score falls + inside a window which is 180 points wider than the alpha-beta window + (or within a 50 point window during quiescence search) call + ScorePosition() to determine a score, otherwise return the estimated + score. If one side has only a king and the other either has no pawns + or no pieces then the function ScoreLoneKing() is called. +*/ + +{ +short s,evflag; + + hung[white] = hung[black] = 0; + slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) || + (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0))); + s = -Pscore[ply-1] + mtl[side] - mtl[xside]; + s -= INCscore; + + if (slk) evflag = false; + else evflag = + (ply == 1 || ply < Sdepth || + ((ply == Sdepth+1 || ply == Sdepth+2) && + (s > alpha-xwndw && s < beta+xwndw)) || + (ply > Sdepth+2 && s >= alpha-25 && s <= beta+25)); + + if (evflag) + { + EvalNodes++; + ataks(side,atak[side]); + if (atak[side][PieceList[xside][0]] > 0) return(10001-ply); + ataks(xside,atak[xside]); + InChk = (atak[xside][PieceList[side][0]] > 0); + ScorePosition(side,&s); + } + else + { + if (SqAtakd(PieceList[xside][0],side)) return(10001-ply); + InChk = SqAtakd(PieceList[side][0],xside); + if (slk) ScoreLoneKing(side,&s); + } + + Pscore[ply] = s - mtl[side] + mtl[xside]; + if (InChk) ChkFlag[ply-1] = Pindex[TOsquare]; + else ChkFlag[ply-1] = 0; + Threat[ply-1] = (hung[side] > 1 && ply == Sdepth+1); + return(s); +} + + +ProbeTTable(side,depth,alpha,beta,score) +short side,depth,*alpha,*beta,*score; + +/* + Look for the current board position in the transposition table. +*/ + +{ +short hindx; + if (side == white) hashkey |= 1; else hashkey &= 0xFFFE; + hindx = (hashkey & (ttblsz-1)); + ptbl = (ttable + hindx); + if (ptbl->depth >= depth && ptbl->hashbd == hashbd) + { + HashCnt++; + PV = ptbl->mv; + if (ptbl->flags & truescore) + { + *score = ptbl->score; + *beta = -20000; + return(true); + } +/* + else if (ptbl->flags & upperbound) + { + if (ptbl->score < *beta) *beta = ptbl->score+1; + } +*/ + else if (ptbl->flags & lowerbound) + { + if (ptbl->score > *alpha) *alpha = ptbl->score-1; + } + } + return(false); +} + + +PutInTTable(side,score,depth,alpha,beta,mv) +short side,score,depth,alpha,beta; +unsigned short mv; + +/* + Store the current board position in the transposition table. +*/ + +{ +short hindx; + if (side == white) hashkey |= 1; else hashkey &= 0xFFFE; + hindx = (hashkey & (ttblsz-1)); + ptbl = (ttable + hindx); + ptbl->hashbd = hashbd; + ptbl->depth = depth; + ptbl->score = score; + ptbl->mv = mv; + ptbl->flags = 0; + if (score < alpha) ptbl->flags |= upperbound; + else if (score > beta) ptbl->flags |= lowerbound; + else ptbl->flags |= truescore; +} + + +ZeroTTable() +{ +int i; + if (hashflag) + for (i = 0; i < ttblsz; i++) + { + ptbl = (ttable + i); + ptbl->depth = 0; + } +} + + +MoveList(side,ply) +short side,ply; + +/* + Fill the array Tree[] with all available moves for side to play. Array + TrPnt[ply] contains the index into Tree[] of the first move at a ply. +*/ + +{ +register short i; +short xside,f; + + xside = otherside[side]; + if (PV == 0) Swag0 = killr0[ply]; else Swag0 = PV; + Swag1 = killr1[ply]; Swag2 = killr2[ply]; + Swag3 = killr3[ply]; Swag4 = 0; + if (ply > 2) Swag4 = killr1[ply-2]; + TrPnt[ply+1] = TrPnt[ply]; + Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1; + for (i = PieceCnt[side]; i >= 0; i--) + GenMoves(ply,PieceList[side][i],side,xside); + if (kingmoved[side] == 0 && !castld[side]) + { + f = PieceList[side][0]; + if (castle(side,f,f+2,0)) + { + LinkMove(ply,f,f+2,xside); + Tree[TrPnt[ply+1]-1].flags |= cstlmask; + } + if (castle(side,f,f-2,0)) + { + LinkMove(ply,f,f-2,xside); + Tree[TrPnt[ply+1]-1].flags |= cstlmask; + } + } +} + +#if (NEWMOVE < 11) +GenMoves(ply,sq,side,xside) +short ply,sq,side,xside; + +/* + Generate moves for a piece. The from square is mapped onto a special + board and offsets (taken from array Dir[]) are added to the mapped + location. The newly generated square is tested to see if it falls off + the board by ANDing the square with 88 HEX. Legal moves are linked + into the tree. +*/ + +{ +register short m,u,d; +short i,m0,piece; + + piece = board[sq]; m0 = map[sq]; + if (sweep[piece]) + for (i = Dstart[piece]; i <= Dstop[piece]; i++) + { + d = Dir[i]; m = m0+d; + while (!(m & 0x88)) + { + u = unmap[m]; + if (color[u] == neutral) + { + LinkMove(ply,sq,u,xside); + m += d; + } + else if (color[u] == xside) + { + LinkMove(ply,sq,u,xside); + break; + } + else break; + } + } + else if (piece == pawn) + { + if (side == white && color[sq+8] == neutral) + { + LinkMove(ply,sq,sq+8,xside); + if (row[sq] == 1) + if (color[sq+16] == neutral) + LinkMove(ply,sq,sq+16,xside); + } + else if (side == black && color[sq-8] == neutral) + { + LinkMove(ply,sq,sq-8,xside); + if (row[sq] == 6) + if (color[sq-16] == neutral) + LinkMove(ply,sq,sq-16,xside); + } + for (i = Dstart[piece]; i <= Dstop[piece]; i++) + if (!((m = m0+Dir[i]) & 0x88)) + { + u = unmap[m]; + if (color[u] == xside || u == epsquare) + LinkMove(ply,sq,u,xside); + } + } + else + { + for (i = Dstart[piece]; i <= Dstop[piece]; i++) + if (!((m = m0+Dir[i]) & 0x88)) + { + u = unmap[m]; + if (color[u] != side) LinkMove(ply,sq,u,xside); + } + } +} +#endif + +LinkMove(ply,f,t,xside) +short ply,f,t,xside; + +/* + Add a move to the tree. Assign a bonus to order the moves + as follows: + 1. Principle variation + 2. Capture of last moved piece + 3. Other captures (major pieces first) + 4. Killer moves + 5. "history" killers +*/ + +{ +register short s,z; +unsigned short mv; +struct leaf *node; + + node = &Tree[TrPnt[ply+1]]; + ++TrPnt[ply+1]; + node->flags = node->reply = 0; + node->f = f; node->t = t; + mv = (f<<8) + t; + s = 0; + if (mv == Swag0) s = 2000; + else if (mv == Swag1) s = 60; + else if (mv == Swag2) s = 50; + else if (mv == Swag3) s = 40; + else if (mv == Swag4) s = 30; + if (color[t] != neutral) + { + node->flags |= capture; + if (t == TOsquare) s += 500; + s += value[board[t]] - board[f]; + } + if (board[f] == pawn) + if (row[t] == 0 || row[t] == 7) + { + node->flags |= promote; + s += 800; + } + else if (row[t] == 1 || row[t] == 6) + { + node->flags |= pwnthrt; + s += 600; + } + else if (t == epsquare) node->flags |= epmask; + z = (f<<6) + t; if (xside == white) z |= 0x1000; + s += history[z]; + node->score = s - 20000; +} + +#if (NEWMOVE < 10) +CaptureList(side,xside,ply) +short side,xside,ply; + +/* + Generate captures and Pawn promotions only. +*/ + +#define LinkCapture\ +{\ + node->f = sq; node->t = u;\ + node->reply = 0;\ + node->flags = capture;\ + node->score = value[board[u]] + svalue[board[u]] - piece;\ + if (piece == pawn && (u < 8 || u > 55))\ + {\ + node->flags |= promote;\ + node->score = valueQ;\ + }\ + ++node;\ + ++TrPnt[ply+1];\ +} + +{ +register short m,u; +short d,sq,i,j,j1,j2,m0,r7,d0,piece,*PL; +struct leaf *node; + + TrPnt[ply+1] = TrPnt[ply]; + node = &Tree[TrPnt[ply]]; + Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1; + if (side == white) + { + r7 = 6; d0 = 8; + } + else + { + r7 = 1; d0 = -8; + } + PL = PieceList[side]; + for (i = 0; i <= PieceCnt[side]; i++) + { + sq = PL[i]; + m0 = map[sq]; piece = board[sq]; + j1 = Dstart[piece]; j2 = Dstop[piece]; + if (sweep[piece]) + for (j = j1; j <= j2; j++) + { + d = Dir[j]; m = m0+d; + while (!(m & 0x88)) + { + u = unmap[m]; + if (color[u] == neutral) m += d; + else + { + if (color[u] == xside) LinkCapture; + break; + } + } + } + else + { + for (j = j1; j <= j2; j++) + if (!((m = m0+Dir[j]) & 0x88)) + { + u = unmap[m]; + if (color[u] == xside) LinkCapture; + } + if (piece == pawn && row[sq] == r7) + { + u = sq+d0; + if (color[u] == neutral) LinkCapture; + } + } + } +} +#endif + +int castle(side,kf,kt,iop) +short side,kf,kt,iop; + +/* + Make or Unmake a castling move. +*/ + +{ +short rf,rt,d,t0,xside; + + xside = otherside[side]; + if (kt > kf) + { + rf = kf+3; rt = kt-1; d = 1; + } + else + { + rf = kf-4; rt = kt+1; d = -1; + } + if (iop == 0) + { + if (board[kf] != king || board[rf] != rook || color[rf] != side) + return(false); + if (color[kt] != neutral || color[rt] != neutral) return(false); + if (d == -1 && color[kt+d] != neutral) return(false); + if (SqAtakd(kf,xside)) return(false); + if (SqAtakd(kt,xside)) return(false); + if (SqAtakd(kf+d,xside)) return(false); + } + else + { + if (iop == 1) castld[side] = true; else castld[side] = false; + if (iop == 2) + { + t0 = kt; kt = kf; kf = t0; + t0 = rt; rt = rf; rf = t0; + } + board[kt] = king; color[kt] = side; Pindex[kt] = 0; + board[kf] = no_piece; color[kf] = neutral; + board[rt] = rook; color[rt] = side; Pindex[rt] = Pindex[rf]; + board[rf] = no_piece; color[rf] = neutral; + PieceList[side][Pindex[kt]] = kt; + PieceList[side][Pindex[rt]] = rt; + if (hashflag) + { + UpdateHashbd(side,king,kf,kt); + UpdateHashbd(side,rook,rf,rt); + } + } + return(true); +} + + +EnPassant(xside,f,t,iop) +short xside,f,t,iop; + +/* + Make or unmake an en passant move. +*/ + +{ +short l; + if (t > f) l = t-8; else l = t+8; + if (iop == 1) + { + board[l] = no_piece; color[l] = neutral; + } + else + { + board[l] = pawn; color[l] = xside; + } + InitializeStats(); +} + + +MakeMove(side,node,tempb,tempc,tempsf,tempst) +short side,*tempc,*tempb,*tempsf,*tempst; +struct leaf *node; + +/* + Update Arrays board[], color[], and Pindex[] to reflect the new board + position obtained after making the move pointed to by node. Also + update miscellaneous stuff that changes when a move is made. +*/ + +{ +register short f,t; +short xside,ct,cf; + + xside = otherside[side]; + f = node->f; t = node->t; epsquare = -1; + FROMsquare = f; TOsquare = t; + INCscore = 0; + GameList[++GameCnt].gmove = (f<<8) + t; + if (node->flags & cstlmask) + { + GameList[GameCnt].piece = no_piece; + GameList[GameCnt].color = side; + castle(side,f,t,1); + } + else + { + *tempc = color[t]; *tempb = board[t]; + *tempsf = svalue[f]; *tempst = svalue[t]; + GameList[GameCnt].piece = *tempb; + GameList[GameCnt].color = *tempc; + if (*tempc != neutral) + { + UpdatePieceList(*tempc,t,1); + if (*tempb == pawn) --PawnCnt[*tempc][column[t]]; + if (board[f] == pawn) + { + --PawnCnt[side][column[f]]; + ++PawnCnt[side][column[t]]; + cf = column[f]; ct = column[t]; + if (PawnCnt[side][ct] > 1+PawnCnt[side][cf]) + INCscore -= 15; + else if (PawnCnt[side][ct] < 1+PawnCnt[side][cf]) + INCscore += 15; + else if (ct == 0 || ct == 7 || PawnCnt[side][ct+ct-cf] == 0) + INCscore -= 15; + } + mtl[xside] -= value[*tempb]; + if (*tempb == pawn) pmtl[xside] -= valueP; + if (hashflag) UpdateHashbd(xside,*tempb,-1,t); + INCscore += *tempst; + } + color[t] = color[f]; board[t] = board[f]; svalue[t] = svalue[f]; + Pindex[t] = Pindex[f]; PieceList[side][Pindex[t]] = t; + color[f] = neutral; board[f] = no_piece; + if (board[t] == pawn) + if (t-f == 16) epsquare = f+8; + else if (f-t == 16) epsquare = f-8; + if (node->flags & promote) + { + board[t] = queen; + --PawnCnt[side][column[t]]; + mtl[side] += valueQ - valueP; + pmtl[side] -= valueP; + HasQueen[side] = true; + if (hashflag) + { + UpdateHashbd(side,pawn,f,-1); + UpdateHashbd(side,queen,f,-1); + } + INCscore -= *tempsf; + } + if (board[t] == king) ++kingmoved[side]; + if (node->flags & epmask) EnPassant(xside,f,t,1); + else if (hashflag) UpdateHashbd(side,board[t],f,t); + } +} + + +UnmakeMove(side,node,tempb,tempc,tempsf,tempst) +short side,*tempc,*tempb,*tempsf,*tempst; +struct leaf *node; + +/* + Take back a move. +*/ + +{ +register short f,t; +short xside; + + xside = otherside[side]; + f = node->f; t = node->t; epsquare = -1; + GameCnt--; + if (node->flags & cstlmask) castle(side,f,t,2); + else + { + color[f] = color[t]; board[f] = board[t]; svalue[f] = *tempsf; + Pindex[f] = Pindex[t]; PieceList[side][Pindex[f]] = f; + color[t] = *tempc; board[t] = *tempb; svalue[t] = *tempst; + if (node->flags & promote) + { + board[f] = pawn; + ++PawnCnt[side][column[t]]; + mtl[side] += valueP - valueQ; + pmtl[side] += valueP; + if (hashflag) + { + UpdateHashbd(side,queen,-1,t); + UpdateHashbd(side,pawn,-1,t); + } + } + if (*tempc != neutral) + { + UpdatePieceList(*tempc,t,2); + if (*tempb == pawn) ++PawnCnt[*tempc][column[t]]; + if (board[f] == pawn) + { + --PawnCnt[side][column[t]]; + ++PawnCnt[side][column[f]]; + } + mtl[xside] += value[*tempb]; + if (*tempb == pawn) pmtl[xside] += valueP; + if (hashflag) UpdateHashbd(xside,*tempb,-1,t); + } + if (board[f] == king) --kingmoved[side]; + if (node->flags & epmask) EnPassant(xside,f,t,2); + else if (hashflag) UpdateHashbd(side,board[f],f,t); + } +} + + +UpdateHashbd(side,piece,f,t) +short side,piece,f,t; + +/* + hashbd contains a 32 bit "signature" of the board position. hashkey + contains a 16 bit code used to address the hash table. When a move is + made, XOR'ing the hashcode of moved piece on the from and to squares + with the hashbd and hashkey values keeps things current. +*/ + +{ + if (f >= 0) + { + hashbd ^= hashcode[side][piece][f].bd; + hashkey ^= hashcode[side][piece][f].key; + } + if (t >= 0) + { + hashbd ^= hashcode[side][piece][t].bd; + hashkey ^= hashcode[side][piece][t].key; + } +} + + +UpdatePieceList(side,sq,iop) +short side,sq,iop; + +/* + Update the PieceList and Pindex arrays when a piece is captured or + when a capture is unmade. +*/ + +{ +register short i; + if (iop == 1) + { + PieceCnt[side]--; + for (i = Pindex[sq]; i <= PieceCnt[side]; i++) + { + PieceList[side][i] = PieceList[side][i+1]; + Pindex[PieceList[side][i]] = i; + } + } + else + { + PieceCnt[side]++; + PieceList[side][PieceCnt[side]] = sq; + Pindex[sq] = PieceCnt[side]; + } +} + + +InitializeStats() + +/* + Scan thru the board seeing what's on each square. If a piece is found, + update the variables PieceCnt, PawnCnt, Pindex and PieceList. Also + determine the material for each side and set the hashkey and hashbd + variables to represent the current board position. Array + PieceList[side][indx] contains the location of all the pieces of + either side. Array Pindex[sq] contains the indx into PieceList for a + given square. +*/ + +{ +register short i,sq; + epsquare = -1; + for (i = 0; i < 8; i++) + PawnCnt[white][i] = PawnCnt[black][i] = 0; + mtl[white] = mtl[black] = pmtl[white] = pmtl[black] = 0; + PieceCnt[white] = PieceCnt[black] = 0; + hashbd = hashkey = 0; + for (sq = 0; sq < 64; sq++) + if (color[sq] != neutral) + { + mtl[color[sq]] += value[board[sq]]; + if (board[sq] == pawn) + { + pmtl[color[sq]] += valueP; + ++PawnCnt[color[sq]][column[sq]]; + } + if (board[sq] == king) Pindex[sq] = 0; + else Pindex[sq] = ++PieceCnt[color[sq]]; + PieceList[color[sq]][Pindex[sq]] = sq; + hashbd ^= hashcode[color[sq]][board[sq]][sq].bd; + hashkey ^= hashcode[color[sq]][board[sq]][sq].key; + } +} + + +pick(p1,p2) +short p1,p2; + +/* + Find the best move in the tree between indexes p1 and p2. Swap the + best move into the p1 element. +*/ + +{ +register short p,s; +short p0,s0; +struct leaf temp; + + s0 = Tree[p1].score; p0 = p1; + for (p = p1+1; p <= p2; p++) + if ((s = Tree[p].score) > s0) + { + s0 = s; p0 = p; + } + if (p0 != p1) + { + temp = Tree[p1]; Tree[p1] = Tree[p0]; Tree[p0] = temp; + } +} + + +repetition(cnt) +short *cnt; + +/* + Check for draw by threefold repetition. +*/ + +{ +register short i,c; +short f,t,b[64]; +unsigned short m; + *cnt = c = 0; + if (GameCnt > Game50+3) + { +/* + memset((char *)b,0,64*sizeof(short)); +*/ + for (i = 0; i < 64; b[i++] = 0); + for (i = GameCnt; i > Game50; i--) + { + m = GameList[i].gmove; f = m>>8; t = m & 0xFF; + if (++b[f] == 0) c--; else c++; + if (--b[t] == 0) c--; else c++; + if (c == 0) (*cnt)++; + } + } +} + +#if (NEWMOVE < 3) +int SqAtakd(sq,side) +short sq,side; + +/* + See if any piece with color 'side' ataks sq. First check for pawns + or king, then try other pieces. Array Dcode is used to check for + knight attacks or R,B,Q co-linearity. +*/ + +{ +register short m,d; +short i,m0,m1,loc,piece,*PL; + + m1 = map[sq]; + if (side == white) m = m1-0x0F; else m = m1+0x0F; + if (!(m & 0x88)) + if (board[unmap[m]] == pawn && color[unmap[m]] == side) return(true); + if (side == white) m = m1-0x11; else m = m1+0x11; + if (!(m & 0x88)) + if (board[unmap[m]] == pawn && color[unmap[m]] == side) return(true); + if (distance(sq,PieceList[side][0]) == 1) return(true); + + PL = PieceList[side]; + for (i = 1; i <= PieceCnt[side]; i++) + { + loc = PL[i]; piece = board[loc]; + if (piece == pawn) continue; + m0 = map[loc]; d = Dcode[abs(m1-m0)]; + if (d == 0 || (Pdir[d] & pbit[piece]) == 0) continue; + if (piece == knight) return(true); + else + { + if (m1 < m0) d = -d; + for (m = m0+d; m != m1; m += d) + if (color[unmap[m]] != neutral) break; + if (m == m1) return(true); + } + } + return(false); +} +#endif + +#if (NEWMOVE < 2) +ataks(side,a) +short side,*a; + +/* + Fill array atak[][] with info about ataks to a square. Bits 8-15 + are set if the piece (king..pawn) ataks the square. Bits 0-7 + contain a count of total ataks to the square. +*/ + +{ +register short u,m; +short d,c,j,j1,j2,piece,i,m0,sq,*PL; + +/* + memset((char *)a,0,64*sizeof(short)); +*/ + for (u = 0; u < 64; a[u++] = 0); + Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1; + PL = PieceList[side]; + for (i = 0; i <= PieceCnt[side]; i++) + { + sq = PL[i]; + m0 = map[sq]; + piece = board[sq]; + c = control[piece]; j1 = Dstart[piece]; j2 = Dstop[piece]; + if (sweep[piece]) + for (j = j1; j <= j2; j++) + { + d = Dir[j]; m = m0+d; + while (!(m & 0x88)) + { + u = unmap[m]; + a[u] = ++a[u] | c; + if (color[u] == neutral) m += d; + else break; + } + } + else + for (j = j1; j <= j2; j++) + if (!((m = m0+Dir[j]) & 0x88)) + { + u = unmap[m]; + a[u] = ++a[u] | c; + } + } +} +#endif + +/* ............ POSITIONAL EVALUATION ROUTINES ............ */ + +ScorePosition(side,score) +short side,*score; + +/* + Perform normal static evaluation of board position. A score is + generated for each piece and these are summed to get a score for each + side. +*/ + +{ +register short sq,s; +short i,xside,pscore[3]; + + wking = PieceList[white][0]; bking = PieceList[black][0]; + UpdateWeights(); + xside = otherside[side]; + pscore[white] = pscore[black] = 0; + + for (c1 = white; c1 <= black; c1++) + { + c2 = otherside[c1]; + if (c1 == white) EnemyKing = bking; else EnemyKing = wking; + atk1 = atak[c1]; atk2 = atak[c2]; + PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2]; + for (i = 0; i <= PieceCnt[c1]; i++) + { + sq = PieceList[c1][i]; + s = SqValue(sq,side); + pscore[c1] += s; + svalue[sq] = s; + } + } + if (hung[side] > 1) pscore[side] += HUNGX; + if (hung[xside] > 1) pscore[xside] += HUNGX; + + *score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10; + if (dither) *score += rand() % dither; + + if (*score > 0 && pmtl[side] == 0) + if (emtl[side] < valueR) *score = 0; + else if (*score < valueR) *score /= 2; + if (*score < 0 && pmtl[xside] == 0) + if (emtl[xside] < valueR) *score = 0; + else if (-*score < valueR) *score /= 2; + + if (mtl[xside] == valueK && emtl[side] > valueB) *score += 200; + if (mtl[side] == valueK && emtl[xside] > valueB) *score -= 200; +} + + +ScoreLoneKing(side,score) +short side,*score; + +/* + Static evaluation when loser has only a king and winner has no pawns + or no pieces. +*/ + +{ +short winner,loser,king1,king2,s,i; + + UpdateWeights(); + if (mtl[white] > mtl[black]) winner = white; else winner = black; + loser = otherside[winner]; + king1 = PieceList[winner][0]; king2 = PieceList[loser][0]; + + s = 0; + + if (pmtl[winner] > 0) + for (i = 1; i <= PieceCnt[winner]; i++) + s += ScoreKPK(side,winner,loser,king1,king2,PieceList[winner][i]); + + else if (emtl[winner] == valueB+valueN) + s = ScoreKBNK(winner,king1,king2); + + else if (emtl[winner] > valueB) + s = 500 + emtl[winner] - DyingKing[king2] - 2*distance(king1,king2); + + if (side == winner) *score = s; else *score = -s; +} + + +int ScoreKPK(side,winner,loser,king1,king2,sq) +short side,winner,loser,king1,king2,sq; + +/* + Score King and Pawns versus King endings. +*/ + +{ +short s,r; + + if (PieceCnt[winner] == 1) s = 50; else s = 120; + if (winner == white) + { + if (side == loser) r = row[sq]-1; else r = row[sq]; + if (row[king2] >= r && distance(sq,king2) < 8-r) s += 10*row[sq]; + else s = 500+50*row[sq]; + if (row[sq] < 6) sq += 16; else sq += 8; + } + else + { + if (side == loser) r = row[sq]+1; else r = row[sq]; + if (row[king2] <= r && distance(sq,king2) < r+1) s += 10*(7-row[sq]); + else s = 500+50*(7-row[sq]); + if (row[sq] > 1) sq -= 16; else sq -= 8; + } + s += 8*(taxicab(king2,sq) - taxicab(king1,sq)); + return(s); +} + + +int ScoreKBNK(winner,king1,king2) +short winner,king1,king2; + +/* + Score King+Bishop+Knight versus King endings. + This doesn't work all that well but it's better than nothing. +*/ + +{ +short s; + s = emtl[winner] - 300; + if (KBNKsq == 0) s += KBNK[king2]; + else s += KBNK[locn[row[king2]][7-column[king2]]]; + s -= taxicab(king1,king2); + s -= distance(PieceList[winner][1],king2); + s -= distance(PieceList[winner][2],king2); + return(s); +} + + +SqValue(sq,side) +short sq,side; + +/* + Calculate the positional value for the piece on 'sq'. +*/ + +{ +register short j,fyle,rank; +short s,piece,a1,a2,in_square,r,mob,e,c; + + piece = board[sq]; + a1 = (atk1[sq] & 0x4FFF); a2 = (atk2[sq] & 0x4FFF); + rank = row[sq]; fyle = column[sq]; + s = 0; + if (piece == pawn && c1 == white) + { + s = Mwpawn[sq]; + if (sq == 11 || sq == 12) + if (color[sq+8] != neutral) s += PEDRNK2B; + if ((fyle == 0 || PC1[fyle-1] == 0) && + (fyle == 7 || PC1[fyle+1] == 0)) + s += ISOLANI[fyle]; + else if (PC1[fyle] > 1) s += PDOUBLED; + if (a1 < ctlP && atk1[sq+8] < ctlP) + { + s += BACKWARD[a2 & 0xFF]; + if (PC2[fyle] == 0) s += PWEAKH; + if (color[sq+8] != neutral) s += PBLOK; + } + if (PC2[fyle] == 0) + { + if (side == black) r = rank-1; else r = rank; + in_square = (row[bking] >= r && distance(sq,bking) < 8-r); + if (a2 == 0 || side == white) e = 0; else e = 1; + for (j = sq+8; j < 64; j += 8) + if (atk2[j] >= ctlP) { e = 2; break; } + else if (atk2[j] > 0 || color[j] != neutral) e = 1; + if (e == 2) s += (stage*PassedPawn3[rank]) / 10; + else if (in_square || e == 1) s += (stage*PassedPawn2[rank]) / 10; + else if (emtl[black] > 0) s += (stage*PassedPawn1[rank]) / 10; + else s += PassedPawn0[rank]; + } + } + else if (piece == pawn && c1 == black) + { + s = Mbpawn[sq]; + if (sq == 51 || sq == 52) + if (color[sq-8] != neutral) s += PEDRNK2B; + if ((fyle == 0 || PC1[fyle-1] == 0) && + (fyle == 7 || PC1[fyle+1] == 0)) + s += ISOLANI[fyle]; + else if (PC1[fyle] > 1) s += PDOUBLED; + if (a1 < ctlP && atk1[sq-8] < ctlP) + { + s += BACKWARD[a2 & 0xFF]; + if (PC2[fyle] == 0) s += PWEAKH; + if (color[sq-8] != neutral) s += PBLOK; + } + if (PC2[fyle] == 0) + { + if (side == white) r = rank+1; else r = rank; + in_square = (row[wking] <= r && distance(sq,wking) < r+1); + if (a2 == 0 || side == black) e = 0; else e = 1; + for (j = sq-8; j >= 0; j -= 8) + if (atk2[j] >= ctlP) { e = 2; break; } + else if (atk2[j] > 0 || color[j] != neutral) e = 1; + if (e == 2) s += (stage*PassedPawn3[7-rank]) / 10; + else if (in_square || e == 1) s += (stage*PassedPawn2[7-rank]) / 10; + else if (emtl[white] > 0) s += (stage*PassedPawn1[7-rank]) / 10; + else s += PassedPawn0[7-rank]; + } + } + else if (piece == knight) + { + s = Mknight[c1][sq]; + } + else if (piece == bishop) + { + s = Mbishop[c1][sq]; + BRscan(sq,&s,&mob); + s += BMBLTY[mob]; + } + else if (piece == rook) + { + s += RookBonus; + BRscan(sq,&s,&mob); + s += RMBLTY[mob]; + if (PC1[fyle] == 0) s += RHOPN; + if (PC2[fyle] == 0) s += RHOPNX; + if (rank == rank7[c1] && pmtl[c2] > 100) s += 10; + if (stage > 2) s += 14 - taxicab(sq,EnemyKing); + } + else if (piece == queen) + { + if (stage > 2) s += 14 - taxicab(sq,EnemyKing); + if (distance(sq,EnemyKing) < 3) s += 12; + } + else if (piece == king) + { + s = Mking[c1][sq]; + if (KSFTY > 0) + if (Developed[c2] || stage > 0) KingScan(sq,&s); + if (castld[c1]) s += KCASTLD; + else if (kingmoved[c1]) s += KMOVD; + + if (PC1[fyle] == 0) s += KHOPN; + if (PC2[fyle] == 0) s += KHOPNX; + if (fyle == 1 || fyle == 2 || fyle == 3 || fyle == 7) + { + if (PC1[fyle-1] == 0) s += KHOPN; + if (PC2[fyle-1] == 0) s += KHOPNX; + } + if (fyle == 4 || fyle == 5 || fyle == 6 || fyle == 0) + { + if (PC1[fyle+1] == 0) s += KHOPN; + if (PC2[fyle+1] == 0) s += KHOPNX; + } + if (fyle == 2) + { + if (PC1[0] == 0) s += KHOPN; + if (PC2[0] == 0) s += KHOPNX; + } + if (fyle == 5) + { + if (PC1[7] == 0) s += KHOPN; + if (PC2[7] == 0) s += KHOPNX; + } + } + + if (a2 > 0) + { + c = (control[piece] & 0x4FFF); + if (a1 == 0 || a2 > c+1) + { + s += HUNGP; + ++hung[c1]; + if (piece != king && trapped(sq,piece)) ++hung[c1]; + } + else if (piece != pawn || a2 > a1) + if (a2 >= c || a1 < ctlP) s += ATAKD; + } + return(s); +} + +#if (NEWMOVE > 6) +KingScan(sq,s) +short sq,*s; + +/* + Assign penalties if king can be threatened by checks, if squares + near the king are controlled by the enemy (especially the queen), + or if there are no pawns near the king. +*/ + +#define ScoreThreat\ + if (color[u] != c2)\ + if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\ + else *s -= 3 + +{ +register short m,u; +short d,i,m0,cnt,ok; + + cnt = 0; + m0 = map[sq]; + if (HasBishop[c2] || HasQueen[c2]) + for (i = Dstart[bishop]; i <= Dstop[bishop]; i++) + { + d = Dir[i]; m = m0+d; + while (!(m & 0x88)) + { + u = unmap[m]; + if (atk2[u] & ctlBQ) ScoreThreat; + if (color[u] != neutral) break; + m += d; + } + } + if (HasRook[c2] || HasQueen[c2]) + for (i = Dstart[rook]; i <= Dstop[rook]; i++) + { + d = Dir[i]; m = m0+d; + while (!(m & 0x88)) + { + u = unmap[m]; + if (atk2[u] & ctlRQ) ScoreThreat; + if (color[u] != neutral) break; + m += d; + } + } + if (HasKnight[c2]) + for (i = Dstart[knight]; i <= Dstop[knight]; i++) + if (!((m = m0+Dir[i]) & 0x88)) + { + u = unmap[m]; + if (atk2[u] & ctlNN) ScoreThreat; + } + *s += (KSFTY*Kthreat[cnt]) / 16; + + cnt = 0; ok = false; + m0 = map[sq]; + for (i = Dstart[king]; i <= Dstop[king]; i++) + if (!((m = m0+Dir[i]) & 0x88)) + { + u = unmap[m]; + if (board[u] == pawn) ok = true; + if (atk2[u] > atk1[u]) + { + ++cnt; + if (atk2[u] & ctlQ) + if (atk2[u] > ctlQ+1 && atk1[u] < ctlQ) *s -= 4*KSFTY; + } + } + if (!ok) *s -= KSFTY; + if (cnt > 1) *s -= KSFTY; +} +#endif + +#if (NEWMOVE < 4) +BRscan(sq,s,mob) +short sq,*s,*mob; + +/* + Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the + hung[] array if a pin is found. +*/ + +{ +register short m,u; +short d,j,m0,piece,pin,*Kf; + + Kf = Kfield[c1]; + *mob = 0; + m0 = map[sq]; piece = board[sq]; + for (j = Dstart[piece]; j <= Dstop[piece]; j++) + { + pin = -1; + d = Dir[j]; m = m0+d; + while (!(m & 0x88)) + { + u = unmap[m]; *s += Kf[u]; + if (color[u] == neutral) + { + (*mob)++; + m += d; + } + else if (pin < 0) + { + if (board[u] == pawn || board[u] == king) break; + pin = u; + m += d; + } + else if (color[u] == c2 && (board[u] > piece || atk2[u] == 0)) + { + if (color[pin] == c2) + { + *s += PINVAL; + if (atk2[pin] == 0 || + atk1[pin] > control[board[pin]]+1) + ++hung[c2]; + } + else *s += XRAY; + break; + } + else break; + } + } +} +#endif + +#if (NEWMOVE > 5) +int trapped(sq,piece) +short sq,piece; + +/* + See if the attacked piece has unattacked squares to move to. +*/ + +{ +register short u,m,d; +short i,m0; + + m0 = map[sq]; + if (sweep[piece]) + for (i = Dstart[piece]; i <= Dstop[piece]; i++) + { + d = Dir[i]; m = m0+d; + while (!(m & 0x88)) + { + u = unmap[m]; + if (color[u] == c1) break; + if (atk2[u] == 0 || board[u] >= piece) return(false); + if (color[u] == c2) break; + m += d; + } + } + else if (piece == pawn) + { + if (c1 == white) u = sq+8; else u = sq-8; + if (color[u] == neutral && atk1[u] >= atk2[u]) + return(false); + if (!((m = m0+Dir[Dpwn[c1]]) & 0x88)) + if (color[unmap[m]] == c2) return(false); + if (!((m = m0+Dir[Dpwn[c1]+1]) & 0x88)) + if (color[unmap[m]] == c2) return(false); + } + else + { + for (i = Dstart[piece]; i <= Dstop[piece]; i++) + if (!((m = m0+Dir[i]) & 0x88)) + { + u = unmap[m]; + if (color[u] != c1) + if (atk2[u] == 0 || board[u] >= piece) return(false); + } + } + return(true); +} +#endif + +ExaminePosition() + +/* + This is done one time before the search is started. Set up arrays + Mwpawn, Mbpawn, Mknight, Mbishop, Mking which are used in the + SqValue() function to determine the positional value of each piece. +*/ + +{ +register short i,sq; +short wpadv,bpadv,wstrong,bstrong,z,side,pp,j,val,Pd,fyle,rank; + + wking = PieceList[white][0]; bking = PieceList[black][0]; + ataks(white,atak[white]); ataks(black,atak[black]); + Zwmtl = Zbmtl = 0; + UpdateWeights(); + HasPawn[white] = HasPawn[black] = 0; + HasKnight[white] = HasKnight[black] = 0; + HasBishop[white] = HasBishop[black] = 0; + HasRook[white] = HasRook[black] = 0; + HasQueen[white] = HasQueen[black] = 0; + for (side = white; side <= black; side++) + for (i = 0; i <= PieceCnt[side]; i++) + switch (board[PieceList[side][i]]) + { + case pawn : ++HasPawn[side]; break; + case knight : ++HasKnight[side]; break; + case bishop : ++HasBishop[side]; break; + case rook : ++HasRook[side]; break; + case queen : ++HasQueen[side]; break; + } + if (!Developed[white]) + Developed[white] = (board[1] != knight && board[2] != bishop && + board[5] != bishop && board[6] != knight); + if (!Developed[black]) + Developed[black] = (board[57] != knight && board[58] != bishop && + board[61] != bishop && board[62] != knight); + if (!PawnStorm && stage < 5) + PawnStorm = ((column[wking] < 3 && column[bking] > 4) || + (column[wking] > 4 && column[bking] < 3)); + + CopyBoard(pknight,Mknight[white]); + CopyBoard(pknight,Mknight[black]); + CopyBoard(pbishop,Mbishop[white]); + CopyBoard(pbishop,Mbishop[black]); + BlendBoard(KingOpening,KingEnding,Mking[white]); + BlendBoard(KingOpening,KingEnding,Mking[black]); + + for (sq = 0; sq < 64; sq++) + { + fyle = column[sq]; rank = row[sq]; + wstrong = bstrong = true; + for (i = sq; i < 64; i += 8) + if (atak[black][i] >= ctlP) wstrong = false; + for (i = sq; i >= 0; i -= 8) + if (atak[white][i] >= ctlP) bstrong = false; + wpadv = bpadv = PADVNCM; + if ((fyle == 0 || PawnCnt[white][fyle-1] == 0) && + (fyle == 7 || PawnCnt[white][fyle+1] == 0)) wpadv = PADVNCI; + if ((fyle == 0 || PawnCnt[black][fyle-1] == 0) && + (fyle == 7 || PawnCnt[black][fyle+1] == 0)) bpadv = PADVNCI; + Mwpawn[sq] = (wpadv*PawnAdvance[sq]) / 10; + Mbpawn[sq] = (bpadv*PawnAdvance[63-sq]) / 10; + Mwpawn[sq] += PawnBonus; Mbpawn[sq] += PawnBonus; + if (castld[white] || kingmoved[white]) + { + if ((fyle < 3 || fyle > 4) && distance(sq,wking) < 3) + Mwpawn[sq] += PAWNSHIELD; + } + else if (rank < 3 && (fyle < 2 || fyle > 5)) + Mwpawn[sq] += PAWNSHIELD / 2; + if (castld[black] || kingmoved[black]) + { + if ((fyle < 3 || fyle > 4) && distance(sq,bking) < 3) + Mbpawn[sq] += PAWNSHIELD; + } + else if (rank > 4 && (fyle < 2 || fyle > 5)) + Mbpawn[sq] += PAWNSHIELD / 2; + if (PawnStorm) + { + if ((column[wking] < 4 && fyle > 4) || + (column[wking] > 3 && fyle < 3)) Mwpawn[sq] += 3*rank - 21; + if ((column[bking] < 4 && fyle > 4) || + (column[bking] > 3 && fyle < 3)) Mbpawn[sq] -= 3*rank; + } + + Mknight[white][sq] += 5 - distance(sq,bking); + Mknight[white][sq] += 5 - distance(sq,wking); + Mknight[black][sq] += 5 - distance(sq,wking); + Mknight[black][sq] += 5 - distance(sq,bking); + Mbishop[white][sq] += BishopBonus; + Mbishop[black][sq] += BishopBonus; + for (i = 0; i <= PieceCnt[black]; i++) + if (distance(sq,PieceList[black][i]) < 3) + Mknight[white][sq] += KNIGHTPOST; + for (i = 0; i <= PieceCnt[white]; i++) + if (distance(sq,PieceList[white][i]) < 3) + Mknight[black][sq] += KNIGHTPOST; + if (wstrong) Mknight[white][sq] += KNIGHTSTRONG; + if (bstrong) Mknight[black][sq] += KNIGHTSTRONG; + if (wstrong) Mbishop[white][sq] += BISHOPSTRONG; + if (bstrong) Mbishop[black][sq] += BISHOPSTRONG; + + if (HasBishop[white] == 2) Mbishop[white][sq] += 8; + if (HasBishop[black] == 2) Mbishop[black][sq] += 8; + if (HasKnight[white] == 2) Mknight[white][sq] += 5; + if (HasKnight[black] == 2) Mknight[black][sq] += 5; + + if (board[sq] == bishop) + if (rank % 2 == fyle % 2) KBNKsq = 0; else KBNKsq = 7; + + Kfield[white][sq] = Kfield[black][sq] = 0; + if (distance(sq,wking) == 1) Kfield[black][sq] = KATAK; + if (distance(sq,bking) == 1) Kfield[white][sq] = KATAK; + + Pd = 0; + for (i = 0; i < 64; i++) + if (board[i] == pawn) + { + if (color[i] == white) + { + pp = true; + if (row[i] == 6) z = i+8; else z = i+16; + for (j = i+8; j < 64; j += 8) + if (atak[black][j] > ctlP || board[j] == pawn) pp = false; + } + else + { + pp = true; + if (row[i] == 1) z = i-8; else z = i-16; + for (j = i-8; j >= 0; j -= 8) + if (atak[white][j] > ctlP || board[j] == pawn) pp = false; + } + if (pp) Pd += 5*taxicab(sq,z); else Pd += taxicab(sq,z); + } + if (Pd != 0) + { + val = (Pd*stage2) / 10; + Mking[white][sq] -= val; + Mking[black][sq] -= val; + } + } +} + + +UpdateWeights() + +/* + If material balance has changed, determine the values for the + positional evaluation terms. +*/ + +{ +short tmtl; + + if (mtl[white] != Zwmtl || mtl[black] != Zbmtl) + { + Zwmtl = mtl[white]; Zbmtl = mtl[black]; + emtl[white] = Zwmtl - pmtl[white] - valueK; + emtl[black] = Zbmtl - pmtl[black] - valueK; + tmtl = emtl[white] + emtl[black]; + if (tmtl > 6600) stage = 0; + else if (tmtl < 1400) stage = 10; + else stage = (6600-tmtl) / 520; + if (tmtl > 3600) stage2 = 0; + else if (tmtl < 1400) stage2 = 10; + else stage2 = (3600-tmtl) / 220; + + PEDRNK2B = -15; /* centre pawn on 2nd rank & blocked */ + PBLOK = -4; /* blocked backward pawn */ + PDOUBLED = -14; /* doubled pawn */ + PWEAKH = -4; /* weak pawn on half open file */ + PAWNSHIELD = 10-stage; /* pawn near friendly king */ + PADVNCM = 10; /* advanced pawn multiplier */ + PADVNCI = 7; /* muliplier for isolated pawn */ + PawnBonus = stage; + + KNIGHTPOST = (stage+2)/3; /* knight near enemy pieces */ + KNIGHTSTRONG = (stage+6)/2; /* occupies pawn hole */ + + BISHOPSTRONG = (stage+6)/2; /* occupies pawn hole */ + BishopBonus = 2*stage; + + RHOPN = 10; /* rook on half open file */ + RHOPNX = 4; + RookBonus = 6*stage; + + XRAY = 8; /* Xray attack on piece */ + PINVAL = 10; /* Pin */ + + KHOPN = (3*stage-30) / 2; /* king on half open file */ + KHOPNX = KHOPN / 2; + KCASTLD = 10 - stage; + KMOVD = -40 / (stage+1); /* king moved before castling */ + KATAK = (10-stage) / 2; /* B,R attacks near enemy king */ + if (stage < 8) KSFTY = 16-2*stage; else KSFTY = 0; + + ATAKD = -6; /* defender > attacker */ + HUNGP = -8; /* each hung piece */ + HUNGX = -12; /* extra for >1 hung piece */ + } +} + +#if (NEWMOVE < 1) +int distance(a,b) +short a,b; +{ +register short d1,d2; + + d1 = abs(column[a]-column[b]); + d2 = abs(row[a]-row[b]); + return(d1 > d2 ? d1 : d2); +} +#endif + +BlendBoard(a,b,c) +short a[64],b[64],c[64]; +{ +register int sq; + for (sq = 0; sq < 64; sq++) + c[sq] = (a[sq]*(10-stage) + b[sq]*stage) / 10; +} + + +CopyBoard(a,b) +short a[64],b[64]; +{ +register int sq; + for (sq = 0; sq < 64; sq++) + b[sq] = a[sq]; +} diff --git a/gnu/games/chess/gnuchess.h b/gnu/games/chess/gnuchess.h new file mode 100644 index 00000000000..4d4d1d84161 --- /dev/null +++ b/gnu/games/chess/gnuchess.h @@ -0,0 +1,99 @@ +/* + This file contains code for CHESS. + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. + + This file is part of CHESS. + + CHESS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the CHESS General Public + License for full details. + + Everyone is granted permission to copy, modify and redistribute + CHESS, but only under the conditions described in the + CHESS General Public License. A copy of this license is + supposed to have been given to you along with CHESS so you + can know your rights and responsibilities. It should be in a + file named COPYING. Among other things, the copyright notice + and this notice must be preserved on all copies. + + $Id: gnuchess.h,v 1.1 1995/10/18 08:41:11 deraadt Exp $ +*/ + + +/* Header file for GNU CHESS */ + +#define neutral 2 +#define white 0 +#define black 1 +#define no_piece 0 +#define pawn 1 +#define knight 2 +#define bishop 3 +#define rook 4 +#define queen 5 +#define king 6 +#define pxx " PNBRQK" +#define qxx " pnbrqk" +#define rxx "12345678" +#define cxx "abcdefgh" +#define check 0x0001 +#define capture 0x0002 +#define draw 0x0004 +#define promote 0x0008 +#define cstlmask 0x0010 +#define epmask 0x0020 +#define exact 0x0040 +#define pwnthrt 0x0080 +#define maxdepth 30 +#define true 1 +#define false 0 + +struct leaf + { + short f,t,score,reply; + unsigned short flags; + }; +struct GameRec + { + unsigned short gmove; + short score,depth,time,piece,color; + long nodes; + }; +struct TimeControlRec + { + short moves[2]; + long clock[2]; + }; +struct BookEntry + { + struct BookEntry *next; + unsigned short *mv; + }; + +extern char mvstr1[5],mvstr2[5]; +extern struct leaf Tree[2000],*root; +extern short TrPnt[maxdepth],board[64],color[64]; +extern short row[64],column[64],locn[8][8]; +extern short atak[2][64],PawnCnt[2][8]; +extern short castld[2],kingmoved[2]; +extern short c1,c2,*atk1,*atk2,*PC1,*PC2; +extern short mate,post,opponent,computer,Sdepth,Awindow,Bwindow,dither; +extern long ResponseTime,ExtraTime,Level,et,et0,time0,cputimer,ft; +extern long NodeCnt,evrate,ETnodes,EvalNodes,HashCnt; +extern short quit,reverse,bothsides,hashflag,InChk,player,force,easy,beep,meter; +extern short timeout,xwndw; +extern struct GameRec GameList[240]; +extern short GameCnt,Game50,epsquare,lpost,rcptr,contempt; +extern short MaxSearchDepth; +extern struct BookEntry *Book; +extern struct TimeControlRec TimeControl; +extern short TCflag,TCmoves,TCminutes,OperatorTime; +extern short otherside[3]; +extern short Stboard[64]; +extern short Stcolor[64]; +extern unsigned short hint,PrVar[maxdepth]; + +#define HZ 60 diff --git a/gnu/games/chess/move.c b/gnu/games/chess/move.c new file mode 100644 index 00000000000..59aea96192d --- /dev/null +++ b/gnu/games/chess/move.c @@ -0,0 +1,361 @@ +#ifndef lint +static char rcsid[] = "$Id: move.c,v 1.1 1995/10/18 08:41:11 deraadt Exp $"; +#endif /* not lint */ + +/* move generator hes@log-sv.se 890318 + Modified: 890606 NEWMOVE Levels 1-6 for easier debugging */ +#include "move.h" +#include "gnuchess.h" + +short distdata[64][64]; +short taxidata[64][64]; + +void Initialize_dist() { +register short a,b,d,di; + + /* init taxi and dist data */ + for(a=0;a<64;a++) + for(b=0;b<64;b++) { + d = abs(column[a]-column[b]); + di = abs(row[a]-row[b]); + taxidata[a][b] = d + di; + distdata[a][b] = (d > di ? d : di); + }; +} + +#if (NEWMOVE > 1) +struct sqdata posdata[3][8][64][64]; + +static short direc[8][8] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* no_piece = 0 */ + -10,-11, -9, 0, 0, 0, 0, 0, /* wpawn = 1 */ + -21,-19,-12, -8, 21, 19, 12, 8, /* knight = 2 */ + -11, -9, 11, 9, 0, 0, 0, 0, /* bishop = 3 */ + -10, -1, 10, 1, 0, 0, 0, 0, /* rook = 4 */ + -11, -9,-10, -1, 11, 9, 10, 1, /* queen = 5 */ + -11, -9,-10, -1, 11, 9, 10, 1, /* king = 6 */ + 0, 0, 0, 0, 0, 0, 0, 0};/* no_piece = 7 */ + +static short dc[3] = {-1,1,0}; + +static short max_steps [8] = {0,2,1,7,7,7,1,0}; + +static short unmap[120] = { + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7,-1, + -1, 8, 9,10,11,12,13,14,15,-1, + -1,16,17,18,19,20,21,22,23,-1, + -1,24,25,26,27,28,29,30,31,-1, + -1,32,33,34,35,36,37,38,39,-1, + -1,40,41,42,43,44,45,46,47,-1, + -1,48,49,50,51,52,53,54,55,-1, + -1,56,57,58,59,60,61,62,63,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; + +void Initialize_moves() { + short c,ptyp,po,p0,d,di,s; + struct sqdata *p; + short dest[8][8]; + short steps[8]; + short sorted[8]; + + /* init posdata */ + for(c=0;c<3;c++) + for(ptyp=0;ptyp<8;ptyp++) + for(po=0;po<64;po++) + for(p0=0;p0<64;p0++) { + posdata[c][ptyp][po][p0].nextpos = po; + posdata[c][ptyp][po][p0].nextdir = po; + }; + /* dest is a function of dir and step */ + for(c=0;c<2;c++) + for(ptyp=1;ptyp<7;ptyp++) + for(po=21;po<99;po++) + if (unmap[po] >= 0) { + p = posdata[c][ptyp][unmap[po]]; + for(d=0;d<8;d++) { + dest[d][0] = unmap[po]; + if (dc[c]*direc[ptyp][d] != 0) { + p0=po; + for(s=0;s<max_steps[ptyp];s++) { + p0 = p0 + dc[c]*direc[ptyp][d]; + /* break if (off board) or + (pawns move two steps from home square) */ + if (unmap[p0] < 0 || + (ptyp == pawn && s>0 && (d>0 || Stboard[unmap[po]] != ptyp))) + break; + else + dest[d][s] = unmap[p0]; + } + } + else s=0; + /* sort dest in number of steps order */ + steps[d] = s; + for(di=d;di>0;di--) + if (steps[sorted[di-1]] < s) + sorted[di] = sorted[di-1]; + else + break; + sorted[di] = d; + } + /* update posdata, pawns have two threads (capture and no capture) */ + p0=unmap[po]; + if (ptyp == pawn) { + for(s=0;s<steps[0];s++) { + p[p0].nextpos = dest[0][s]; + p0 = dest[0][s]; + } + p0=unmap[po]; + for(d=1;d<3;d++) { + p[p0].nextdir = dest[d][0]; + p0 = dest[d][0]; + } + } + else { + p[p0].nextdir = dest[sorted[0]][0]; + for(d=0;d<8;d++) + for(s=0;s<steps[sorted[d]];s++) { + p[p0].nextpos = dest[sorted[d]][s]; + p0 = dest[sorted[d]][s]; + if (d < 7) + p[p0].nextdir = dest[sorted[d+1]][0]; + /* else is already initialised */ + } + } +#ifdef DEBUG + printf("Ptyp:%d Position:%d\n{",ptyp,unmap[po]); + for(p0=0;p0<63;p0++) printf("%d,",p[p0].nextpos); + printf("%d};\n",p[63].nextpos); + for(p0=0;p0<63;p0++) printf("%d,",p[p0].nextdir); + printf("%d};\n",p[63].nextdir); +#endif DEBUG + } +} +#endif + + +#if (NEWMOVE > 2) +int SqAtakd(sq,side) +short sq,side; + +/* + See if any piece with color 'side' ataks sq. First check pawns + Then Queen, Bishop, Rook and King and last Knight. +*/ + +{ + register short u; + register struct sqdata *p; + + p = posdata[1-side][pawn][sq]; + u = p[sq].nextdir; /* follow captures thread */ + while (u != sq) { + if (board[u] == pawn && color[u] == side) return(true); + u = p[u].nextdir; + } + /* king capture */ + if (distance(sq,PieceList[side][0]) == 1) return(true); + /* try a queen bishop capture */ + p = posdata[side][bishop][sq]; + u = p[sq].nextpos; + while (u != sq) { + if (color[u] == neutral) { + u = p[u].nextpos; + } + else { + if (color[u] == side && + (board[u] == queen || board[u] == bishop)) + return(true); + u = p[u].nextdir; + } + } + /* try a queen rook capture */ + p = posdata[side][rook][sq]; + u = p[sq].nextpos; + while (u != sq) { + if (color[u] == neutral) { + u = p[u].nextpos; + } + else { + if (color[u] == side && + (board[u] == queen || board[u] == rook)) + return(true); + u = p[u].nextdir; + } + } + /* try a knight capture */ + p = posdata[side][knight][sq]; + u = p[sq].nextpos; + while (u != sq) { + if (color[u] == neutral) { + u = p[u].nextpos; + } + else { + if (color[u] == side && board[u] == knight) return(true); + u = p[u].nextdir; + } + } + return(false); +} +#endif + +#if (NEWMOVE > 3) +BRscan(sq,s,mob) +short sq,*s,*mob; +/* + Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the + hung[] array if a pin is found. +*/ +{ + register short u,piece,pin; + register struct sqdata *p; + short *Kf; + + Kf = Kfield[c1]; + *mob = 0; + piece = board[sq]; + p = posdata[color[sq]][piece][sq]; + u = p[sq].nextpos; + pin = -1; /* start new direction */ + while (u != sq) { + *s += Kf[u]; + if (color[u] == neutral) { + (*mob)++; + if (p[u].nextpos == p[u].nextdir) pin = -1; /* oops new direction */ + u = p[u].nextpos; + } + else if (pin < 0) { + if (board[u] == pawn || board[u] == king) + u = p[u].nextdir; + else { + if (p[u].nextpos != p[u].nextdir) + pin = u; /* not on the edge and on to find a pin */ + u = p[u].nextpos; + } + } + else if (color[u] == c2 && (board[u] > piece || atk2[u] == 0)) + { + if (color[pin] == c2) + { + *s += PINVAL; + if (atk2[pin] == 0 || + atk1[pin] > control[board[pin]]+1) + ++hung[c2]; + } + else *s += XRAY; + pin = -1; /* new direction */ + u = p[u].nextdir; + } + else { + pin = -1; /* new direction */ + u = p[u].nextdir; + } + } +} +#endif + +#if (NEWMOVE >= 5) +CaptureList(side,xside,ply) +short side,xside,ply; +{ + register short u,sq; + register struct sqdata *p; + short i,piece,*PL; + struct leaf *node; + + TrPnt[ply+1] = TrPnt[ply]; + node = &Tree[TrPnt[ply]]; + PL = PieceList[side]; + for (i = 0; i <= PieceCnt[side]; i++) + { + sq = PL[i]; + piece = board[sq]; + p = posdata[side][piece][sq]; + if (piece == pawn) { + u = p[sq].nextdir; /* follow captures thread */ + while (u != sq) { + if (color[u] == xside) { + node->f = sq; node->t = u; + node->flags = capture; + if (u < 8 || u > 55) + { + node->flags |= promote; + node->score = valueQ; + } + else + node->score = value[board[u]] + svalue[board[u]] - piece; + ++node; + ++TrPnt[ply+1]; + } + u = p[u].nextdir; + } + } + else { + u = p[sq].nextpos; + while (u != sq) { + if (color[u] == neutral) + u = p[u].nextpos; + else { + if (color[u] == xside) { + node->f = sq; node->t = u; + node->flags = capture; + node->score = value[board[u]] + svalue[board[u]] - piece; + ++node; + ++TrPnt[ply+1]; + } + u = p[u].nextdir; + } + } + } + } +} +#endif + +#if (NEWMOVE > 5) +GenMoves(ply,sq,side,xside) + short ply,sq,side,xside; + +/* + Generate moves for a piece. The moves are taken from the + precalulated array posdata. If the board is free, next move + is choosen from nextpos else from nextdir. +*/ + +{ + register short u,piece; + register struct sqdata *p; + + piece = board[sq]; + p = posdata[side][piece][sq]; + if (piece == pawn) { + u = p[sq].nextdir; /* follow captures thread */ + while (u != sq) { + if (color[u] == xside) LinkMove(ply,sq,u,xside); + u = p[u].nextdir; + } + u = p[sq].nextpos; /* and follow no captures thread */ + while (u != sq) { + if (color[u] == neutral && (u != sq+16 || color[u-8] == neutral) + && (u != sq-16 || color[u+8] == neutral)) { + LinkMove(ply,sq,u,xside); + } + u = p[u].nextpos; + } + } + else { + u = p[sq].nextpos; + while (u != sq) { + if (color[u] == neutral) { + LinkMove(ply,sq,u,xside); + u = p[u].nextpos; + } + else { + if (color[u] == xside) LinkMove(ply,sq,u,xside); + u = p[u].nextdir; + } + } + } +} +#endif diff --git a/gnu/games/chess/move.h b/gnu/games/chess/move.h new file mode 100644 index 00000000000..c309a5ff0de --- /dev/null +++ b/gnu/games/chess/move.h @@ -0,0 +1,83 @@ +/* $Id: move.h,v 1.1 1995/10/18 08:41:11 deraadt Exp $ */ + +/* header file for move generator hes 890318 + Modified: 890510 minor bug fixed in Newataks + 890606 NEWMOVE levels 1-6 */ + +#if (NEWMOVE >= 1) +extern short distdata[64][64]; +extern short taxidata[64][64]; + +#define taxicab(a,b) taxidata[a][b] +#define distance(a,b) distdata[a][b] + +extern void Initialize_dist(); +#endif + +#if (NEWMOVE >= 2) +struct sqdata { + short nextpos; + short nextdir; +}; +extern struct sqdata posdata[3][8][64][64]; + +extern void Initialize_moves(); + +#define ataks(side,a)\ +{\ + register short u,c,sq;\ + register struct sqdata *p;\ + short i,piece,*PL;\ + \ + for (u = 64; u; a[--u] = 0); \ + PL = PieceList[side];\ + for (i = 0; i <= PieceCnt[side]; i++)\ + {\ + sq = PL[i];\ + piece = board[sq];\ + c = control[piece];\ + p = posdata[side][piece][sq];\ + if (piece == pawn) {\ + u = p[sq].nextdir; /* follow captures thread */\ + while (u != sq) {\ + a[u] = ++a[u] | c;\ + u = p[u].nextdir;\ + }\ + }\ + else {\ + u = p[sq].nextpos;\ + while (u != sq) {\ + a[u] = ++a[u] | c;\ + if (color[u] == neutral)\ + u = p[u].nextpos;\ + else\ + u = p[u].nextdir;\ + }\ + }\ + }\ +} +#endif + +#if (NEWMOVE >= 3) +extern short PieceList[2][16]; + +extern int Sqatakd(); +#endif + +#if (NEWMOVE > 3) +extern short Kfield[2][64],PINVAL,control[7],hung[2],XRAY; + +extern BRscan(); +#endif + +#if (NEWMOVE > 4) +#define valueQ 1100 + +extern short PieceCnt[2],value[7],svalue[64]; + +extern CaptureList(); +#endif + +#if (NEWMOVE > 5) +extern GenMoves(); +#endif diff --git a/gnu/games/chess/nondsp.c b/gnu/games/chess/nondsp.c new file mode 100644 index 00000000000..ca89c936bd9 --- /dev/null +++ b/gnu/games/chess/nondsp.c @@ -0,0 +1,794 @@ +/* + UNIX & MSDOS NON-DISPLAY, AND CHESSTOOL interface for Chess + + Revision: 4-25-88 + + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. + Copyright (c) 1988 John Stanback + + This file is part of CHESS. + + CHESS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the CHESS General Public + License for full details. + + Everyone is granted permission to copy, modify and redistribute + CHESS, but only under the conditions described in the + CHESS General Public License. A copy of this license is + supposed to have been given to you along with CHESS so you + can know your rights and responsibilities. It should be in a + file named COPYING. Among other things, the copyright notice + and this notice must be preserved on all copies. +*/ + +#ifndef lint +static char rcsid[] = "$Id: nondsp.c,v 1.1 1995/10/18 08:41:11 deraadt Exp $"; +#endif /* not lint */ + +#include <stdio.h> +#include <ctype.h> +#ifdef MSDOS +#include <dos.h> +#include <stdlib.h> +#include <time.h> +#else +#include <sys/param.h> +#include <sys/times.h> +#include <sys/file.h> +struct tms tmbuf1,tmbuf2; +int TerminateSearch(),Die(); +#endif MSDOS + +#include "gnuchess.h" +#ifdef NEWMOVE +#include "move.h" +#endif + +#define printz printf +#define scanz scanf +int mycnt1,mycnt2; + + +Initialize() +{ + mycnt1 = mycnt2 = 0; +#ifndef MSDOS +#endif +#ifdef CHESSTOOL + setlinebuf(stdout); +/* + setvbuf(stdout,NULL,_IOLBF,BUFSIZ); +*/ + printf("Chess\n"); + if (Level == 0 && !TCflag) Level = 15; +#endif CHESSTOOL +} + +ExitChess() +{ + ListGame(); + exit(0); +} + +#ifndef MSDOS +Die() +{ +char s[80]; + printz("Abort? "); + scanz("%s",s); + if (strcmp(s,"yes") == 0) ExitChess(); +} + +TerminateSearch() +{ + timeout = true; + bothsides = false; +} +#endif MSDOS + + +InputCommand() + +/* + Process the users command. If easy mode is OFF (the computer is + thinking on opponents time) and the program is out of book, then make + the 'hint' move on the board and call SelectMove() to find a response. + The user terminates the search by entering ^C (quit siqnal) before + entering a command. If the opponent does not make the hint move, then + set Sdepth to zero. +*/ + +{ +int i; +short ok,tmp; +long cnt,rate,t1,t2; +unsigned short mv; +char s[80]; + + ok = quit = false; + player = opponent; + ft = 0; + if (hint > 0 && !easy && Book == NULL) + { + fflush(stdout); + time0 = time((long *)0); + algbr(hint>>8,hint & 0xFF,false); + strcpy(s,mvstr1); + tmp = epsquare; + if (VerifyMove(s,1,&mv)) + { + SelectMove(computer,2); + VerifyMove(mvstr1,2,&mv); + if (Sdepth > 0) Sdepth--; + } + ft = time((long *)0) - time0; + epsquare = tmp; + } + +#ifndef MSDOS +#endif + while (!(ok || quit)) + { + PromptForMove(); + i = scanz("%s",s); + if (i == EOF || s[0] == 0) ExitChess(); + player = opponent; + ok = VerifyMove(s,0,&mv); + if (ok && mv != hint) + { + Sdepth = 0; + ft = 0; + } + + if (strcmp(s,"bd") == 0) + { + ClrScreen(); + UpdateDisplay(0,0,1,0); + } + if (strcmp(s,"quit") == 0) quit = true; + if (strcmp(s,"post") == 0) post = !post; + if (strcmp(s,"set") == 0) EditBoard(); + if (strcmp(s,"go") == 0) ok = true; + if (strcmp(s,"help") == 0) help(); + if (strcmp(s,"force") == 0) force = !force; + if (strcmp(s,"book") == 0) Book = NULL; + if (strcmp(s,"new") == 0) NewGame(); + if (strcmp(s,"list") == 0) ListGame(); + if (strcmp(s,"level") == 0) SelectLevel(); + if (strcmp(s,"hash") == 0) hashflag = !hashflag; + if (strcmp(s,"beep") == 0) beep = !beep; + if (strcmp(s,"Awindow") == 0) ChangeAlphaWindow(); + if (strcmp(s,"Bwindow") == 0) ChangeBetaWindow(); + if (strcmp(s,"rcptr") == 0) rcptr = !rcptr; + if (strcmp(s,"hint") == 0) GiveHint(); + if (strcmp(s,"zero") == 0) ZeroTTable(); + if (strcmp(s,"both") == 0) + { + bothsides = !bothsides; + Sdepth = 0; + SelectMove(opponent,1); + ok = true; + } + if (strcmp(s,"reverse") == 0) + { + reverse = !reverse; + ClrScreen(); + UpdateDisplay(0,0,1,0); + } + if (strcmp(s,"switch") == 0) + { + computer = otherside[computer]; + opponent = otherside[opponent]; + force = false; + Sdepth = 0; + ok = true; + } + if (strcmp(s,"white") == 0) + { + computer = white; opponent = black; + ok = true; force = false; + Sdepth = 0; + } + if (strcmp(s,"black") == 0) + { + computer = black; opponent = white; + ok = true; force = false; + Sdepth = 0; + } + if (strcmp(s,"undo") == 0 && GameCnt >= 0) Undo(); + if (strcmp(s,"remove") == 0 && GameCnt >= 1) + { + Undo(); Undo(); + } + if (strcmp(s,"get") == 0) GetGame(); + if (strcmp(s,"save") == 0) SaveGame(); + if (strcmp(s,"depth") == 0) ChangeSearchDepth(); + if (strcmp(s,"random") == 0) dither = 6; + if (strcmp(s,"easy") == 0) easy = !easy; + if (strcmp(s,"contempt") == 0) SetContempt(); + if (strcmp(s,"xwndw") == 0) ChangeXwindow(); + if (strcmp(s,"test") == 0) + { + t1 = time(0); + cnt = 0; + for (i = 0; i < 10000; i++) + { + MoveList(opponent,2); + cnt += TrPnt[3] - TrPnt[2]; + } + t2 = time(0); + rate = cnt / (t2-t1); + printz("cnt= %ld rate= %ld\n",cnt,rate); + } + } + + ElapsedTime(1); + if (force) + { + computer = opponent; opponent = otherside[computer]; + } +#ifndef MSDOS + (void) times(&tmbuf1); +#ifdef CHESSTOOL + printf("%d. %s\n",++mycnt2,s); +#endif CHESSTOOL +#endif MSDOS +} + + +help() +{ + ClrScreen(); + printz("CHESS command summary\n"); + printz("g1f3 move from g1 to f3\n"); + printz("nf3 move knight to f3\n"); + printz("o-o castle king side\n"); + printz("o-o-o castle queen side\n"); + printz("set edit board\n"); + printz("switch sides with computer\n"); + printz("white computer plays white\n"); + printz("black computer plays black\n"); + printz("reverse board display\n"); + printz("both computer match\n"); + printz("random randomize play\n"); + printz("undo undo last move\n"); + printz("time change level\n"); + printz("depth set search depth\n"); + printz("post principle variation\n"); + printz("hint suggest a move\n"); + printz("bd redraw board\n"); + printz("clock set time control\n"); + printz("force enter game moves\n"); + printz("list game to chess.lst\n"); + printz("save game to file\n"); + printz("get game from file\n"); + printz("new start new game\n"); + printz("quit exit CHESS\n"); + printz("Computer: "); + if (computer == white) printz("WHITE\n"); else printz("BLACK\n"); + printz("Opponent: "); + if (opponent == white) printz("WHITE\n"); else printz("BLACK\n"); + printz("Response time: %ld",Level," sec.\n"); + printz("Easy mode: "); + if (easy) printz("ON\n"); else printz("OFF\n"); + printz("Depth: %d\n",MaxSearchDepth); + printz("Random: "); + if (dither) printz("ON\n"); else printz("OFF\n"); + printz("Transposition table: "); + if (hashflag) printz("ON\n"); else printz("OFF\n"); + UpdateDisplay(0,0,1,0); +} + + +EditBoard() + +/* + Set up a board position. Pieces are entered by typing the piece + followed by the location. For example, Nf3 will place a knight on + square f3. +*/ + +{ +short a,r,c,sq; +char s[80]; + + ClrScreen(); + UpdateDisplay(0,0,1,0); + printz(". exit to main\n"); + printz("# clear board\n"); + printz("enter piece & location: \n"); + + a = white; + do + { + scanz("%s",s); + if (s[0] == '#') + { + for (sq = 0; sq < 64; sq++) + { + board[sq] = no_piece; color[sq] = neutral; + } + UpdateDisplay(0,0,1,0); + } + if (s[0] == 'c' || s[0] == 'C') a = otherside[a]; + c = s[1]-'a'; r = s[2]-'1'; + if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8)) + { + sq = locn[r][c]; + color[sq] = a; + if (s[0] == 'p') board[sq] = pawn; + else if (s[0] == 'n') board[sq] = knight; + else if (s[0] == 'b') board[sq] = bishop; + else if (s[0] == 'r') board[sq] = rook; + else if (s[0] == 'q') board[sq] = queen; + else if (s[0] == 'k') board[sq] = king; + else { board[sq] = no_piece; color[sq] = neutral; } + } + } + while (s[0] != '.'); + if (board[4] != king) kingmoved[white] = 10; + if (board[60] != king) kingmoved[black] = 10; + GameCnt = -1; Game50 = 0; Sdepth = 0; + InitializeStats(); + ClrScreen(); + UpdateDisplay(0,0,1,0); +} + + +ShowDepth(ch) +char ch; +{ +} + +ShowResults(score,bstline,ch) +short score; +unsigned short bstline[]; +char ch; +{ +#ifndef CHESSTOOL +register int i; + printz("%2d%c %5d %4ld %7ld ",Sdepth,ch,score,et,NodeCnt); + for (i = 1; bstline[i] > 0; i++) + { + algbr((short)(bstline[i] >> 8),(short)(bstline[i] & 0xFF),false); + if (i == 9 || i == 17) printz("\n "); + printz("%5s ",mvstr1); + } + printz("\n"); +#endif +} + + +SearchStartStuff(side) +short side; +{ +#ifndef MSDOS +#endif +#ifndef CHESSTOOL + printz("\nMove# %d Target= %ld Clock: %ld\n", + TCmoves-TimeControl.moves[side]+1, + ResponseTime,TimeControl.clock[side]); +#endif +} + + +OutputMove() +{ +#ifdef CHESSTOOL + printz("%d. ... %s\n",++mycnt1,mvstr1); + if (root->flags & draw) + { + printz("Draw\n"); + ListGame(); + exit(0); + } + if (root->score == -9999) + { + if (opponent == white) printz("White\n"); else printz("Black\n"); + ListGame(); + exit(0); + } + if (root->score == 9998) + { + if (computer == white) printz("White\n"); else printz("Black\n"); + ListGame(); + exit(0); + } +#else + printz("Nodes= %ld Eval= %ld Hash= %ld Rate= %ld ", + NodeCnt,EvalNodes,HashCnt,evrate); + printz("CPU= %.2ld:%.2ld.%.2ld\n\n", + cputimer/6000,(cputimer % 6000)/100,cputimer % 100); + + if (root->flags & epmask) UpdateDisplay(0,0,1,0); + else UpdateDisplay(root->f,root->t,0,root->flags & cstlmask); + printz("My move is: %s\n\n",mvstr1); + if (beep) printz("%c",7); + + if (root->flags & draw) printz("Draw game!\n"); + else if (root->score == -9999) printz("opponent mates!\n"); + else if (root->score == 9998) printz("computer mates!\n"); + else if (root->score < -9000) printz("opponent will soon mate!\n"); + else if (root->score > 9000) printz("computer will soon mate!\n"); +#endif CHESSTOOL +} + + +ElapsedTime(iop) +short iop; + +/* + Determine the time that has passed since the search was started. If + the elapsed time exceeds the target (ResponseTime+ExtraTime) then set + timeout to true which will terminate the search. +*/ + +{ + et = time((long *)0) - time0; + if (et < 0) et = 0; + ETnodes += 50; + if (et > et0 || iop == 1) + { + if (et > ResponseTime+ExtraTime && Sdepth > 1) timeout = true; + et0 = et; + if (iop == 1) + { + time0 = time((long *)0); et0 = 0; + } +#ifdef MSDOS + cputimer = 100*et; + if (et > 0) evrate = NodeCnt/(et+ft); else evrate = 0; + if (kbhit() && Sdepth > 1) + { + timeout = true; + bothsides = false; + } +#else + (void) times(&tmbuf2); + cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ; + if (cputimer > 0) evrate = (100*NodeCnt)/(cputimer+100*ft); + else evrate = 0; +#endif MSDOS + ETnodes = NodeCnt + 50; + } +} + + +SetTimeControl() +{ + if (TCflag) + { + TimeControl.moves[white] = TimeControl.moves[black] = TCmoves; + TimeControl.clock[white] = TimeControl.clock[black] = 60*(long)TCminutes; + } + else + { + TimeControl.moves[white] = TimeControl.moves[black] = 0; + TimeControl.clock[white] = TimeControl.clock[black] = 0; + Level = 60*(long)TCminutes; + } + et = 0; + ElapsedTime(1); +} + + +ClrScreen() +{ +#ifndef CHESSTOOL + printz("\n"); +#endif +} + + +UpdateDisplay(f,t,flag,iscastle) +short f,t,flag,iscastle; +{ +#ifndef CHESSTOOL +short r,c,l; + if (flag) + { + printz("\n"); + for (r = 7; r >= 0; r--) + { + for (c = 0; c <= 7; c++) + { + if (reverse) l = locn[7-r][7-c]; else l = locn[r][c]; + if (color[l] == neutral) printz(" -"); + else if (color[l] == white) printz(" %c",qxx[board[l]]); + else printz(" %c",pxx[board[l]]); + } + printz("\n"); + } + printz("\n"); + } +#endif CHESSTOOL +} + + +GetOpenings() + +/* + Read in the Opening Book file and parse the algebraic notation for a + move into an unsigned integer format indicating the from and to + square. Create a linked list of opening lines of play, with + entry->next pointing to the next line and entry->move pointing to a + chunk of memory containing the moves. More Opening lines of up to 256 + half moves may be added to gnuchess.book. +*/ + +{ +FILE *fd; +int c,i,j,side; +char buffr[2048]; +struct BookEntry *entry; +unsigned short mv,*mp,tmp[100]; + + if ((fd = fopen("gnuchess.book","r")) != NULL) + { +/* + setvbuf(fd,buffr,_IOFBF,2048); +*/ + Book = NULL; + i = 0; side = white; + while ((c = parse(fd,&mv,side)) >= 0) + if (c == 1) + { + tmp[++i] = mv; + side = otherside[side]; + } + else if (c == 0 && i > 0) + { + entry = (struct BookEntry *)malloc(sizeof(struct BookEntry)); + mp = (unsigned short *)malloc((i+1)*sizeof(unsigned short)); + entry->mv = mp; + entry->next = Book; + Book = entry; + for (j = 1; j <= i; j++) *(mp++) = tmp[j]; + *mp = 0; + i = 0; side = white; + } + fclose(fd); + } +} + + +int parse(fd,mv,side) +FILE *fd; +unsigned short *mv; +short side; +{ +int c,i,r1,r2,c1,c2; +char s[100]; + while ((c = getc(fd)) == ' '); + i = 0; s[0] = c; + while (c != ' ' && c != '\n' && c != EOF) s[++i] = c = getc(fd); + s[++i] = '\0'; + if (c == EOF) return(-1); + if (s[0] == '!' || i < 3) + { + while (c != '\n' && c != EOF) c = getc(fd); + return(0); + } + if (s[4] == 'o') + if (side == black) *mv = 0x3C3A; else *mv = 0x0402; + else if (s[0] == 'o') + if (side == black) *mv = 0x3C3E; else *mv = 0x0406; + else + { + c1 = s[0] - 'a'; r1 = s[1] - '1'; + c2 = s[2] - 'a'; r2 = s[3] - '1'; + *mv = (locn[r1][c1]<<8) + locn[r2][c2]; + } + return(1); +} + + +GetGame() +{ +FILE *fd; +char fname[40]; +int c; +short sq; +unsigned short m; + + printz("Enter file name: "); + scanz("%s",fname); + if (fname[0] == '\0') strcpy(fname,"chess.000"); + if ((fd = fopen(fname,"r")) != NULL) + { + fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50); + fscanf(fd,"%hd%hd%hd%hd", + &castld[white],&castld[black], + &kingmoved[white],&kingmoved[black]); + fscanf(fd,"%hd%hd",&TCflag,&OperatorTime); + fscanf(fd,"%ld%ld%hd%hd", + &TimeControl.clock[white],&TimeControl.clock[black], + &TimeControl.moves[white],&TimeControl.moves[black]); + for (sq = 0; sq < 64; sq++) + { + fscanf(fd,"%hd",&m); + board[sq] = (m >> 8); color[sq] = (m & 0xFF); + if (color[sq] == 0) color[sq] = neutral; else --color[sq]; + } + GameCnt = -1; c = '?'; + while (c != EOF) + { + ++GameCnt; + c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove, + &GameList[GameCnt].score,&GameList[GameCnt].depth, + &GameList[GameCnt].nodes,&GameList[GameCnt].time, + &GameList[GameCnt].piece,&GameList[GameCnt].color); + if (GameList[GameCnt].color == 0) GameList[GameCnt].color = neutral; + else --GameList[GameCnt].color; + } + GameCnt--; + if (TimeControl.clock[white] > 0) TCflag = true; + computer--; opponent--; + } + fclose(fd); + InitializeStats(); + UpdateDisplay(0,0,1,0); + Sdepth = 0; +} + + +SaveGame() +{ +FILE *fd; +char fname[40]; +short sq,i,c; + + printz("Enter file name: "); + scanz("%s",fname); + + if (fname[0] == '\0' || access(fname,W_OK) == -1) strcpy(fname,"chess.000"); + fd = fopen(fname,"w"); + fprintf(fd,"%d %d %d\n",computer+1,opponent+1,Game50); + fprintf(fd,"%d %d %d %d\n", + castld[white],castld[black],kingmoved[white],kingmoved[black]); + fprintf(fd,"%d %d\n",TCflag,OperatorTime); + fprintf(fd,"%ld %ld %d %d\n", + TimeControl.clock[white],TimeControl.clock[black], + TimeControl.moves[white],TimeControl.moves[black]); + for (sq = 0; sq < 64; sq++) + { + if (color[sq] == neutral) c = 0; else c = color[sq]+1; + fprintf(fd,"%d\n",256*board[sq] + c); + } + for (i = 0; i <= GameCnt; i++) + { + if (GameList[i].color == neutral) c = 0; + else c = GameList[i].color + 1; + fprintf(fd,"%d %d %d %ld %d %d %d\n", + GameList[i].gmove,GameList[i].score,GameList[i].depth, + GameList[i].nodes,GameList[i].time, + GameList[i].piece,c); + } + fclose(fd); +} + + +ListGame() +{ +FILE *fd; +short i,f,t; + fd = fopen("chess.lst","w"); + fprintf(fd,"\n"); + fprintf(fd," score depth nodes time "); + fprintf(fd," score depth nodes time\n"); + for (i = 0; i <= GameCnt; i++) + { + f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF); + algbr(f,t,false); + if ((i % 2) == 0) fprintf(fd,"\n"); else fprintf(fd," "); + fprintf(fd,"%5s %5d %2d %6ld %5d",mvstr1, + GameList[i].score,GameList[i].depth, + GameList[i].nodes,GameList[i].time); + } + fprintf(fd,"\n\n"); + fclose(fd); +} + + +Undo() + +/* + Undo the most recent half-move. +*/ + +{ +short f,t; + f = GameList[GameCnt].gmove>>8; + t = GameList[GameCnt].gmove & 0xFF; + if (board[t] == king && distance(t,f) > 1) + castle(GameList[GameCnt].color,f,t,2); + else + { + board[f] = board[t]; color[f] = color[t]; + board[t] = GameList[GameCnt].piece; + color[t] = GameList[GameCnt].color; + if (board[f] == king) --kingmoved[color[f]]; + } + if (TCflag) ++TimeControl.moves[color[f]]; + GameCnt--; mate = false; Sdepth = 0; + UpdateDisplay(0,0,1,0); + InitializeStats(); +} + + +ShowMessage(s) +char *s; +{ +#ifndef CHESSTOOL + printz("%s\n"); +#endif CHESSTOOL +} + +ShowSidetomove() +{ +} + +PromptForMove() +{ +#ifndef CHESSTOOL + printz("\nYour move is? "); +#endif CHESSTOOL +} + + +ShowCurrentMove(pnt,f,t) +short pnt,f,t; +{ +} + +ChangeAlphaWindow() +{ + printz("window: "); + scanz("%hd",&Awindow); +} + +ChangeBetaWindow() +{ + printz("window: "); + scanz("%hd",&Bwindow); +} + +GiveHint() +{ + algbr((short)(hint>>8),(short)(hint & 0xFF),false); + printz("try %s\n",mvstr1); +} + + +SelectLevel() +{ + OperatorTime = 30000; + printz("Enter #moves #minutes: "); + scanz("%hd %hd",&TCmoves,&TCminutes); + printz("Operator time= "); + scanz("%hd",&OperatorTime); + TCflag = (TCmoves > 1); + SetTimeControl(); +} + + +ChangeSearchDepth() +{ + printz("depth= "); + scanz("%hd",&MaxSearchDepth); +} + +SetContempt() +{ + printz("contempt= "); + scanz("%hd",&contempt); +} + +ChangeXwindow() +{ + printz("xwndw= "); + scanz("%hd",&xwndw); +} diff --git a/gnu/games/chess/pathnames.h b/gnu/games/chess/pathnames.h new file mode 100644 index 00000000000..46d6b6c6494 --- /dev/null +++ b/gnu/games/chess/pathnames.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)pathnames.h 5.1 (Berkeley) 5/2/90 + * $Id: pathnames.h,v 1.1 1995/10/18 08:41:11 deraadt Exp $ + */ + +#define _PATH_CHESSBOOK "/usr/share/games/gnuchess.book" diff --git a/gnu/games/chess/uxdsp.c b/gnu/games/chess/uxdsp.c new file mode 100644 index 00000000000..a0a5ba2599d --- /dev/null +++ b/gnu/games/chess/uxdsp.c @@ -0,0 +1,936 @@ +/* + ALPHA interface for CHESS + + Revision: 4-25-88 + + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. + Copyright (c) 1988 John Stanback + + This file is part of CHESS. + + CHESS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the CHESS General Public + License for full details. + + Everyone is granted permission to copy, modify and redistribute + CHESS, but only under the conditions described in the + CHESS General Public License. A copy of this license is + supposed to have been given to you along with CHESS so you + can know your rights and responsibilities. It should be in a + file named COPYING. Among other things, the copyright notice + and this notice must be preserved on all copies. +*/ + +#ifndef lint +static char rcsid[] = "$Id: uxdsp.c,v 1.1 1995/10/18 08:41:11 deraadt Exp $"; +#endif /* not lint */ + +#include <stdio.h> +#include <ctype.h> +#include <sys/param.h> +#include <sys/times.h> +#include <sys/file.h> +#include <curses.h> +#include <signal.h> +#include "gnuchess.h" +#ifdef NEWMOVE +#include "move.h" +#endif +#include "pathnames.h" + +struct tms tmbuf1,tmbuf2; +void TerminateSearch(),Die(); + +#define scanz fflush(stdout),scanw +#define printz printw + + +Initialize() +{ + signal(SIGINT,Die); signal(SIGQUIT,Die); + initscr(); + crmode(); +} + + +ExitChess() +{ + nocrmode(); + endwin(); + exit(0); +} + + +void +Die() +{ +char s[80]; + signal(SIGINT,SIG_IGN); + signal(SIGQUIT,SIG_IGN); + ShowMessage("Abort? "); + scanz("%s",s); + if (strcmp(s,"yes") == 0) ExitChess(); + signal(SIGINT,Die); signal(SIGQUIT,Die); +} + + +void +TerminateSearch() +{ + signal(SIGINT,SIG_IGN); + signal(SIGQUIT,SIG_IGN); + timeout = true; + bothsides = false; + signal(SIGINT,Die); signal(SIGQUIT,Die); +} + + +InputCommand() + +/* + Process the users command. If easy mode is OFF (the computer is + thinking on opponents time) and the program is out of book, then make + the 'hint' move on the board and call SelectMove() to find a response. + The user terminates the search by entering ^C (quit siqnal) before + entering a command. If the opponent does not make the hint move, then + set Sdepth to zero. +*/ + +{ +short ok,i,tmp; +long cnt,rate,t1,t2; +unsigned short mv; +char s[80]; + + ok = quit = false; + player = opponent; + ShowSidetomove(); + ft = 0; + if (hint > 0 && !easy && Book == NULL) + { + fflush(stdout); + time0 = time((long *)0); + algbr(hint>>8,hint & 0xFF,false); + strcpy(s,mvstr1); + tmp = epsquare; + if (VerifyMove(s,1,&mv)) + { + PromptForMove(); + SelectMove(computer,2); + VerifyMove(mvstr1,2,&mv); + if (Sdepth > 0) Sdepth--; + } + ft = time((time_t *)0) - time0; + epsquare = tmp; + } + + signal(SIGINT,Die); signal(SIGQUIT,Die); + while (!(ok || quit)) + { + PromptForMove(); + scanz("%s",s); + player = opponent; + ok = VerifyMove(s,0,&mv); + if (ok && mv != hint) + { + Sdepth = 0; + ft = 0; + } + + if (strcmp(s,"bd") == 0) + { + ClrScreen(); + UpdateDisplay(0,0,1,0); + } + if (strcmp(s,"quit") == 0) quit = true; + if (strcmp(s,"post") == 0) post = !post; + if (strcmp(s,"edit") == 0) EditBoard(); + if (strcmp(s,"go") == 0) ok = true; + if (strcmp(s,"help") == 0) help(); + if (strcmp(s,"force") == 0) force = !force; + if (strcmp(s,"book") == 0) Book = NULL; + if (strcmp(s,"undo") == 0 && GameCnt >= 0) Undo(); + if (strcmp(s,"new") == 0) NewGame(); + if (strcmp(s,"list") == 0) ListGame(); + if (strcmp(s,"level") == 0) SelectLevel(); + if (strcmp(s,"hash") == 0) hashflag = !hashflag; + if (strcmp(s,"beep") == 0) beep = !beep; + if (strcmp(s,"Awindow") == 0) ChangeAlphaWindow(); + if (strcmp(s,"Bwindow") == 0) ChangeBetaWindow(); + if (strcmp(s,"hint") == 0) GiveHint(); + if (strcmp(s,"both") == 0) + { + bothsides = !bothsides; + Sdepth = 0; + SelectMove(opponent,1); + ok = true; + } + if (strcmp(s,"reverse") == 0) + { + reverse = !reverse; + ClrScreen(); + UpdateDisplay(0,0,1,0); + } + if (strcmp(s,"switch") == 0) + { + computer = otherside[computer]; + opponent = otherside[opponent]; + force = false; + Sdepth = 0; + ok = true; + } + if (strcmp(s,"white") == 0) + { + computer = white; opponent = black; + ok = true; force = false; + Sdepth = 0; + } + if (strcmp(s,"black") == 0) + { + computer = black; opponent = white; + ok = true; force = false; + Sdepth = 0; + } + if (strcmp(s,"remove") == 0 && GameCnt >= 1) + { + Undo(); Undo(); + } + if (strcmp(s,"get") == 0) GetGame(); + if (strcmp(s,"save") == 0) SaveGame(); + if (strcmp(s,"depth") == 0) ChangeSearchDepth(); + if (strcmp(s,"random") == 0) dither = 6; + if (strcmp(s,"easy") == 0) easy = !easy; + if (strcmp(s,"contempt") == 0) SetContempt(); + if (strcmp(s,"xwndw") == 0) ChangeXwindow(); + if (strcmp(s,"test") == 0) + { + t1 = time(0); + cnt = 0; + for (i = 0; i < 10000; i++) + { + MoveList(opponent,2); + cnt += TrPnt[3] - TrPnt[2]; + } + t2 = time(0); + rate = cnt / (t2-t1); + gotoXY(50,24); + printz("cnt= %ld rate= %ld",cnt,rate); + ClrEoln(); + } + if (strcmp(s,"p") == 0) ShowPostnValues(); + if (strcmp(s,"debug") == 0) DoDebug(); + } + + ClearMessage(); + ElapsedTime(1); + if (force) + { + computer = opponent; opponent = otherside[computer]; + } + (void) times(&tmbuf1); + signal(SIGINT,TerminateSearch); signal(SIGQUIT,TerminateSearch); +} + + +EditBoard() + +/* + Set up a board position. Pieces are entered by typing the piece + followed by the location. For example, Nf3 will place a knight on + square f3. +*/ + +{ +short a,r,c,sq; +char s[80]; + + ClrScreen(); + UpdateDisplay(0,0,1,0); + gotoXY(50,2); printz(". Exit to main"); + gotoXY(50,3); printz("# Clear board"); + gotoXY(49,5); printz("Enter piece & location: "); + a = white; + do + { + gotoXY(73,5); ClrEoln(); scanz("%s",s); + if (s[0] == '#') + { + for (sq = 0; sq < 64; sq++) + { + board[sq] = no_piece; color[sq] = neutral; + } + UpdateDisplay(0,0,1,0); + } + if (s[0] == 'c' || s[0] == 'C') a = otherside[a]; + c = s[1]-'a'; r = s[2]-'1'; + if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8)) + { + sq = locn[r][c]; + color[sq] = a; + if (s[0] == 'p') board[sq] = pawn; + else if (s[0] == 'n') board[sq] = knight; + else if (s[0] == 'b') board[sq] = bishop; + else if (s[0] == 'r') board[sq] = rook; + else if (s[0] == 'q') board[sq] = queen; + else if (s[0] == 'k') board[sq] = king; + else { board[sq] = no_piece; color[sq] = neutral; } + DrawPiece(sq); + } + } + while (s[0] != '.'); + if (board[4] != king) kingmoved[white] = 10; + if (board[60] != king) kingmoved[black] = 10; + GameCnt = -1; Game50 = 0; Sdepth = 0; + InitializeStats(); + ClrScreen(); + UpdateDisplay(0,0,1,0); +} + + +help() +{ + ClrScreen(); + gotoXY(28,1); printz("CHESS command summary"); + gotoXY(1,3); printz("g1f3 move from g1 to f3"); + gotoXY(1,4); printz("nf3 move knight to f3"); + gotoXY(1,5); printz("o-o castle king side"); + gotoXY(1,6); printz("o-o-o castle queen side"); + gotoXY(1,7); printz("edit edit board"); + gotoXY(1,8); printz("switch sides with computer"); + gotoXY(1,9); printz("white computer plays white"); + gotoXY(1,10); printz("black computer plays black"); + gotoXY(1,11); printz("reverse board display"); + gotoXY(1,12); printz("both computer match"); + gotoXY(1,13); printz("random randomize play"); + gotoXY(1,14); printz("undo undo last move"); + gotoXY(42,3); printz("level change level"); + gotoXY(42,4); printz("depth set search depth"); + gotoXY(42,5); printz("post principle variation"); + gotoXY(42,6); printz("hint suggest a move"); + gotoXY(42,7); printz("bd redraw board"); + gotoXY(42,8); printz("force enter game moves"); + gotoXY(42,9); printz("list game to chess.lst"); + gotoXY(42,10); printz("save game to file"); + gotoXY(42,11); printz("get game from file"); + gotoXY(42,12); printz("new start new game"); + gotoXY(42,13); printz("quit exit CHESS"); + gotoXY(10,21); printz("Computer: "); + if (computer == white) printz("WHITE"); else printz("BLACK"); + gotoXY(10,22); printz("Opponent: "); + if (opponent == white) printz("WHITE"); else printz("BLACK"); + gotoXY(10,23); printz("Level: %ld",Level," sec."); + gotoXY(10,24); printz("Easy mode: "); + if (easy) printz("ON"); else printz("OFF"); + gotoXY(40,21); printz("Depth: %d",MaxSearchDepth); + gotoXY(40,22); printz("Random: "); + if (dither) printz("ON"); else printz("OFF"); + gotoXY(40,23); printz("Transposition table: "); + if (hashflag) printz("ON"); else printz("OFF"); + refresh(); + while (getchar() != 27); + ClrScreen(); + UpdateDisplay(0,0,1,0); +} + + +ShowDepth(ch) +char ch; +{ + gotoXY(50,4); printz("Depth= %d%c ",Sdepth,ch); ClrEoln(); +} + + +ShowResults(score,bstline,ch) +short score; +unsigned short bstline[]; +char ch; +{ +short d,e,ply; + if (post && player == computer) + { + e = lpost; + gotoXY(50,5); printz("Score= %d",score); ClrEoln(); + d = 8; gotoXY(50,d); ClrEoln(); + for (ply = 1; bstline[ply] > 0; ply++) + { + algbr(bstline[ply] >> 8,bstline[ply] & 0xFF,false); + if (ply == 5 || ply == 9 || ply == 13 || ply == 17) + { + gotoXY(50,++d); ClrEoln(); + } + printz("%5s ",mvstr1); + } + ClrEoln(); + lpost = d; + while (++d <= e) + { + gotoXY(50,d); ClrEoln(); + } + } +} + + +SearchStartStuff(side) +short side; +{ +short i; + signal(SIGINT,TerminateSearch); signal(SIGQUIT,TerminateSearch); + if (player == computer) + for (i = 5; i < 14; i++) + { + gotoXY(50,i); ClrEoln(); + } +} + + +OutputMove() +{ + if (root->flags & epmask) UpdateDisplay(0,0,1,0); + else UpdateDisplay(root->f,root->t,0,root->flags & cstlmask); + gotoXY(50,17); printz("My move is: %s",mvstr1); + if (beep) putchar(7); + ClrEoln(); + + gotoXY(50,24); + if (root->flags & draw) printz("Draw game!"); + else if (root->score == -9999) printz("opponent mates!"); + else if (root->score == 9998) printz("computer mates!"); + else if (root->score < -9000) printz("opponent will soon mate!"); + else if (root->score > 9000) printz("computer will soon mate!"); + ClrEoln(); + + if (post) + { + gotoXY(50,22); printz("Nodes= %6ld",NodeCnt); ClrEoln(); + gotoXY(50,23); printz("Nodes/Sec= %4ld",evrate); ClrEoln(); + } +} + + +ElapsedTime(iop) + +/* + Determine the time that has passed since the search was started. If + the elapsed time exceeds the target (ResponseTime+ExtraTime) then set + timeout to true which will terminate the search. +*/ + +short iop; +{ + et = time((time_t *)0) - time0; + if (et < 0) et = 0; + ETnodes += 50; + if (et > et0 || iop == 1) + { + if (et > ResponseTime+ExtraTime && Sdepth > 1) timeout = true; + et0 = et; + if (iop == 1) + { + time0 = time((time_t *)0); et0 = 0; + } + (void) times(&tmbuf2); + cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ; + if (cputimer > 0) evrate = (100*NodeCnt)/(cputimer+100*ft); + else evrate = 0; + ETnodes = NodeCnt + 50; + UpdateClocks(); + } +} + + +UpdateClocks() +{ +short m,s; + m = et/60; s = (et - 60*m); + if (TCflag) + { + m = (TimeControl.clock[player] - et) / 60; + s = TimeControl.clock[player] - et - 60*m; + } + if (m < 0) m = 0; + if (s < 0) s = 0; + if (player == white) + if (reverse) gotoXY(20,2); else gotoXY(20,23); + else + if (reverse) gotoXY(20,23); else gotoXY(20,2); + printz("%d:%2d ",m,s); + if (post) + { + gotoXY(50,22); printz("Nodes= %6ld",NodeCnt); + gotoXY(50,23); printz("Nodes/Sec= %4ld",evrate); + } + refresh(); +} + + + +SetTimeControl() +{ + if (TCflag) + { + TimeControl.moves[white] = TimeControl.moves[black] = TCmoves; + TimeControl.clock[white] = TimeControl.clock[black] = 60*(long)TCminutes; + } + else + { + TimeControl.moves[white] = TimeControl.moves[black] = 0; + TimeControl.clock[white] = TimeControl.clock[black] = 0; + Level = 60*(long)TCminutes; + } + et = 0; + ElapsedTime(1); +} + + +gotoXY(x,y) +short x,y; +{ + move(y-1,x-1); +} + + +ClrScreen() +{ + clear(); refresh(); +} + + +ClrEoln() +{ + clrtoeol(); refresh(); +} + + +DrawPiece(sq) +short sq; +{ +short r,c; char x; + if (reverse) r = 7-row[sq]; else r = row[sq]; + if (reverse) c = 7-column[sq]; else c = column[sq]; + if (color[sq] == black) x = '*'; else x = ' '; + gotoXY(5+5*c,5+2*(7-r)); printz("%c%c ",x,pxx[board[sq]]); +} + + +UpdateDisplay(f,t,flag,iscastle) +short f,t,flag,iscastle; +{ +short i,l,z; + if (flag) + { + gotoXY(56,2); printz("CHESS"); + i = 3; + gotoXY(3,++i); + printz("|----|----|----|----|----|----|----|----|"); + while (i<19) + { + gotoXY(1,++i); + if (reverse) z = (i/2)-1; else z = 10-(i/2); + printz("%d | | | | | | | | |",z); + gotoXY(3,++i); + if (i < 19) + printz("+----+----+----+----+----+----+----+----+"); + } + printz("|----|----|----|----|----|----|----|----|"); + gotoXY(3,21); + if (reverse) printz(" h g f e d c b a"); + else printz(" a b c d e f g h"); + if (reverse) gotoXY(5,23); else gotoXY(5,2); + if (computer == black) printz("Computer"); else printz("Human "); + if (reverse) gotoXY(5,2); else gotoXY(5,23); + if (computer == white) printz("Computer"); else printz("Human "); + for (l = 0; l < 64; l++) DrawPiece(l); + } + else + { + DrawPiece(f); DrawPiece(t); + if (iscastle) + if (t > f) + { DrawPiece(f+3); DrawPiece(t-1); } + else + { DrawPiece(f-4); DrawPiece(t+1); } + } + refresh(); +} + + +GetOpenings() + +/* + Read in the Opening Book file and parse the algebraic notation for a + move into an unsigned integer format indicating the from and to + square. Create a linked list of opening lines of play, with + entry->next pointing to the next line and entry->move pointing to a + chunk of memory containing the moves. More Opening lines of up to 256 + half moves may be added to gnuchess.book. +*/ + +{ +FILE *fd; +int c,i,j,side; +struct BookEntry *entry; +unsigned short mv,*mp,tmp[100]; + + if ((fd = fopen(_PATH_CHESSBOOK,"r")) != NULL) + { + Book = NULL; + i = 0; side = white; + while ((c = parse(fd,&mv,side)) >= 0) + if (c == 1) + { + tmp[++i] = mv; + side = otherside[side]; + } + else if (c == 0 && i > 0) + { + entry = (struct BookEntry *)malloc(sizeof(struct BookEntry)); + mp = (unsigned short *)malloc((i+1)*sizeof(unsigned short)); + entry->mv = mp; + entry->next = Book; + Book = entry; + for (j = 1; j <= i; j++) *(mp++) = tmp[j]; + *mp = 0; + i = 0; side = white; + } + fclose(fd); + } + else + { + fprintf(stderr, "\nchess: can't read %s.\n", _PATH_CHESSBOOK); + exit(1); + } +} + + +int parse(fd,mv,side) +FILE *fd; +unsigned short *mv; +short side; +{ +int c,i,r1,r2,c1,c2; +char s[100]; + while ((c = getc(fd)) == ' '); + i = 0; s[0] = c; + while (c != ' ' && c != '\n' && c != EOF) s[++i] = c = getc(fd); + s[++i] = '\0'; + if (c == EOF) return(-1); + if (s[0] == '!' || i < 3) + { + while (c != '\n' && c != EOF) c = getc(fd); + return(0); + } + if (s[4] == 'o') + if (side == black) *mv = 0x3C3A; else *mv = 0x0402; + else if (s[0] == 'o') + if (side == black) *mv = 0x3C3E; else *mv = 0x0406; + else + { + c1 = s[0] - 'a'; r1 = s[1] - '1'; + c2 = s[2] - 'a'; r2 = s[3] - '1'; + *mv = (locn[r1][c1]<<8) + locn[r2][c2]; + } + return(1); +} + + +GetGame() +{ +FILE *fd; +char fname[40]; +int c; +short sq; +unsigned short m; + + ShowMessage("File name: "); + scanz("%s",fname); + if (fname[0] == '\0') strcpy(fname,"chess.000"); + if ((fd = fopen(fname,"r")) != NULL) + { + fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50); + fscanf(fd,"%hd%hd%hd%hd", + &castld[white],&castld[black], + &kingmoved[white],&kingmoved[black]); + fscanf(fd,"%hd%hd",&TCflag,&OperatorTime); + fscanf(fd,"%ld%ld%hd%hd", + &TimeControl.clock[white],&TimeControl.clock[black], + &TimeControl.moves[white],&TimeControl.moves[black]); + for (sq = 0; sq < 64; sq++) + { + fscanf(fd,"%hd",&m); + board[sq] = (m >> 8); color[sq] = (m & 0xFF); + if (color[sq] == 0) color[sq] = neutral; else --color[sq]; + } + GameCnt = -1; c = '?'; + while (c != EOF) + { + ++GameCnt; + c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove, + &GameList[GameCnt].score,&GameList[GameCnt].depth, + &GameList[GameCnt].nodes,&GameList[GameCnt].time, + &GameList[GameCnt].piece,&GameList[GameCnt].color); + if (GameList[GameCnt].color == 0) GameList[GameCnt].color = neutral; + else --GameList[GameCnt].color; + } + GameCnt--; + if (TimeControl.clock[white] > 0) TCflag = true; + computer--; opponent--; + } + fclose(fd); + InitializeStats(); + UpdateDisplay(0,0,1,0); + Sdepth = 0; +} + + +SaveGame() +{ +FILE *fd; +char fname[40]; +short sq,i,c; + + ShowMessage("File name: "); + scanz("%s",fname); + + if (fname[0] == '\0' || access(fname,W_OK) == -1) strcpy(fname,"chess.000"); + fd = fopen(fname,"w"); + fprintf(fd,"%d %d %d\n",computer+1,opponent+1,Game50); + fprintf(fd,"%d %d %d %d\n", + castld[white],castld[black],kingmoved[white],kingmoved[black]); + fprintf(fd,"%d %d\n",TCflag,OperatorTime); + fprintf(fd,"%ld %ld %d %d\n", + TimeControl.clock[white],TimeControl.clock[black], + TimeControl.moves[white],TimeControl.moves[black]); + for (sq = 0; sq < 64; sq++) + { + if (color[sq] == neutral) c = 0; else c = color[sq]+1; + fprintf(fd,"%d\n",256*board[sq] + c); + } + for (i = 0; i <= GameCnt; i++) + { + if (GameList[i].color == neutral) c = 0; + else c = GameList[i].color + 1; + fprintf(fd,"%d %d %d %ld %d %d %d\n", + GameList[i].gmove,GameList[i].score,GameList[i].depth, + GameList[i].nodes,GameList[i].time, + GameList[i].piece,c); + } + fclose(fd); +} + + +ListGame() +{ +FILE *fd; +short i,f,t; + fd = fopen("chess.lst","w"); + fprintf(fd,"\n"); + fprintf(fd," score depth nodes time "); + fprintf(fd," score depth nodes time\n"); + for (i = 0; i <= GameCnt; i++) + { + f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF); + algbr(f,t,false); + if ((i % 2) == 0) fprintf(fd,"\n"); else fprintf(fd," "); + fprintf(fd,"%5s %5d %2d %6ld %5d",mvstr1, + GameList[i].score,GameList[i].depth, + GameList[i].nodes,GameList[i].time); + } + fprintf(fd,"\n\n"); + fclose(fd); +} + + +Undo() + +/* + Undo the most recent half-move. +*/ + +{ +short f,t; + f = GameList[GameCnt].gmove>>8; + t = GameList[GameCnt].gmove & 0xFF; + if (board[t] == king && distance(t,f) > 1) + castle(GameList[GameCnt].color,f,t,2); + else + { + board[f] = board[t]; color[f] = color[t]; + board[t] = GameList[GameCnt].piece; + color[t] = GameList[GameCnt].color; + if (board[f] == king) --kingmoved[color[f]]; + } + if (TCflag) ++TimeControl.moves[color[f]]; + GameCnt--; mate = false; Sdepth = 0; + UpdateDisplay(0,0,1,0); + InitializeStats(); +} + + +ShowMessage(s) +char *s; +{ + gotoXY(50,24); printz("%s",s); ClrEoln(); +} + +ClearMessage() +{ + gotoXY(50,24); ClrEoln(); +} + +ShowSidetomove() +{ + gotoXY(50,14); + if (player == white) printz("%2d: WHITE",1+(GameCnt+1)/2); + else printz("%2d: BLACK",1+(GameCnt+1)/2); + ClrEoln(); +} + +PromptForMove() +{ + gotoXY(50,19); printz("Your move is? "); ClrEoln(); +} + +ShowCurrentMove(pnt,f,t) +short pnt,f,t; +{ + algbr(f,t,false); + gotoXY(50,7); printz("(%2d) %4s",pnt,mvstr1); +} + +ChangeAlphaWindow() +{ + ShowMessage("window: "); + scanz("%hd",&Awindow); +} + +ChangeBetaWindow() +{ + ShowMessage("window: "); + scanz("%hd",&Bwindow); +} + +GiveHint() +{ +char s[40]; + algbr((short)(hint>>8),(short)(hint & 0xFF),false); + strcpy(s,"try "); + strcat(s,mvstr1); + ShowMessage(s); +} + +ChangeSearchDepth() +{ + ShowMessage("depth= "); + scanz("%hd",&MaxSearchDepth); +} + +SetContempt() +{ + ShowMessage("contempt= "); + scanz("%hd",&contempt); +} + +ChangeXwindow() +{ + ShowMessage("xwndw= "); + scanz("%hd",&xwndw); +} + + +SelectLevel() +{ + ClrScreen(); + gotoXY(32,2); printz("CHESS"); + gotoXY(20,4); printz(" 1. 60 moves in 5 minutes"); + gotoXY(20,5); printz(" 2. 60 moves in 15 minutes"); + gotoXY(20,6); printz(" 3. 60 moves in 30 minutes"); + gotoXY(20,7); printz(" 4. 40 moves in 30 minutes"); + gotoXY(20,8); printz(" 5. 40 moves in 60 minutes"); + gotoXY(20,9); printz(" 6. 40 moves in 120 minutes"); + gotoXY(20,10); printz(" 7. 40 moves in 240 minutes"); + gotoXY(20,11); printz(" 8. 1 move in 15 minutes"); + gotoXY(20,12); printz(" 9. 1 move in 60 minutes"); + gotoXY(20,13); printz("10. 1 move in 600 minutes"); + + OperatorTime = 0; TCmoves = 60; TCminutes = 5; + + gotoXY(20,17); printz("Enter Level: "); + refresh(); + scanz("%ld",&Level); + switch (Level) + { + case 1 : TCmoves = 60; TCminutes = 5; break; + case 2 : TCmoves = 60; TCminutes = 15; break; + case 3 : TCmoves = 60; TCminutes = 30; break; + case 4 : TCmoves = 40; TCminutes = 30; break; + case 5 : TCmoves = 40; TCminutes = 60; break; + case 6 : TCmoves = 40; TCminutes = 120; break; + case 7 : TCmoves = 40; TCminutes = 240; break; + case 8 : TCmoves = 1; TCminutes = 15; break; + case 9 : TCmoves = 1; TCminutes = 60; break; + case 10 : TCmoves = 1; TCminutes = 600; break; + } + + TCflag = (TCmoves > 1); + SetTimeControl(); + ClrScreen(); + UpdateDisplay(0,0,1,0); +} + + +ShowPostnValues() +{ +short i,r,c; + ExaminePosition(); + for (i = 0; i < 64; i++) + { + if (reverse) r = 7-row[i]; else r = row[i]; + if (reverse) c = 7-column[i]; else c = column[i]; + gotoXY(4+5*c,5+2*(7-r)); + c1 = color[i]; c2 = otherside[c1]; + PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2]; + atk1 = atak[c1]; atk2 = atak[c2]; + if (color[i] == neutral) printz(" "); + else printz("%3d ",SqValue(i,opponent)); + } + ScorePosition(opponent,&i); + gotoXY(50,24); + printz("Score= %d",i); ClrEoln(); +} + + +DoDebug() +{ +short k,p,i,r,c,tp,tc; +char s[40]; + ExaminePosition(); + ShowMessage("Enter piece: "); + scanz("%s",s); + if (s[0] == 'w') k = white; else k = black; + if (s[1] == 'p') p = pawn; + else if (s[1] == 'n') p = knight; + else if (s[1] == 'b') p = bishop; + else if (s[1] == 'r') p = rook; + else if (s[1] == 'q') p = queen; + else if (s[1] == 'k') p = king; + else p = no_piece; + for (i = 0; i < 64; i++) + { + if (reverse) r = 7-row[i]; else r = row[i]; + if (reverse) c = 7-column[i]; else c = column[i]; + gotoXY(4+5*c,5+2*(7-r)); + tp = board[i]; tc = color[i]; + board[i] = p; color[i] = k; + c1 = k; c2 = otherside[c1]; + PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2]; + atk1 = atak[c1]; atk2 = atak[c2]; + printz("%3d ",SqValue(i,opponent)); + board[i] = tp; color[i] = tc; + } + ScorePosition(opponent,&i); + gotoXY(50,24); + printz("Score= %d",i); ClrEoln(); +} |