]> git.sesse.net Git - pgn-extract/commitdiff
Import pgn-extract 17-19.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 10 Dec 2014 23:16:07 +0000 (00:16 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 10 Dec 2014 23:16:07 +0000 (00:16 +0100)
174 files changed:
COPYING [new file with mode: 0644]
Makefile [new file with mode: 0644]
apply.c [new file with mode: 0644]
apply.h [new file with mode: 0644]
argsfile.c [new file with mode: 0644]
argsfile.h [new file with mode: 0644]
bool.h [new file with mode: 0644]
decode.c [new file with mode: 0644]
decode.h [new file with mode: 0644]
defs.h [new file with mode: 0644]
eco.c [new file with mode: 0644]
eco.h [new file with mode: 0644]
eco.pgn [new file with mode: 0644]
end.c [new file with mode: 0644]
end.h [new file with mode: 0644]
fenmatcher.c [new file with mode: 0644]
fenmatcher.h [new file with mode: 0644]
grammar.c [new file with mode: 0644]
grammar.h [new file with mode: 0644]
hashing.c [new file with mode: 0644]
hashing.h [new file with mode: 0644]
help.html [new file with mode: 0644]
index.html [new file with mode: 0644]
lex.c [new file with mode: 0644]
lex.h [new file with mode: 0644]
lines.c [new file with mode: 0644]
lines.h [new file with mode: 0644]
lists.c [new file with mode: 0644]
lists.h [new file with mode: 0644]
main.c [new file with mode: 0644]
map.c [new file with mode: 0644]
map.h [new file with mode: 0644]
moves.c [new file with mode: 0644]
moves.h [new file with mode: 0644]
mymalloc.c [new file with mode: 0644]
mymalloc.h [new file with mode: 0644]
output.c [new file with mode: 0644]
output.h [new file with mode: 0644]
pgn-extract.xml [new file with mode: 0644]
style.css [new file with mode: 0755]
taglines.c [new file with mode: 0644]
taglines.h [new file with mode: 0644]
taglist.h [new file with mode: 0644]
test/Makefile [new file with mode: 0644]
test/infiles/Pvars.txt [new file with mode: 0644]
test/infiles/alg.txt [new file with mode: 0644]
test/infiles/argslist.txt [new file with mode: 0644]
test/infiles/barnes-horton.pgn [new file with mode: 0644]
test/infiles/clist.txt [new file with mode: 0644]
test/infiles/files.txt [new file with mode: 0644]
test/infiles/fischer.pgn [new file with mode: 0644]
test/infiles/fools-mate.pgn [new file with mode: 0644]
test/infiles/fools-mate.txt [new file with mode: 0644]
test/infiles/najdorf.pgn [new file with mode: 0644]
test/infiles/petrosian.pgn [new file with mode: 0644]
test/infiles/roster.txt [new file with mode: 0644]
test/infiles/taglist.txt [new file with mode: 0644]
test/infiles/test-7.pgn [new file with mode: 0644]
test/infiles/test-C.pgn [new file with mode: 0644]
test/infiles/test-F.pgn [new file with mode: 0644]
test/infiles/test-L1.pgn [new file with mode: 0644]
test/infiles/test-L2.pgn [new file with mode: 0644]
test/infiles/test-N.pgn [new file with mode: 0644]
test/infiles/test-P.pgn [new file with mode: 0644]
test/infiles/test-R.pgn [new file with mode: 0644]
test/infiles/test-S.pgn [new file with mode: 0644]
test/infiles/test-Ta.pgn [new file with mode: 0644]
test/infiles/test-V.pgn [new file with mode: 0644]
test/infiles/test-W.pgn [new file with mode: 0644]
test/infiles/test-a.txt [new file with mode: 0644]
test/infiles/test-addhashcode.pgn [new file with mode: 0644]
test/infiles/test-checkmate.pgn [new file with mode: 0644]
test/infiles/test-e.pgn [new file with mode: 0644]
test/infiles/test-evaluation.pgn [new file with mode: 0644]
test/infiles/test-f1.pgn [new file with mode: 0644]
test/infiles/test-f2.pgn [new file with mode: 0644]
test/infiles/test-fencomments.pgn [new file with mode: 0644]
test/infiles/test-hash.pgn [new file with mode: 0644]
test/infiles/test-long-line.pgn [new file with mode: 0644]
test/infiles/test-nochecks.pgn [new file with mode: 0644]
test/infiles/test-nomovenumbers.pgn [new file with mode: 0644]
test/infiles/test-noresults.pgn [new file with mode: 0644]
test/infiles/test-notags.pgn [new file with mode: 0644]
test/infiles/test-o.txt [new file with mode: 0644]
test/infiles/test-plylimit.pgn [new file with mode: 0644]
test/infiles/test-r.txt [new file with mode: 0644]
test/infiles/test-selectonly.pgn [new file with mode: 0644]
test/infiles/test-stalemate.pgn [new file with mode: 0644]
test/infiles/test-t.pgn [new file with mode: 0644]
test/infiles/test-totalplycount.pgn [new file with mode: 0644]
test/infiles/vvars.txt [new file with mode: 0644]
test/infiles/xvars.txt [new file with mode: 0644]
test/infiles/zmatch.txt [new file with mode: 0644]
test/outfiles/1.pgn [new file with mode: 0644]
test/outfiles/2.pgn [new file with mode: 0644]
test/outfiles/A.pgn [new file with mode: 0644]
test/outfiles/B.pgn [new file with mode: 0644]
test/outfiles/E.pgn [new file with mode: 0644]
test/outfiles/LLog.txt [new file with mode: 0644]
test/outfiles/fischer-b30-out.pgn [new file with mode: 0644]
test/outfiles/fischer-bl45-out.pgn [new file with mode: 0644]
test/outfiles/fischer-bu45-out.pgn [new file with mode: 0644]
test/outfiles/log.txt [new file with mode: 0644]
test/outfiles/test-7-out.pgn [new file with mode: 0644]
test/outfiles/test-AA-dupes.pgn [new file with mode: 0644]
test/outfiles/test-AA-unique.pgn [new file with mode: 0644]
test/outfiles/test-CC-out.pgn [new file with mode: 0644]
test/outfiles/test-DD-unique.pgn [new file with mode: 0644]
test/outfiles/test-FF-out.pgn [new file with mode: 0644]
test/outfiles/test-NN-out.pgn [new file with mode: 0644]
test/outfiles/test-PP-out.pgn [new file with mode: 0644]
test/outfiles/test-RR-out.pgn [new file with mode: 0644]
test/outfiles/test-SS-out.pgn [new file with mode: 0644]
test/outfiles/test-TTa-out.pgn [new file with mode: 0644]
test/outfiles/test-TTb-out.pgn [new file with mode: 0644]
test/outfiles/test-TTd-out.pgn [new file with mode: 0644]
test/outfiles/test-TTdd-out.pgn [new file with mode: 0644]
test/outfiles/test-TTp-out.pgn [new file with mode: 0644]
test/outfiles/test-TTr-out.pgn [new file with mode: 0644]
test/outfiles/test-TTw-out.pgn [new file with mode: 0644]
test/outfiles/test-UU-unique.pgn [new file with mode: 0644]
test/outfiles/test-VV-out.pgn [new file with mode: 0644]
test/outfiles/test-WWdeutsch-out.pgn [new file with mode: 0644]
test/outfiles/test-WWelalg-out.pgn [new file with mode: 0644]
test/outfiles/test-WWhalg-out.pgn [new file with mode: 0644]
test/outfiles/test-WWlalg-out.pgn [new file with mode: 0644]
test/outfiles/test-WWuci-out.pgn [new file with mode: 0644]
test/outfiles/test-Wdeutsch-out.pgn [new file with mode: 0644]
test/outfiles/test-Welalg-out.pgn [new file with mode: 0644]
test/outfiles/test-Whalg-out.pgn [new file with mode: 0644]
test/outfiles/test-Wlalg-out.pgn [new file with mode: 0644]
test/outfiles/test-ZZ-dupes.pgn [new file with mode: 0644]
test/outfiles/test-ZZ-unique.pgn [new file with mode: 0644]
test/outfiles/test-a-out.pgn [new file with mode: 0644]
test/outfiles/test-addhashcode-out.pgn [new file with mode: 0644]
test/outfiles/test-b30-out.pgn [new file with mode: 0644]
test/outfiles/test-bl45-out.pgn [new file with mode: 0644]
test/outfiles/test-bu45-out.pgn [new file with mode: 0644]
test/outfiles/test-c-out.pgn [new file with mode: 0644]
test/outfiles/test-checkmate-out.pgn [new file with mode: 0644]
test/outfiles/test-d-dupes.pgn [new file with mode: 0644]
test/outfiles/test-d-unique.pgn [new file with mode: 0644]
test/outfiles/test-e-out.pgn [new file with mode: 0644]
test/outfiles/test-evaluation-out.pgn [new file with mode: 0644]
test/outfiles/test-f-out.pgn [new file with mode: 0644]
test/outfiles/test-fencomments-out.pgn [new file with mode: 0644]
test/outfiles/test-l-out.pgn [new file with mode: 0644]
test/outfiles/test-long-line-log.txt [new file with mode: 0644]
test/outfiles/test-long-line-out.pgn [new file with mode: 0644]
test/outfiles/test-markmatches-out.pgn [new file with mode: 0644]
test/outfiles/test-n-matched.pgn [new file with mode: 0644]
test/outfiles/test-n-unmatched.pgn [new file with mode: 0644]
test/outfiles/test-nochecks-out.pgn [new file with mode: 0644]
test/outfiles/test-nomovenumbers-out.pgn [new file with mode: 0644]
test/outfiles/test-noresults-out.pgn [new file with mode: 0644]
test/outfiles/test-notags-out.pgn [new file with mode: 0644]
test/outfiles/test-o-out.pgn [new file with mode: 0644]
test/outfiles/test-plylimit-out.pgn [new file with mode: 0644]
test/outfiles/test-r-log.txt [new file with mode: 0644]
test/outfiles/test-s-out.pgn [new file with mode: 0644]
test/outfiles/test-selectonly-out.pgn [new file with mode: 0644]
test/outfiles/test-stalemate-out.pgn [new file with mode: 0644]
test/outfiles/test-t-out.pgn [new file with mode: 0644]
test/outfiles/test-totalplycount-out.pgn [new file with mode: 0644]
test/outfiles/test-v-out.pgn [new file with mode: 0644]
test/outfiles/test-w1000-out.pgn [new file with mode: 0644]
test/outfiles/test-w60-out.pgn [new file with mode: 0644]
test/outfiles/test-w75-out.pgn [new file with mode: 0644]
test/outfiles/test-x-out.pgn [new file with mode: 0644]
test/outfiles/test-z-out.pgn [new file with mode: 0644]
test/runtests [new file with mode: 0755]
test/tests.txt [new file with mode: 0644]
tokens.h [new file with mode: 0644]
typedef.h [new file with mode: 0644]

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..9a17037
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,249 @@
+
+                   GNU GENERAL PUBLIC LICENSE
+                    Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+                    675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The license agreements of most software companies try to keep users
+at the mercy of those companies.  By contrast, our General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of a such a program, whether
+gratis or for a fee, 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.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License.  The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications.  Each
+licensee is addressed as "you".
+
+  1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program.  You may charge a fee for the physical act of
+transferring a copy.
+
+  2. You may modify your copy or copies of the Program 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 that
+    you changed the 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 the Program or any part thereof, either
+    with or without modifications, to be licensed at no charge to all
+    third parties under the terms of this General Public License (except
+    that you may choose to grant warranty protection to some or all
+    third parties, at your option).
+
+    c) If the modified program normally reads commands interactively when
+    run, you must cause it, when started running for such interactive use
+    in the simplest and most usual way, to print or display an
+    announcement including an appropriate copyright notice and a notice
+    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 General
+    Public License.
+
+    d) You may charge a fee for the physical act of transferring a
+    copy, and you may at your option offer warranty protection in
+    exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+\f
+  3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+    a) accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    b) accompany it with a written offer, valid for at least three
+    years, to give any third party free (except for a nominal charge
+    for the cost of distribution) a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    c) accompany it with the information you received as to where the
+    corresponding source code may be obtained.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it.  For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+  4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License.  However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+  5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions.  You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
+\f
+  7. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of the license which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+  8. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "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
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+       Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to humanity, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+  To do so, attach the following notices to the program.  It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 1, or (at your option)
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19xx name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License.  Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  program `Gnomovision' (a program to direct compilers to make passes
+  at assemblers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..da88bf5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,125 @@
+# Make file for the pgn-extract program.
+#    Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+#    Copyright (C) 1994-2014 David Barnes
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 1, or (at your option)
+#    any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#    David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+#    http://www.cs.kent.ac.uk/people/staff/djb/
+
+OBJS=grammar.o lex.o map.o decode.o moves.o lists.o apply.o output.o eco.o\
+       lines.o end.o main.o hashing.o argsfile.o mymalloc.o fenmatcher.o\
+       taglines.o
+DEBUGINFO=-g
+
+# These flags are particularly severe on checking warnings.
+# It may be that they are not all appropriate to your environment.
+# For instance, not all environments have prototypes available for
+# the standard library functions.
+
+# Linux users might need to add -D__linux__ to these in order to
+# use strcasecmp instead of strcmpi (cf output.c)
+
+# Mac OS X users might need to add -D__unix__ to CFLAGS
+# and use CC=cc or CC=gcc
+
+CFLAGS+=-c -pedantic -Wall -Wshadow -Wformat -Wpointer-arith \
+       -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings \
+       -Wsign-compare $(DEBUGINFO)\
+       -I/usr/local/lib/ansi-include \
+       -O3
+CC=gcc
+
+# AIX 3.2 Users might like to use these alternatives for CFLAGS and CC.
+# Thanks to Erol Basturk for providing them.
+AIX_CFLAGS=-c -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_ALL_SOURCE
+AIX_CC=xlc
+
+pgn-extract : $(OBJS)
+       $(CC) $(DEBUGINFO) $(OBJS) -o pgn-extract
+
+purify : $(OBJS)
+       purify $(CC) $(DEBUGINFO) $(OBJS) -o pgn-extract
+
+clean:
+       rm -f core pgn-extract *.o
+
+mymalloc.o : mymalloc.c mymalloc.h
+       $(CC) $(CFLAGS) mymalloc.c
+
+apply.o :  apply.c defs.h lex.h grammar.h typedef.h map.h bool.h apply.h taglist.h\
+          eco.h decode.h moves.h hashing.h mymalloc.h output.h fenmatcher.h
+       $(CC) $(CFLAGS) apply.c
+
+argsfile.o : argsfile.c argsfile.h bool.h defs.h typedef.h lines.h \
+               taglist.h tokens.h lex.h taglines.h moves.h eco.h apply.h output.h \
+               lists.h mymalloc.h
+       $(CC) $(CFLAGS) argsfile.c
+
+decode.o : decode.c defs.h typedef.h taglist.h lex.h bool.h decode.h lists.h \
+            tokens.h mymalloc.h
+       $(CC) $(CFLAGS) decode.c
+
+eco.o :  eco.c defs.h lex.h typedef.h map.h bool.h eco.h taglist.h apply.h \
+           mymalloc.h
+       $(CC) $(CFLAGS) eco.c
+
+end.o : end.c end.h bool.h defs.h typedef.h lines.h tokens.h lex.h mymalloc.h \
+        apply.h grammar.h
+       $(CC) $(CFLAGS) end.c
+
+grammar.o : grammar.c bool.h defs.h typedef.h lex.h taglist.h map.h lists.h\
+           moves.h apply.h output.h tokens.h eco.h end.h grammar.h hashing.h \
+           mymalloc.h
+       $(CC) $(CFLAGS) grammar.c
+
+hashing.o : hashing.c hashing.h bool.h defs.h typedef.h tokens.h\
+               taglist.h lex.h mymalloc.h
+       $(CC) $(CFLAGS) hashing.c
+
+lex.o : lex.c bool.h defs.h typedef.h tokens.h taglist.h map.h\
+       lists.h decode.h moves.h lines.h grammar.h mymalloc.h apply.h\
+       output.h
+       $(CC) $(CFLAGS) lex.c
+
+lines.o : lines.c bool.h lines.h mymalloc.h
+       $(CC) $(CFLAGS) lines.c
+
+lists.o :  lists.c lists.h taglist.h bool.h defs.h typedef.h mymalloc.h
+       $(CC) $(CFLAGS) lists.c
+
+main.o : main.c bool.h defs.h typedef.h tokens.h taglist.h lex.h moves.h\
+          map.h lists.h output.h end.h grammar.h hashing.h \
+          argsfile.h mymalloc.h
+       $(CC) $(CFLAGS) main.c
+
+map.o :  map.c defs.h lex.h typedef.h map.h bool.h decode.h taglist.h \
+         mymalloc.h
+       $(CC) $(CFLAGS) map.c
+
+moves.o :  moves.c defs.h typedef.h lex.h bool.h map.h lists.h moves.h apply.h\
+          lines.h taglist.h mymalloc.h fenmatcher.h
+       $(CC) $(CFLAGS) moves.c
+
+fenmatcher.o : fenmatcher.c apply.h bool.h defs.h fenmatcher.h mymalloc.h typedef.h
+       $(CC) $(CFLAGS) fenmatcher.c
+
+output.o :  output.c output.h taglist.h bool.h typedef.h defs.h lex.h grammar.h\
+           apply.h mymalloc.h
+       $(CC) $(CFLAGS) output.c
+
+taglines.o : taglines.c bool.h defs.h typedef.h tokens.h taglist.h lex.h lines.h \
+             lists.h moves.h output.h taglines.h
+       $(CC) $(CFLAGS) taglines.c
+
diff --git a/apply.c b/apply.c
new file mode 100644 (file)
index 0000000..53118d2
--- /dev/null
+++ b/apply.c
@@ -0,0 +1,1945 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "map.h"
+#include "apply.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "output.h"
+#include "lex.h"
+#include "grammar.h"
+#include "moves.h"
+#include "eco.h"
+#include "decode.h"
+#include "hashing.h"
+#include "fenmatcher.h"
+
+/* Define a positional search depth that should look at the
+ * full length of a game.  This is used in play_moves().
+ */
+#define DEFAULT_POSITIONAL_DEPTH 300
+
+        /* Prototypes of functions limited to this file. */
+static Boolean position_matches(const Board *board);
+static Boolean play_moves(Game *game_details, Board *board, Move *moves,
+                unsigned max_depth, Boolean check_move_validity);
+static Boolean apply_variations(const Game *game_details,const Board *board,
+                                Variation *variation, Boolean check_move_validity);
+static Boolean rewrite_variations(const Board *board,Variation *variation, Boolean null_move_found);
+static Boolean rewrite_moves(Board *board, Move *move_details, Boolean null_move_found);
+static void append_evaluation(Move *move_details, const Board *board);
+static void append_FEN_comment(Move *move_details, const Board *board);
+static double evaluate(const Board *board);
+static double shannonEvaluation(const Board *board);
+
+        /* The English SAN piece characters. These are
+         * always used when building a FEN string, rather
+         * than using any language-dependent user settings.
+         */
+static char SAN_piece_characters[NUM_PIECE_VALUES] = {
+    '?', '?', 
+    'P', 'N', 'B', 'R', 'Q', 'K'
+};
+
+
+    /* These letters may be changed via a call to set_output_piece_characters
+     * with a string of the form "PNBRQK".
+     * This would normally be done with the -Wsan argument.
+     */
+static const char *output_piece_characters[NUM_PIECE_VALUES] = {
+    "?", "?", 
+    "P", "N", "B", "R", "Q", "K"
+};
+
+    /* letters should contain a string of the form: "PNBRQK" */
+void set_output_piece_characters(const char *letters)
+{
+    if(letters == NULL){
+        fprintf(GlobalState.logfile,
+                "NULL string passed to set_output_piece_characters.\n");
+    }
+    else{
+        Piece piece;
+        int piece_index;
+        for(piece_index = 0, piece = PAWN; piece <= KING &&
+                                           letters[piece_index] != '\0'; piece++){
+            /* Check whether we have a single character piece, 
+             * or one of the form X+Y, where the piece is represented
+             * by the combination XY.
+             */
+            if(letters[piece_index+1] == '+'){
+                /* A two-char piece. */
+                static char double_char_piece[] = "XY";
+                double_char_piece[0] = letters[piece_index];
+                piece_index++;
+                /* Skip the plus. */
+                piece_index++;
+                if(letters[piece_index] != '\0'){
+                    double_char_piece[1] = letters[piece_index];
+                    output_piece_characters[piece] = copy_string(double_char_piece);
+                    piece_index++;
+                }
+                else{
+                    fprintf(GlobalState.logfile,
+                            "Missing piece letter following + in -Wsan%s.\n",
+                            letters);
+                    exit(1);
+                }
+            }
+            else{
+                static char single_char_piece[] = "X";
+                *single_char_piece = letters[piece_index];
+                output_piece_characters[piece] = copy_string(single_char_piece);
+                piece_index++;
+            }
+        }
+        if(piece < NUM_PIECE_VALUES){
+            fprintf(GlobalState.logfile,
+                    "Insufficient piece letters found with -Wsan%s.\n",
+                    letters);
+            fprintf(GlobalState.logfile,
+                    "The argument should be of the form -Wsan%s.\n",
+                    "PNBRQK");
+            exit(1);
+        }
+        else if(letters[piece_index] != '\0'){
+            fprintf(GlobalState.logfile,
+                    "Too many piece letters found with -Wsan%s.\n",
+                    letters);
+            fprintf(GlobalState.logfile,
+                    "The argument should be of the form -Wsan%s.\n",
+                    "PNBRQK");
+            exit(1);
+        }
+        else{
+            /* Ok. */
+        }
+    }
+}
+
+      /* Return a fresh copy of the given string. */
+char *
+copy_string(const char *str)
+{   char *result;
+    size_t len = strlen(str);
+
+    result = MallocOrDie(len+1);
+    strcpy(result,str);
+    return result;
+}
+
+        /* Allocate space for a new board. */
+static Board *
+allocate_new_board(void)
+{   
+    return (Board *) MallocOrDie(sizeof(Board));
+}
+
+        /* Free the board space. */
+static void
+free_board(Board *board)
+{
+    (void) free((void *)board);
+}
+
+static Piece
+is_FEN_piece(char c)
+{   Piece piece = EMPTY;
+
+    switch(c){
+        case 'K': case 'k':
+            piece = KING;
+            break;
+        case 'Q': case 'q':
+            piece = QUEEN;
+            break;
+        case 'R': case 'r':
+            piece = ROOK;
+            break;
+        case 'N': case 'n':
+            piece = KNIGHT;
+            break;
+        case 'B': case 'b':
+            piece = BISHOP;
+            break;
+        case 'P': case 'p':
+            piece = PAWN;
+            break;
+    }
+    return piece;
+}
+
+        /* Return the SAN letter associated with the given piece. */
+char
+SAN_piece_letter(Piece piece)
+{
+    if(piece < NUM_PIECE_VALUES){
+        return SAN_piece_characters[piece];
+    }
+    else{
+        return '?';
+    }
+}
+
+        /* Return the SAN letter for the given Piece. */
+char
+coloured_piece_to_SAN_letter(Piece coloured_piece)
+{   Piece piece = EXTRACT_PIECE(coloured_piece);
+    char letter = SAN_piece_letter(piece);
+    if(EXTRACT_COLOUR(coloured_piece) == BLACK){
+        letter = tolower(letter);
+    }
+    return letter;
+}
+
+        /* Set up the board from the FEN string passed as
+         * argument.
+         * This has the form:
+         *        Forsythe string of the setup position.
+         *        w/b - colour to move.
+         *        castling permissions.
+         *        en-passant square.
+         *        half-moves since pawn move/piece capture.
+         *        move number.
+         */
+Board *
+new_fen_board(const char *fen)
+{   Board *new_board = allocate_new_board();
+    /* Start with a clear board. */
+    static const Board initial_board = {
+        { { OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF},
+          { OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF},
+          { OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF}
+        },
+        /* Who to move next. */
+        WHITE,
+        /* Move number. */
+        1,
+        /* Castling rights. */
+        FALSE, FALSE, FALSE, FALSE,
+        /* Initial king positions. */
+        'e',FIRSTRANK,
+        'e',LASTRANK,
+        /* En Passant rights. */
+        FALSE, 0, 0,
+        /* Initial hash value. */
+        0ul,
+        /* halfmove_clock */
+        0,
+      };
+    Rank rank = LASTRANK;
+    Col col;
+    const char *fen_char = fen;
+    Boolean Ok = TRUE;
+    /* In some circumstances we will try to parse the game data,
+     * even if there are errors.
+     */
+    Boolean try_to_parse_game = FALSE;
+
+    /* Reset the contents of the new board. */
+    *new_board = initial_board;
+    /* Extract the piece positions. */
+    col = FIRSTCOL;
+    while(Ok && (*fen_char != ' ') && (*fen_char != '\0') &&
+                (rank >= FIRSTRANK)){
+        Piece piece;
+        char ch = *fen_char;
+        Colour colour;
+
+        if((piece = is_FEN_piece(ch)) != EMPTY){
+            if(isupper((int) ch)){
+                colour = WHITE;
+            }
+            else{
+                colour = BLACK;
+            }
+            if(col <= LASTCOL){
+                new_board->board[RankConvert(rank)][ColConvert(col)] = 
+                                MAKE_COLOURED_PIECE(colour,piece);
+                if(piece == KING){
+                    if(colour == WHITE){
+                        new_board->WKingCol = col;
+                        new_board->WKingRank = rank;
+                    }
+                    else{
+                        new_board->BKingCol = col;
+                        new_board->BKingRank = rank;
+                    }
+                }
+                col++;
+                fen_char++;
+            }
+            else{
+                Ok = FALSE;
+            }
+        }
+        else if(isdigit((int) ch)){
+           if(('1' <= ch) && (ch <= '8')){
+               col += ch - '0';
+               /* In filling up the remaining columns of a rank we will
+                * temporarily exceed LASTCOL, but we expect the
+                * next character to be '/' so that we reset.
+                */
+               if(col <= (LASTCOL+1)){
+                   fen_char++;
+               }
+               else{
+                   Ok = FALSE;
+               }
+           }
+           else{
+               Ok = FALSE;
+           }
+        }
+        else if(ch == '/'){
+            /* End of that rank. We should have completely filled the
+             * previous rank.
+             */
+            if(col == (LASTCOL+1)){
+                col = FIRSTCOL;
+                rank--;
+                fen_char++;
+            }
+            else{
+                Ok = FALSE;
+            }
+        }
+        else{
+            /* Unknown character. */
+            Ok = FALSE;
+        }
+    }
+    /* As we don't print any error messages until the end of the function,
+     * we don't need to guard everything with if(Ok).
+     */
+    if(*fen_char == ' '){
+        /* Find out who is to move. */
+        fen_char++;
+    }
+    else{
+        Ok = FALSE;
+    }
+    if(*fen_char == 'w'){
+        new_board->to_move = WHITE;
+        fen_char++;
+    }
+    else if(*fen_char == 'b'){
+        new_board->to_move = BLACK;
+        fen_char++;
+    }
+    else{
+        Ok = FALSE;
+    }
+    if(*fen_char == ' '){
+        fen_char++;
+    }
+    else{
+        Ok = FALSE;
+    }
+    /* Determine castling rights. */
+    if(*fen_char == '-'){
+        /* No castling rights -- default above. */
+        new_board->WKingCastle = new_board->WQueenCastle =
+            new_board->BKingCastle = new_board->BQueenCastle = FALSE;
+        fen_char++;
+    }
+    else{
+        /* Check to make sure that this section isn't empty. */
+        if(*fen_char == ' '){
+            Ok = FALSE;
+        }
+        if(*fen_char == 'K'){
+            new_board->WKingCastle = TRUE;
+            fen_char++;
+        }
+        if(*fen_char == 'Q'){
+            new_board->WQueenCastle = TRUE;
+            fen_char++;
+        }
+        if(*fen_char == 'k'){
+            new_board->BKingCastle = TRUE;
+            fen_char++;
+        }
+        if(*fen_char == 'q'){
+            new_board->BQueenCastle = TRUE;
+            fen_char++;
+        }
+    }
+    if(*fen_char == ' '){
+        fen_char++;
+    }
+    else{
+        Ok = FALSE;
+    }
+    /* If we are ok to this point, try to make a best efforts approach
+     * to handle the game, even if there are subsequent errors.
+     */
+    if(Ok){
+       try_to_parse_game = TRUE;
+    }
+    /* Check for an en-passant square. */
+    if(*fen_char == '-'){
+        /* None. */
+        fen_char++;
+    }
+    else if(is_col(*fen_char)){
+        col = *fen_char;
+        fen_char++;
+        if(is_rank(*fen_char)){
+            rank = *fen_char;
+            fen_char++;
+            /* Make sure that the en-passant indicator is consistent
+             * with whose move it is.
+             */
+            if(((new_board->to_move == WHITE) && (rank == '6')) ||
+                ((new_board->to_move == BLACK) && (rank == '3'))){
+                /* Consistent. */
+                new_board->EnPassant = TRUE;
+                new_board->ep_rank = rank;
+                new_board->ep_col = col;
+            }
+            else{
+                Ok = FALSE;
+            }
+        }
+        else{
+            Ok = FALSE;
+        }
+    }
+    else{
+        Ok = FALSE;
+    }
+    if(*fen_char == ' '){
+        fen_char++;
+    }
+    else{
+        Ok = FALSE;
+    }
+    /* Check for half-move count since last pawn move
+     * or capture.
+     */
+    if(isdigit((int) *fen_char)){
+        unsigned halfmove_clock = *fen_char-'0';
+        fen_char++;
+        while(isdigit((int) *fen_char)){
+            halfmove_clock = (halfmove_clock*10)+(*fen_char-'0');
+            fen_char++;
+        }
+        new_board->halfmove_clock = halfmove_clock;
+    }
+    else{
+        Ok = FALSE;
+    }
+    if(*fen_char == ' '){
+        fen_char++;
+    }
+    else{
+        Ok = FALSE;
+    }
+    /* Check for current move number. */
+    if(isdigit((int) *fen_char)){
+        unsigned move_number = 0;
+
+        move_number = *fen_char-'0';
+        fen_char++;
+        while(isdigit((int) *fen_char)){
+            move_number = (move_number*10)+(*fen_char-'0');
+            fen_char++;
+        }
+        if(move_number < 1) {
+            move_number = 1;
+        }
+        new_board->move_number = move_number;
+    }
+    else{
+        Ok = FALSE;
+    }
+    /* Allow trailing space. */
+    while(isspace((int) *fen_char)){
+        fen_char++;
+    }
+    if(*fen_char != '\0'){
+        Ok = FALSE;
+    }
+    if(Ok){
+    }
+    else{
+        fprintf(GlobalState.logfile,"Illegal FEN string %s at %s",fen,fen_char);
+        if(try_to_parse_game){
+            fprintf(GlobalState.logfile," Attempting to parse the game, anyway.");
+        }
+        else{
+            (void) free_board((void *)new_board);
+            new_board = NULL;
+        }
+        putc('\n',GlobalState.logfile);
+    }
+    return new_board;
+}
+
+        /* Set up a board structure for a new game.
+         * This involves placing the pieces in their initial positions,
+         * setting up castling and en-passant rights, and initialising
+         * the hash positions.
+         * If the fen argument is NULL then a completely new board is
+         * setup, otherwise the indicated FEN position is returned.
+         */
+static Board *
+new_game_board(const char *fen)
+{   Board *new_board;
+    static const Board initial_board =
+      {
+        { { OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF},
+          { OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF},
+          { OFF,OFF,W(ROOK),W(KNIGHT),W(BISHOP),W(QUEEN),
+                            W(KING),W(BISHOP),W(KNIGHT),W(ROOK),OFF,OFF},
+          { OFF,OFF,W(PAWN),W(PAWN),W(PAWN),W(PAWN),
+                            W(PAWN),W(PAWN),W(PAWN),W(PAWN),OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,OFF,OFF},
+          { OFF,OFF,B(PAWN),B(PAWN),B(PAWN),B(PAWN),
+                            B(PAWN),B(PAWN),B(PAWN),B(PAWN),OFF,OFF},
+          { OFF,OFF,B(ROOK),B(KNIGHT),B(BISHOP),B(QUEEN),
+                            B(KING),B(BISHOP),B(KNIGHT),B(ROOK),OFF,OFF},
+          { OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF},
+          { OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF}
+        },
+        /* Who to move next. */
+        WHITE,
+        /* Move number. */
+        1,
+        /* Castling rights. */
+        TRUE, TRUE, TRUE, TRUE,
+        /* Initial king positions. */
+        'e',FIRSTRANK,
+        'e',LASTRANK,
+        /* En Passant rights. */
+        FALSE, 0, 0,
+        /* Initial hash value. */
+        0ul,
+        /* halfmove_clock */
+        0,
+      };
+    /* Iterate over the columns. */
+    Col col;
+
+    if(fen != NULL){
+        new_board = new_fen_board(fen);
+    }
+    /* Guard against failure of new_fen_board as well as the
+     * normal game situation.
+     */
+    if((fen == NULL) || (new_board == NULL)){
+        /* Use the initial board setup. */
+        new_board = allocate_new_board();
+        *new_board = initial_board;
+    }
+
+    /* Generate the hash value for the initial position. */
+    for(col = FIRSTCOL; col <= LASTCOL; col++){
+        Rank rank;
+
+        for(rank = FIRSTRANK; rank <= LASTRANK; rank++){
+            /* Find the basic components. */
+            Piece coloured_piece = new_board->board[
+                                RankConvert(rank)][ColConvert(col)];
+            Piece piece = EXTRACT_PIECE(coloured_piece);
+            Colour colour = EXTRACT_COLOUR(coloured_piece);
+
+            if(coloured_piece != EMPTY){
+                new_board->hash_value ^= HashLookup(col,rank,piece,colour);
+            }
+        }
+    }
+    return new_board;
+}
+
+        /* Print out the current occupant of the given square. */
+static void
+print_square(Col col, Rank rank, const Board *board,FILE *outfp)
+{   short r = RankConvert(rank);
+    short c = ColConvert(col);
+
+    Piece coloured_piece = board->board[r][c];
+    switch((int) coloured_piece){
+        case W(PAWN):
+        case W(KNIGHT):
+        case W(BISHOP):
+        case W(ROOK):
+        case W(QUEEN):
+        case W(KING):
+        case B(PAWN):
+        case B(KNIGHT):
+        case B(BISHOP):
+        case B(ROOK): 
+        case B(QUEEN):
+        case B(KING):
+            putc(coloured_piece_to_SAN_letter(coloured_piece),outfp);
+            break;
+        case EMPTY:
+            putc('.',outfp);
+            break;
+        case OFF:
+            putc('?',outfp);
+            break;
+        default:
+            fprintf(GlobalState.logfile,
+                "Attempt to print illegal square %c%c in print_square.\n",
+                        col,rank);
+            break;
+    }
+}
+
+        /* Print out the contents of the given board. */
+static void
+print_board(const Board *board,FILE *outfp)
+{  Rank rank;
+   Col col;
+
+   for(rank = LASTRANK; rank >= FIRSTRANK; rank--){
+       for(col = FIRSTCOL; col <= LASTCOL; col++){
+           print_square(col,rank,board,outfp);
+       }
+       putc('\n',outfp);
+   }
+   putc('\n',outfp);
+}
+
+#if INCLUDE_UNUSED_FUNCTIONS
+
+        /* Check the consistency of the board. */
+static void
+check_board(const Board *board,const char *where)
+{  Rank rank;
+   Col col;
+
+   for(rank = LASTRANK; rank >= FIRSTRANK; rank--){
+       for(col = FIRSTCOL; col <= LASTCOL; col++){
+          short r = RankConvert(rank);
+          short c = ColConvert(col);
+
+          switch(board->board[r][c]){
+            case W(PAWN):
+            case W(KNIGHT):
+            case W(BISHOP):
+            case W(ROOK):
+            case W(QUEEN):
+            case W(KING):
+            case B(PAWN):
+            case B(KNIGHT):
+            case B(BISHOP):
+            case B(ROOK):
+            case B(QUEEN):
+            case B(KING):
+            case EMPTY: 
+                break;
+            default:
+                fprintf(GlobalState.logfile,
+                                "%s: Illegal square %c%c (%u %u) contains %d.\n",
+                                where,col,rank,r,c,board->board[r][c]);
+                report_details(GlobalState.logfile);
+                abort();
+                break;
+          }
+      }
+   }
+}
+#endif
+
+    /* Return the number of half moves that have been completed
+     * on the board.
+     */
+static int
+half_moves_played(const Board *board)
+{
+    int half_moves = 2*(board->move_number-1);
+    if(board->to_move == BLACK){
+        half_moves ++;
+    }
+    return half_moves;
+}
+
+        /* Implement move_details on the board.
+         * Return TRUE if the move is ok, FALSE otherwise.
+         * move_details is completed by the call to determine_move_details.
+         * Thereafter, it is safe to make the move on board.
+         */
+static Boolean
+apply_move(Colour colour,Move *move_details, Board *board)
+{   /* Assume success. */
+    Boolean Ok = TRUE;
+
+    if(determine_move_details(colour,move_details,board)){
+        Piece piece_to_move = move_details->piece_to_move;
+
+        if(GlobalState.output_format == EPD){
+            move_details->epd = (char *) MallocOrDie(FEN_SPACE);
+            build_basic_EPD_string(board,move_details->epd);
+        }
+
+       if(move_details->class != NULL_MOVE) {
+           make_move(move_details->class, move_details->from_col,move_details->from_rank,
+                           move_details->to_col,move_details->to_rank,
+                           piece_to_move,colour,board);
+       }
+        /* See if there are any subsiduary actions. */
+        switch(move_details->class){
+            case PAWN_MOVE:
+            case PIECE_MOVE:
+            case ENPASSANT_PAWN_MOVE:
+                /* Nothing more to do. */
+                break;
+            case PAWN_MOVE_WITH_PROMOTION:
+                if(move_details->class == PAWN_MOVE_WITH_PROMOTION){
+                    if(move_details->promoted_piece != EMPTY){
+                        /* Now make the promotion. */
+                        make_move(move_details->class, move_details->to_col,move_details->to_rank,
+                                  move_details->to_col,move_details->to_rank,
+                                  move_details->promoted_piece,colour,board);
+                    }
+                    else{
+                        Ok = FALSE;
+                    }
+                }
+                break;
+        case KINGSIDE_CASTLE:
+            /* Step the Rook to the left of the king. */
+            piece_to_move = ROOK;
+            make_move(move_details->class, LASTCOL,move_details->from_rank,move_details->to_col-1,
+                            move_details->to_rank,
+                            piece_to_move,colour,board);
+            break;
+        case QUEENSIDE_CASTLE:
+            /* Step the Rook to the right of the king. */
+            piece_to_move = ROOK;
+            make_move(move_details->class, FIRSTCOL,move_details->from_rank,move_details->to_col+1,
+                            move_details->to_rank,
+                            piece_to_move,colour,board);
+            break;
+       case NULL_MOVE:
+           /* Nothing more to do. */
+           break;
+        case UNKNOWN_MOVE:
+        default:
+            Ok = FALSE;
+            break;
+        }
+        /* Determine whether or not this move gives check. */
+        if(Ok){
+            move_details->check_status =
+                        king_is_in_check(board,OPPOSITE_COLOUR(colour));
+            if(move_details->check_status == CHECK){
+                /* See whether it is CHECKMATE. */
+                if(king_is_in_checkmate(OPPOSITE_COLOUR(colour),board)){
+                    move_details->check_status = CHECKMATE;
+                }
+            }
+            /* Handle the halfmove_clock. */
+            if(piece_to_move == PAWN ||
+                    move_details->captured_piece != EMPTY) {
+                board->halfmove_clock = 0;
+            }
+            else {
+                board->halfmove_clock++;
+            }
+        }
+    }
+    else{
+        Ok = FALSE;
+    }
+    return Ok;
+}
+
+        /* Play out the moves on the given board.
+         * game_details is updated with the final_ and cumulative_ hash
+         * values.
+        * Check move validity unless a NULL_MOVE has been found in this
+        * variation.
+         */
+static Boolean
+play_moves(Game *game_details, Board *board, Move *moves, unsigned max_depth,
+           Boolean check_move_validity)
+{   Boolean game_ok = TRUE;
+    /* Ply number at which any error was found. */
+    int error_ply = 0;
+    /* Force a match if we aren't looking for positional variations. */
+    Boolean game_matches = GlobalState.positional_variations?FALSE:TRUE;
+    Move *next_move = moves;
+    /* Keep track of the final ECO match. */
+    EcoLog *eco_match = NULL;
+
+    /* Try the initial board position for a match.
+     * This is required because the game might have been set up
+     * from a FEN string, rather than being the normal starting
+     * position.
+     */
+    if(!game_matches && position_matches(board)){
+       game_matches = TRUE;
+        if(GlobalState.add_position_match_comments) {
+           CommentList *comment = create_match_comment(next_move);
+           comment->next = game_details->prefix_comment;
+           game_details->prefix_comment = comment;
+        }
+    }
+    /* Keep going while the game is ok, and we have some more
+     * moves and we haven't exceeded the search depth without finding
+     * a match.
+     */
+    while(game_ok && (next_move != NULL) &&
+                (game_matches || (board->move_number <= max_depth))){
+        if(*(next_move->move) != '\0'){
+            /* See if there are any variations associated with this move. */
+            if((next_move->Variants != NULL) && GlobalState.keep_variations){
+                game_matches |= apply_variations(game_details,board,
+                                                next_move->Variants,
+                                                check_move_validity);
+            }
+            /* Now try the main move. */
+           if(next_move->class == NULL_MOVE) {
+               /* We might not be able to check the validity of
+                * subsequent moves.
+                */
+#if 0
+               check_move_validity = FALSE;
+#endif
+           }
+            if(check_move_validity) {
+               if(apply_move(board->to_move,next_move,board)){
+                  /* Don't try for a positional match if we already have one. */
+                  if(!game_matches && position_matches(board)){
+                      game_matches = TRUE;
+                      if(GlobalState.add_position_match_comments) {
+                          CommentList *comment = create_match_comment(next_move);
+                          append_comments_to_move(next_move, comment);
+                      }
+                  }
+                  /* Combine this hash value with the cumulative one. */
+                  game_details->cumulative_hash_value += board->hash_value;
+                  if(GlobalState.fuzzy_match_duplicates) {
+                       int plies = 2 * board->move_number - 1;
+                       /* Check who has just moved. */
+                       if(board->to_move == BLACK) {
+                           plies++;
+                       }
+                       /* Consider remembering this hash value for fuzzy matches. */
+                       if(GlobalState.fuzzy_match_depth == plies) {
+                           /* Remember it. */
+                           game_details->fuzzy_duplicate_hash = board->hash_value;
+                       }
+                  }
+                  board->to_move = OPPOSITE_COLOUR(board->to_move);
+                  if(board->to_move == WHITE){
+                      board->move_number++;
+                  }
+                  if(GlobalState.add_ECO && !GlobalState.parsing_ECO_file){
+                      int half_moves = half_moves_played(board);
+                      EcoLog *entry = eco_matches(
+                              board->hash_value,
+                              game_details->cumulative_hash_value,
+                              half_moves);
+                      if(entry != NULL){
+                          /* Consider keeping the match.
+                           * Could try to avoid spurious matches which become
+                           * more likely with larger ECO files and
+                           * the longer a game goes on.
+                           * Could be mitigated partly by preferring
+                           * an ECO line of exactly the same length as
+                           * the current game line.
+                           * Not currently implemented.
+                           */
+                          if(eco_match == NULL){
+                              /* We don't have one yet. */
+                              eco_match = entry;
+                          }
+                          else {
+                              /* Keep it anyway.
+                               * This logic always prefers a longer match
+                               * to a shorter, irrespective of whether
+                               * either match is exact or not.
+                               * This logic was followed in versions
+                               * up to and including v13.8.
+                               */
+                              eco_match = entry;
+                          }
+                      }
+                  }
+                  next_move = next_move->next;
+               }
+               else{
+                   print_error_context(GlobalState.logfile);
+                   fprintf(GlobalState.logfile,
+                                   "Failed to make move %u%s %s in the game:\n",
+                                   board->move_number,
+                                   (board->to_move == WHITE)?".":"...",
+                                   next_move->move);
+                   print_board(board,GlobalState.logfile);
+                   report_details(GlobalState.logfile);
+                   game_ok = FALSE;
+                   /* Work out where the error was. */
+                   error_ply = 2 * board->move_number - 1;
+                   /* Check who has just moved. */
+                   if(board->to_move == BLACK) {
+                       error_ply++;
+                   }
+               }
+            }
+           else {
+               /* Go through the motions as if the move were checked. */
+              board->to_move = OPPOSITE_COLOUR(board->to_move);
+              if(board->to_move == WHITE){
+                  board->move_number++;
+              }
+              next_move = next_move->next;
+           }
+        }
+        else{
+            /* An empty move. */
+            fprintf(GlobalState.logfile,
+                        "Internal error: Empty move in play_moves.\n");
+            report_details(GlobalState.logfile);
+            game_ok = FALSE;
+           /* Work out where the error was. */
+           error_ply = 2 * board->move_number - 1;
+           /* Check who has just moved. */
+           if(board->to_move == BLACK) {
+               error_ply++;
+           }
+        }
+    }
+    if(game_ok){
+        if(eco_match != NULL){
+           /* Free any details of the old one. */
+           if(game_details->tags[ECO_TAG] != NULL){
+               (void) free((void *) game_details->tags[ECO_TAG]);
+               game_details->tags[ECO_TAG] = NULL;
+           }
+           if(game_details->tags[OPENING_TAG] != NULL){
+               (void) free((void *)game_details->tags[OPENING_TAG]);
+               game_details->tags[OPENING_TAG] = NULL;
+           }
+           if(game_details->tags[VARIATION_TAG] != NULL){
+               (void) free((void *)game_details->tags[VARIATION_TAG]);
+               game_details->tags[VARIATION_TAG] = NULL;
+           }
+           if(game_details->tags[SUB_VARIATION_TAG] != NULL){
+               (void) free((void *)game_details->tags[SUB_VARIATION_TAG]);
+               game_details->tags[SUB_VARIATION_TAG] = NULL;
+           }
+           /* Add in the new one. */
+           if(eco_match->ECO_tag != NULL){
+               game_details->tags[ECO_TAG] = copy_string(eco_match->ECO_tag);
+           }
+           if(eco_match->Opening_tag != NULL){
+               game_details->tags[OPENING_TAG] = copy_string(eco_match->Opening_tag);
+           }
+           if(eco_match->Variation_tag != NULL){
+               game_details->tags[VARIATION_TAG] =
+                                copy_string(eco_match->Variation_tag);
+           }
+           if(eco_match->Sub_Variation_tag != NULL){
+               game_details->tags[SUB_VARIATION_TAG] =
+                                copy_string(eco_match->Sub_Variation_tag);
+           }
+        }
+    }
+    /* Fill in the hash value of the final position reached. */
+    game_details->final_hash_value = board->hash_value;
+    game_details->moves_ok = game_ok;
+    game_details->error_ply = error_ply;
+    if(!game_ok){
+       /* Decide whether to keep it anyway. */
+       if(GlobalState.keep_broken_games) {
+       }
+       else if(GlobalState.positional_variations){
+       }
+       else {
+           /* Only return a match if it genuinely matched a variation
+            * in which we were interested.
+            */
+            /* We can't have found a genuine match. */
+            game_matches = FALSE;
+        }
+    }
+    return game_matches;
+}
+
+        /* Play out the moves of an ECO line on the given board.
+         * game_details is updated with the final_ and cumulative_ hash
+         * values.
+         */
+
+static void
+play_eco_moves(Game *game_details, Board *board,Move *moves)
+{   Boolean game_ok = TRUE;
+    /* Ply number at which any error was found. */
+    int error_ply = 0;
+    Move *next_move = moves;
+
+    /* Keep going while the game is ok, and we have some more
+     * moves and we haven't exceeded the search depth without finding
+     * a match.
+     */
+    while(game_ok && (next_move != NULL)){
+        if(*(next_move->move) != '\0'){
+            /* Ignore variations. */
+            if(apply_move(board->to_move,next_move,board)){
+               /* Combine this hash value to the cumulative one. */
+               game_details->cumulative_hash_value += board->hash_value;
+               board->to_move = OPPOSITE_COLOUR(board->to_move);
+               if(board->to_move == WHITE){
+                   board->move_number++;
+               }
+               next_move = next_move->next;
+            }
+            else{
+                print_error_context(GlobalState.logfile);
+                fprintf(GlobalState.logfile,
+                                "Failed to make move %u%s %s in the game:\n",
+                                board->move_number,
+                                (board->to_move == WHITE)?".":"...",
+                                next_move->move);
+                print_board(board,GlobalState.logfile);
+                report_details(GlobalState.logfile);
+                game_ok = FALSE;
+               /* Work out where the error was. */
+               error_ply = 2 * board->move_number - 1;
+               /* Check who has just moved. */
+               if(board->to_move == BLACK) {
+                   error_ply++;
+               }
+            }
+        }
+        else{
+            /* An empty move. */
+            fprintf(GlobalState.logfile,
+                        "Internal error: Empty move in play_eco_moves.\n");
+            report_details(GlobalState.logfile);
+            game_ok = FALSE;
+           /* Work out where the error was. */
+           error_ply = 2 * board->move_number - 1;
+           /* Check who has just moved. */
+           if(board->to_move == BLACK) {
+               error_ply++;
+           }
+        }
+    }
+    /* Fill in the hash value of the final position reached. */
+    game_details->final_hash_value = board->hash_value;
+    game_details->moves_ok = game_ok;
+    game_details->error_ply = error_ply;
+}
+
+        /* Play out a variation.
+        * Check move validity unless a NULL_MOVE has been found in this
+        * variation.
+         * Return TRUE if the variation matches a position that
+         * we are looking for.
+         */
+static Boolean
+apply_variations(const Game *game_details,const Board *board,Variation *variation,
+                 Boolean check_move_validity)
+{   /* Force a match if we aren't looking for positional variations. */
+    Boolean variation_matches = GlobalState.positional_variations?FALSE:TRUE;
+    /* Allocate space for the copies.
+     * Allocation is done, rather than relying on local copies in the body
+     * of the loop because the recursive nature of this function has
+     * resulted in stack overflow on the PC version.
+     */
+    Game *copy_game = (Game *) MallocOrDie(sizeof(*copy_game));
+    Board *copy_board = allocate_new_board();
+
+    while(variation != NULL){
+        /* Work on the copies. */
+        *copy_game = *game_details;
+        *copy_board = *board;
+
+        /* We only need one variation to match to declare a match.
+         * Play out the variation to its full depth, because we
+         * will want the full move information if the main line
+         * later matches.
+         */
+        variation_matches |= play_moves(copy_game,copy_board,variation->moves,
+                                        DEFAULT_POSITIONAL_DEPTH,
+                                       check_move_validity);
+        variation = variation->next;
+    }
+    (void) free((void *)copy_game);
+    (void) free_board((void *)copy_board);
+    return variation_matches;
+}
+
+        /* game_details contains a complete move score.
+         * Try to apply each move on a new board.
+         * Store in plycount the number of ply played.
+         * Return TRUE if the game matches a variation that we are
+         * looking for.
+         */
+Boolean
+apply_move_list(Game *game_details,unsigned *plycount)
+{   Move *moves = game_details->moves;
+    Board *board = new_game_board(game_details->tags[FEN_TAG]);
+    Boolean game_matches;
+    /* Set the default search depth. */
+    unsigned max_depth = GlobalState.depth_of_positional_search;
+
+    /* Ensure that we have a sensible search depth. */
+    if(max_depth == 0){
+        /* No positional variations specified. */
+        max_depth = DEFAULT_POSITIONAL_DEPTH;
+    }
+
+    /* Start off the cumulative hash value. */
+    game_details->cumulative_hash_value = 0;
+
+    /* Play through the moves and see if we have a match.
+     * Check move validity.
+     */
+    game_matches = play_moves(game_details,board,moves,max_depth,TRUE);
+
+    game_details->moves_checked = TRUE;
+
+    /* Record how long the game was. */
+    if(board->to_move == BLACK){
+        *plycount = 2 * board->move_number - 1;
+    }
+    else{
+        /* This move number hasn't been played. */
+        *plycount = 2 * (board->move_number - 1);
+    }
+
+    if(game_matches) {
+         game_matches = check_for_only_stalemate(board, moves);
+    }
+
+    (void) free_board((void *)board);
+    return game_matches;
+}
+
+        /* game_details contains a complete move score.
+         * Try to apply each move on a new board.
+         * Store in number_of_moves the length of the game.
+         * Return TRUE if the game is ok.
+         */
+Boolean
+apply_eco_move_list(Game *game_details,unsigned *number_of_half_moves)
+{   Move *moves = game_details->moves;
+    Board *board = new_game_board(game_details->tags[FEN_TAG]);
+
+    /* Start off the cumulative hash value. */
+    game_details->cumulative_hash_value = 0;
+    play_eco_moves(game_details,board,moves);
+    game_details->moves_checked = TRUE;
+    /* Record how long the game was. */
+    *number_of_half_moves = half_moves_played(board);
+    (void) free_board((void *)board);
+    return game_details->moves_ok;
+}
+
+
+        /* Return the string associated with the given piece. */
+const char *
+piece_str(Piece piece)
+{
+    if(piece < NUM_PIECE_VALUES){
+        return output_piece_characters[piece];
+    }
+    else{
+        return "?";
+    }
+}
+
+        /* Rewrite move_details->move according to the details held
+         * within the structure and the current state of the board.
+         */
+static Boolean
+rewrite_SAN_string(Colour colour,Move *move_details, Board *board)
+{   Boolean Ok = TRUE;
+
+    if(move_details == NULL){
+        /* Shouldn't happen. */
+        fprintf(GlobalState.logfile,
+                "Internal error: NULL move details in rewrite_SAN_string.\n");
+        Ok = FALSE;
+    }
+    else if(move_details->move[0] == '\0'){
+        /* Shouldn't happen. */
+        fprintf(GlobalState.logfile,"Empty move in rewrite_SAN_string.\n");
+        Ok = FALSE;
+    }
+    else{
+        const unsigned char *move = move_details->move;
+        MoveClass class = move_details->class;
+        MovePair *move_list = NULL;
+        Col to_col = move_details->to_col;
+        Rank to_rank = move_details->to_rank;
+        unsigned char new_move_str[MAX_MOVE_LEN+1] = "";
+
+        switch(class){
+            case PAWN_MOVE:
+            case ENPASSANT_PAWN_MOVE:
+            case PAWN_MOVE_WITH_PROMOTION:
+                move_list = find_pawn_moves(move_details->from_col,
+                                                '0',to_col,to_rank,
+                                                colour,board);
+                break;
+            case PIECE_MOVE:
+                switch(move_details->piece_to_move){
+                    case KING:
+                        move_list = find_king_moves(to_col,to_rank,colour,board);
+                        break;
+                    case QUEEN:
+                        move_list = find_queen_moves(to_col,to_rank,colour,board);
+                        break;
+                    case ROOK:
+                        move_list = find_rook_moves(to_col,to_rank,colour,board);
+                        break;
+                    case KNIGHT:
+                        move_list = find_knight_moves(to_col,to_rank,colour,board);
+                        break;
+                    case BISHOP:
+                        move_list = find_bishop_moves(to_col,to_rank,colour,board);
+                        break;
+                    default:
+                        fprintf(GlobalState.logfile,"Unknown piece move %s\n",move);
+                        Ok = FALSE;
+                        break;
+                }
+                break;
+            case KINGSIDE_CASTLE:
+            case QUEENSIDE_CASTLE:
+                /* No move list to prepare. */
+                break;
+           case NULL_MOVE:
+                /* No move list to prepare. */
+                break;
+            case UNKNOWN_MOVE:
+            default:
+                fprintf(GlobalState.logfile,
+                        "Unknown move class in rewrite_SAN_string(%d).\n",
+                        move_details->class);
+                Ok = FALSE;
+                break;
+        }
+        if(move_list != NULL){
+            move_list = exclude_checks(move_details->piece_to_move,colour,
+                                                move_list,board);
+        }
+        if((move_list == NULL) && (class != KINGSIDE_CASTLE) &&
+                        (class != QUEENSIDE_CASTLE) && (class != NULL_MOVE)){
+            Ok = FALSE;
+        }
+        /* We should now have enough information in move_details to compose a
+         * SAN string.
+         */
+        if(Ok){
+            size_t new_move_index = 0;
+
+            switch(class){
+                case PAWN_MOVE:
+                case ENPASSANT_PAWN_MOVE:
+                case PAWN_MOVE_WITH_PROMOTION:
+                    /* See if we need to give the source column. */
+                    if(move_details->captured_piece != EMPTY){
+                        new_move_str[new_move_index] = move_details->from_col;
+                        new_move_index++;
+                        new_move_str[new_move_index] = 'x';
+                        new_move_index++;
+                    }
+                    else if(move_list->next != NULL){
+                        new_move_str[new_move_index] = move_details->from_col;
+                        new_move_index++;
+                    }
+                    /* Add in the destination. */
+                    new_move_str[new_move_index] = to_col;
+                    new_move_index++;
+                    new_move_str[new_move_index] = to_rank;
+                    new_move_index++;
+                    if(class == PAWN_MOVE_WITH_PROMOTION){
+                        const char *promoted_piece =
+                                        piece_str(move_details->promoted_piece);
+                        new_move_str[new_move_index] = '=';
+                        new_move_index++;
+                        strcpy((char *) &new_move_str[new_move_index],
+                               promoted_piece);
+                        new_move_index += strlen(promoted_piece);
+                    }
+                    new_move_str[new_move_index] = '\0';
+                    break;
+                case PIECE_MOVE:
+                    {   const char *piece = piece_str(move_details->piece_to_move);
+                        strcpy((char *) &new_move_str[0],piece);
+                        new_move_index += strlen(piece);
+                        /* Check for the need to disambiguate. */
+                        if(move_list->next != NULL){
+                            /* It is necessary.  Count how many times
+                             * the from_ col and rank occur in the list
+                             * of possibles in order to determine which to use
+                             * for this purpose.
+                             */
+                            int col_times = 0, rank_times = 0;
+                            MovePair *possible;
+                            Col from_col = move_details->from_col;
+                            Rank from_rank = move_details->from_rank;
+
+                            for(possible = move_list; possible != NULL;
+                                            possible = possible->next){
+                                if(possible->from_col == from_col){
+                                    col_times++;
+                                }
+                                if(possible->from_rank == from_rank){
+                                    rank_times++;
+                                }
+                            }
+                            if(col_times == 1){
+                                /* Use the col. */
+                                new_move_str[new_move_index] = from_col;
+                                new_move_index++;
+                            }
+                            else if(rank_times == 1){
+                                /* Use the rank. */
+                                new_move_str[new_move_index] = from_rank;
+                                new_move_index++;
+                            }
+                            else{
+                                /* Use both. */
+                                new_move_str[new_move_index] = from_col;
+                                new_move_index++;
+                                new_move_str[new_move_index] = from_rank;
+                                new_move_index++;
+                            }
+                        }
+                        /* See if a capture symbol is needed. */
+                        if(move_details->captured_piece != EMPTY){
+                            new_move_str[new_move_index] = 'x';
+                            new_move_index++;
+                        }
+                        /* Add in the destination. */
+                        new_move_str[new_move_index] = to_col;
+                        new_move_index++;
+                        new_move_str[new_move_index] = to_rank;
+                        new_move_index++;
+                        new_move_str[new_move_index] = '\0';
+                    }
+                    break;
+                case KINGSIDE_CASTLE:
+                    strcpy((char *) new_move_str,"O-O");
+                    break;
+                case QUEENSIDE_CASTLE:
+                    strcpy((char *) new_move_str,"O-O-O");
+                    break;
+                case NULL_MOVE:
+                    strcpy((char *) new_move_str, (char *) NULL_MOVE_STRING);
+                    break;
+                case UNKNOWN_MOVE:
+                default:
+                    Ok = FALSE;
+                    break;
+            }
+            if(Ok){
+                if(move_details->check_status != NOCHECK){
+                    if(move_details->check_status == CHECK){
+                        /* It isn't mate. */
+                        strcat((char *) new_move_str,"+");
+                    }
+                    else{
+                        if(GlobalState.output_format == CM){
+                            strcat((char *) new_move_str,"++");
+                        }
+                        else{
+                            strcat((char *) new_move_str,"#");
+                        }
+                    }
+                }
+            }
+            /* Update the move_details structure with the new string. */
+            strcpy((char *) move_details->move,
+                   (const char *) new_move_str);
+        }
+        if(move_list != NULL){
+            free_move_pair_list(move_list);
+        }
+    }
+    return Ok;
+}
+
+        /* Rewrite move_details->move and apply the move to board.
+         * Return TRUE if the move is ok, FALSE otherwise.
+         */
+static Boolean
+rewrite_move(Colour colour,Move *move_details, Board *board, Boolean null_move_found)
+{   /* Assume success. */
+    Boolean Ok = TRUE;
+
+    if(rewrite_SAN_string(colour,move_details,board)){
+        Piece piece_to_move = move_details->piece_to_move;
+
+       if(move_details->class != NULL_MOVE) {
+           make_move(move_details->class, move_details->from_col,move_details->from_rank,
+                           move_details->to_col,move_details->to_rank,
+                           piece_to_move,colour,board);
+       }
+       else {
+           null_move_found = TRUE;
+       }
+        /* See if there are any subsiduary actions. */
+        switch(move_details->class){
+            case PAWN_MOVE:
+            case PIECE_MOVE:
+            case ENPASSANT_PAWN_MOVE:
+                /* Nothing more to do. */
+                break;
+            case PAWN_MOVE_WITH_PROMOTION:
+                if(move_details->class == PAWN_MOVE_WITH_PROMOTION){
+                    if(move_details->promoted_piece != EMPTY){
+                        /* @@@ Do promoted moves have '+' properly appended? */
+                        /* Now make the promotion. */
+                        make_move(move_details->class, move_details->to_col,move_details->to_rank,
+                                  move_details->to_col,move_details->to_rank,
+                                  move_details->promoted_piece,colour,board);
+                    }
+                    else{
+                        Ok = FALSE;
+                    }
+                }
+                break;
+        case KINGSIDE_CASTLE:
+            /* Step the Rook to the left of the king. */
+            piece_to_move = ROOK;
+            make_move(move_details->class, LASTCOL,move_details->from_rank,move_details->to_col-1,
+                            move_details->to_rank,
+                            piece_to_move,colour,board);
+            break;
+        case QUEENSIDE_CASTLE:
+            /* Step the Rook to the right of the king. */
+            piece_to_move = ROOK;
+            make_move(move_details->class, FIRSTCOL,move_details->from_rank,move_details->to_col+1,
+                            move_details->to_rank,
+                            piece_to_move,colour,board);
+            break;
+       case NULL_MOVE:
+           /* Nothing more. */
+           break;
+        case UNKNOWN_MOVE:
+        default:
+            Ok = FALSE;
+            break;
+        }
+    }
+    else{
+        Ok = FALSE;
+    }
+    return Ok;
+}
+
+        /* Rewrite the list of moves by playing through the game. */
+static Boolean
+rewrite_moves(Board *board, Move *moves, Boolean null_move_found)
+{   Boolean game_ok = TRUE;
+    Move *move_details = moves;
+
+    while(game_ok && (move_details != NULL)){
+        if(*(move_details->move) != '\0'){
+            /* See if there are any variations associated with this move. */
+            if((move_details->Variants != NULL) &&
+                    GlobalState.keep_variations &&
+                    !rewrite_variations(board,move_details->Variants, null_move_found)){
+                /* Something wrong with the variations. */
+                game_ok = FALSE;
+            }
+           /* @@@ There was a else-if here; not sure why?! */
+           if(move_details->class == NULL_MOVE) {
+               null_move_found = TRUE;
+           }
+            if(rewrite_move(board->to_move,move_details,board, null_move_found)){
+                board->to_move = OPPOSITE_COLOUR(board->to_move);
+
+                if(GlobalState.output_evaluation) {
+                    /* Append an evaluation of the new state of the board
+                     * with the move having been played.
+                     */
+                    append_evaluation(move_details, board);
+                }
+
+                if(GlobalState.add_FEN_comments) {
+                    /* Append a FEN comment with the new state of the board
+                     * with the move having been played.
+                     */
+                    append_FEN_comment(move_details, board);
+                }
+
+                move_details = move_details->next;
+                if(board->to_move == WHITE){
+                    board->move_number++;
+                }
+            }
+            else {
+               /* Broken games that are being kept have probably already been
+                * reported, so don't repeat the error.
+                */
+               if(!GlobalState.keep_broken_games) {
+                   fprintf(GlobalState.logfile,
+                                   "Failed to rewrite move %u%s %s in the game:\n",
+                                       board->move_number,
+                                       (board->to_move == WHITE)?".":"...",
+                                       move_details->move);
+                   report_details(GlobalState.logfile);
+                   print_board(board,GlobalState.logfile);
+               }
+                game_ok = FALSE;
+            }
+        }
+        else{
+            /* An empty move. */
+            fprintf(GlobalState.logfile,
+                                "Internal error: Empty move in rewrite_moves.\n");
+            report_details(GlobalState.logfile);
+            game_ok = FALSE;
+        }
+    }
+    if(!game_ok && GlobalState.keep_broken_games && move_details != NULL) {
+        /* Try to place the remaining moves into a comment. */
+       CommentList *comment = (CommentList* ) MallocOrDie(sizeof(*comment));
+       /* Break the link from the previous move. */
+       Move *prev;
+       StringList *commented_move_list = NULL;
+
+       /* Find the move before the current one. */
+       prev = moves;
+       while(prev != NULL && prev->next != move_details) {
+           prev = prev->next;
+       }
+       if(prev != NULL) {
+           prev->next = NULL;
+       }
+       while(move_details != NULL) {
+           commented_move_list = save_string_list_item(commented_move_list, (char *) move_details->move);
+           if(move_details->next == NULL && prev != NULL) {
+               /* Pass the terminating result to prev. */
+               prev->terminating_result = move_details->terminating_result;
+               move_details->terminating_result = NULL;
+               move_details = NULL;
+           }
+           else {
+               move_details = move_details->next;
+           }
+       }
+       comment->Comment = commented_move_list;
+       comment->next = NULL;
+
+       if(prev != NULL) {
+           append_comments_to_move(prev, comment);
+       }
+    }
+    return game_ok;
+}
+
+        /* Rewrite the list of variations.
+         * Return TRUE if the variation are ok. a position that
+         */
+static Boolean
+rewrite_variations(const Board *board,Variation *variation, Boolean null_move_found)
+{   Board *copy_board = allocate_new_board();
+    Boolean variations_ok = TRUE;
+
+    while((variation != NULL) && variations_ok){
+        /* Work on the copy. */
+        *copy_board = *board;
+
+        variations_ok = rewrite_moves(copy_board,variation->moves, null_move_found);
+        variation = variation->next;
+    }
+    (void) free_board((void *)copy_board);
+    return variations_ok;
+}
+
+        /* moves contains a complete game score.
+         * Try to rewrite each move into SAN as it is played on a new board.
+         * Return the final Board position if the game was rewritten alright,
+         * NULL otherwise.
+         */
+Board *
+rewrite_game(Game *current_game)
+{
+    const char *fen = current_game->tags[FEN_TAG];
+    Board *board = new_game_board(fen);
+    Boolean game_ok;
+
+    /* No null-move found at the start of the game. */
+    game_ok = rewrite_moves(board,current_game->moves,FALSE);
+    if(game_ok){
+    }
+    else if(GlobalState.keep_broken_games) {
+    }
+    else {
+        (void) free_board((void *)board);
+        board = NULL;
+    }
+    return board;
+}
+
+
+        /* Define a table to hold the positional hash codes of interest. */
+#define MAX_CODE 53
+static HashLog *codes_of_interest[MAX_CODE];
+
+        /* move_details is a variation in which we are interested.
+         * Generate and store the hash value in codes_of_interest.
+         */
+void
+store_hash_value(Move *move_details,const char *fen)
+{   Move *move = move_details;
+    Board *board = new_game_board(fen);
+    Boolean Ok = TRUE;
+
+    while((move != NULL) && Ok){
+        /* Reset print_move number if a variation was printed. */
+        if(*(move->move) == '\0'){
+            /* A comment node, not a proper move. */
+           move = move->next;
+        }
+        else if(apply_move(board->to_move,move,board)){
+           board->to_move = OPPOSITE_COLOUR(board->to_move);
+           move = move->next;
+           if(board->to_move == WHITE){
+               board->move_number++;
+           }
+        }
+        else{
+            print_error_context(GlobalState.logfile);
+            fprintf(GlobalState.logfile,"Failed to make move %u%s %s\n",
+                                board->move_number,
+                                (board->to_move == WHITE)?".":"...",
+                        move->move);
+            Ok = FALSE;
+        }
+    }
+
+    if(!Ok){
+        exit(1);
+    }
+    else{
+        HashLog *entry = (HashLog *)MallocOrDie(sizeof(*entry));
+        unsigned ix = board->hash_value % MAX_CODE;
+
+        /* We don't include the cumulative hash value as the sequence
+         * of moves to reach this position is not important.
+         */
+        entry->cumulative_hash_value = 0;
+       entry->final_hash_value = board->hash_value;
+        /* Link it into the head at this index. */
+        entry->next = codes_of_interest[ix];
+        codes_of_interest[ix] = entry;
+    }
+    (void) free_board((void *)board);
+}
+
+        /* Does the current board match a position of interest.
+        * Look in codes_of_interest for current_hash_value.
+        */
+static Boolean
+position_matches(const Board *board)
+{
+    HashCode current_hash_value = board->hash_value;
+    unsigned ix = current_hash_value % MAX_CODE;
+    Boolean found = FALSE;
+    HashLog *entry;
+
+    for(entry = codes_of_interest[ix]; !found && (entry != NULL);
+                        entry = entry->next){
+        /* We can test against just the position value. */
+        if(entry->final_hash_value == current_hash_value){
+            found = TRUE;
+        }
+    }
+    if(!found) {
+       const char *matching_pattern = matchBoard(board);
+        found = matching_pattern != NULL;
+    }
+    return found;
+}
+
+    /* Build a basic EPD string from the given board. */
+void
+build_basic_EPD_string(const Board *board,char *epd)
+{   Rank rank;
+    int ix = 0;
+    Boolean castling_allowed = FALSE;
+    for(rank = LASTRANK; rank >= FIRSTRANK; rank--){
+        Col col;
+        int consecutive_spaces = 0;
+        for(col = FIRSTCOL; col <= LASTCOL; col++){
+            int coloured_piece = board->board[RankConvert(rank)]
+                                             [ColConvert(col)];
+            if(coloured_piece != EMPTY){
+                if(consecutive_spaces > 0){
+                    epd[ix] = '0'+consecutive_spaces;
+                    ix++;
+                    consecutive_spaces = 0;
+                }
+                epd[ix] = coloured_piece_to_SAN_letter(coloured_piece);
+                ix++;
+            }
+            else{
+                consecutive_spaces++;
+            }
+        }
+        if(consecutive_spaces > 0){
+            epd[ix] = '0'+consecutive_spaces;
+            ix++;
+        }
+        /* Terminate the row. */
+        if(rank != FIRSTRANK){
+            epd[ix] = '/'; ix++;
+        }
+    }
+    epd[ix] = ' '; ix++;
+    epd[ix]  = '\0';
+    epd[ix] = board->to_move == WHITE? 'w' : 'b'; ix++;
+    epd[ix] = ' '; ix++;
+
+    /* Castling details. */
+    if(board->WKingCastle){
+        epd[ix] = 'K'; ix++;
+        castling_allowed = TRUE;
+    }
+    if(board->WQueenCastle){
+        epd[ix] = 'Q'; ix++;
+        castling_allowed = TRUE;
+    }
+    if(board->BKingCastle){
+        epd[ix] = 'k'; ix++;
+        castling_allowed = TRUE;
+    }
+    if(board->BQueenCastle){
+        epd[ix] = 'q'; ix++;
+        castling_allowed = TRUE;
+    }
+    if(!castling_allowed){
+        /* There are no castling rights. */
+        epd[ix] = '-';
+        ix++;
+    }
+    epd[ix] = ' '; ix++;
+
+    /* Enpassant. */
+    if(board->EnPassant){
+        epd[ix] = board->ep_col; ix++;
+        epd[ix] = board->ep_rank; ix++;
+    }
+    else{
+        epd[ix] = '-'; ix++;
+    }
+    epd[ix] = '\0';
+}
+
+    /* Build a FEN string from the given board. */
+void
+build_FEN_string(const Board *board,char *fen)
+{   
+    size_t ix;
+    int full_move_number =
+            board->to_move == BLACK ? board->move_number : (board->move_number + 1);
+
+    build_basic_EPD_string(board,fen);
+    /* Append the (pseudo) half move count and the full move count. */
+    ix = strlen(fen);
+    fen[ix] = ' '; ix++;
+
+    /* Half moves since the last capture or pawn move. */
+    sprintf(&fen[ix], "%u", board->halfmove_clock);
+    ix = strlen(fen);
+    fen[ix] = ' '; ix++;
+
+    /* The full move number. */
+    sprintf(&fen[ix],"%u", full_move_number);
+}
+
+    /* Append to move_details a FEN comment of the board.
+     * The board state is immediately following application of the
+     * given move.
+     */
+static void
+append_FEN_comment(Move *move_details, const Board *board)
+{
+    char *FEN_comment = MallocOrDie(FEN_SPACE);
+    CommentList *comment = (CommentList* ) MallocOrDie(sizeof(*comment));
+    StringList *current_comment = save_string_list_item(NULL, FEN_comment);
+    
+    build_FEN_string(board, FEN_comment);
+    comment->Comment = current_comment;
+    comment->next = NULL;
+    append_comments_to_move(move_details, comment);
+}
+
+    /* Append to move_details an evaluation value for board.
+     * The board state is immediately following application of the
+     * given move.
+     */
+static void
+append_evaluation(Move *move_details, const Board *board)
+{
+    CommentList *comment = (CommentList* ) MallocOrDie(sizeof(*comment));
+    /* Space template for the value.
+     * @@@ There is a buffer-overflow risk here if the evaluation value
+     * is too large.
+     */
+    const char valueSpace[] = "-012456789.00";
+    char *evaluation = (char *) MallocOrDie(sizeof(valueSpace));
+    StringList *current_comment;
+
+    double value = evaluate(board);
+
+    /* @@@ Overflow possible here if the value is too big to fit. */
+    sprintf(evaluation,"%.2f", value);
+    if(strlen(evaluation) > strlen(valueSpace)) {
+        fprintf(GlobalState.logfile,
+                "Overflow in evaluation space in append_evaluation()\n");
+        exit(1);
+    }
+
+    current_comment = save_string_list_item(NULL, evaluation);
+    comment->Comment = current_comment;
+    comment->next = NULL;
+    append_comments_to_move(move_details, comment);
+}
+
+    /* Append to move_details a comment indicating that this
+     * move resulted in a positional match.
+     */
+CommentList *
+create_match_comment(Move *move_details)
+{
+    /* The comment string. */
+    char *match_comment = copy_string(GlobalState.position_match_comment);
+    StringList *current_comment = save_string_list_item(NULL, match_comment);
+    CommentList *comment = (CommentList* ) MallocOrDie(sizeof(*comment));
+    
+    comment->Comment = current_comment;
+    comment->next = NULL;
+    return comment;
+}
+    /* Return an evaluation of board. */
+static double
+evaluate(const Board *board)
+{
+    return shannonEvaluation(board);
+}
+
+    /* Return an evaluation of board based on
+     * Claude Shannon's technique.
+     */
+static double
+shannonEvaluation(const Board *board)
+{
+    MovePair *white_moves, *black_moves;
+    int whiteMoveCount = 0, blackMoveCount = 0;
+    int whitePieceCount = 0, blackPieceCount = 0;
+    double shannonValue = 0.0;
+
+    Rank rank;
+    Col col;
+    
+    /* Determine the mobilities. */
+    white_moves = find_all_moves(board, WHITE);
+    if(white_moves != NULL){
+        MovePair *m;
+        for(m = white_moves; m != NULL; m = m->next) {
+            whiteMoveCount++;
+        }
+        free_move_pair_list(white_moves);
+    }
+
+    black_moves = find_all_moves(board, BLACK);
+    if(black_moves != NULL){
+        MovePair *m;
+        for(m = black_moves; m != NULL; m = m->next) {
+            blackMoveCount++;
+        }
+        free_move_pair_list(black_moves);
+    }
+
+
+    /* Pick up each piece of the required colour. */
+    for(rank = LASTRANK; rank >= FIRSTRANK; rank--){
+       short r = RankConvert(rank);
+       for(col = FIRSTCOL; col <= LASTCOL; col++){
+           short c = ColConvert(col);
+           int pieceValue = 0;
+           Piece occupant = board->board[r][c];
+           if(occupant != EMPTY) {
+               /* This square is occupied by a piece of the required colour. */
+               Piece piece = EXTRACT_PIECE(occupant);
+
+               switch(piece){
+                   case PAWN:
+                       pieceValue = 1;
+                       break;
+                   case BISHOP:
+                   case KNIGHT:
+                       pieceValue = 3;
+                       break;
+                   case ROOK:
+                       pieceValue = 5;
+                       break;
+                   case QUEEN:
+                       pieceValue = 9;
+                       break;
+                   case KING:
+                       break;
+                   default:
+                       fprintf(GlobalState.logfile,
+                           "Internal error: unknown piece %d in append_evaluation().\n",
+                               piece);
+               }
+               if(EXTRACT_COLOUR(occupant) == WHITE) {
+                   whitePieceCount += pieceValue;
+               }
+               else {
+                   blackPieceCount += pieceValue;
+               }
+           }
+       }
+    }
+
+    shannonValue = (whitePieceCount - blackPieceCount) +
+                   (whiteMoveCount - blackMoveCount) * 0.1;
+    return shannonValue;
+}
diff --git a/apply.h b/apply.h
new file mode 100644 (file)
index 0000000..5c6d3ba
--- /dev/null
+++ b/apply.h
@@ -0,0 +1,36 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+void store_hash_value(Move *move_details,const char *fen);
+Boolean apply_move_list(Game *game_details,unsigned *plycount);
+Boolean apply_eco_move_list(Game *game_details,unsigned *number_of_half_moves);
+Board *rewrite_game(Game *game_details);
+char *copy_string(const char *str);
+Board *new_fen_board(const char *fen);
+/* letters should contain a string of the form: "PNBRQK" */
+void set_output_piece_characters(const char *letters);
+char coloured_piece_to_SAN_letter(Piece coloured_piece);
+void build_basic_EPD_string(const Board *board,char *fen);
+char SAN_piece_letter(Piece piece);
+const char *piece_str(Piece piece);
+void build_FEN_string(const Board *board,char *fen);
+CommentList *create_match_comment(Move *move_details);
diff --git a/argsfile.c b/argsfile.c
new file mode 100644 (file)
index 0000000..82be49e
--- /dev/null
@@ -0,0 +1,1088 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "bool.h"
+#include "defs.h"
+#include "typedef.h"
+#include "lines.h"
+#include "taglist.h"
+#include "tokens.h"
+#include "lex.h"
+#include "taglines.h"
+#include "moves.h"
+#include "end.h"
+#include "eco.h"
+#include "argsfile.h"
+#include "apply.h"
+#include "output.h"
+#include "lists.h"
+#include "mymalloc.h"
+
+#define CURRENT_VERSION "v17-19"
+#define URL "http://www.cs.kent.ac.uk/people/staff/djb/pgn-extract/"
+
+/* The prefix of the arguments allowed in an argsfile.
+ * The full format is:
+ *         :-?
+ * where ? is an argument letter.
+ *
+ * A line of the form:
+ *         :filename
+ * means use filename as a NORMALFILE source of games.
+ *
+ * A line with no leading colon character is taken to apply to the
+ * move-reason argument line. Currently, this only applies to the
+ *        -t -v -x -z
+ * arguments.
+ */
+static const char argument_prefix[] = ":-";
+static const int argument_prefix_len = sizeof(argument_prefix)-1;
+static ArgType classify_arg(const char *line);
+
+        /* Select the correct function according to operating system. */
+static int
+stringcompare(const char *s1, const char *s2)
+{
+#if defined(__unix__) || defined(__linux__) || defined(__APPLE__)
+    return strcasecmp(s1,s2);
+#else
+    return _stricmp(s1,s2);
+#endif
+}
+
+#if 0
+        /* Return TRUE if str contains prefix as a prefix, FALSE otherwise. */
+static Boolean
+prefixMatch(const char *prefix, const char *str)
+{
+    size_t prefixLen = strlen(prefix);
+    if(strlen(str) >= prefixLen) {
+#if defined(__unix__) || defined(__linux__)
+        return strncasecmp(prefix, str, prefixLen) == 0;
+#else
+        return _strnicmp(prefix, str, prefixLen) == 0;
+#endif
+    }
+    else {
+        return FALSE;
+    }
+}
+#endif
+
+    /* Skip over leading spaces from the string. */
+static const char *skip_leading_spaces(const char *str)
+{
+    while(*str == ' ') {
+        str++;
+    }
+    return str;
+}
+
+        /* Print a usage message, and exit. */
+static void
+usage_and_exit(void)
+{
+    const char *help_data[] = {
+      "-7 -- output only the seven tag roster for each game. Other tags (apart",
+      "      from FEN and possibly ECO) are discarded (See -e).",
+      "-#num -- output num games per file, to files named 1.pgn, 2.pgn, etc.",
+
+      "",
+
+      "-aoutputfile -- append extracted games to outputfile. (See -o).",
+      "-Aargsfile -- read the program's arguments from argsfile.",
+      "-b[elu]num -- restricted bounds on the number of moves in a game.",
+      "       lnum set a lower bound of `num' moves,",
+      "       unum set an upper bound of `num' moves,",
+      "       otherwise num (or enum) means equal-to `num' moves.",
+      "-cfile[.pgn] -- Use file.pgn as a check-file for duplicates or",
+      "      contents of file (no pgn suffix) as a list of check-file names.",
+      "-C -- don't include comments in the output. Ordinarily these are retained.",
+      "-dduplicates -- write duplicate games to the file duplicates.",
+      "-D -- don't output duplicate games.",
+      "-eECO_file -- perform ECO classification of games. The optional",
+      "      ECO_file should contain a PGN format list of ECO lines",
+      "      Default is to use eco.pgn from the current directory.",
+      "-E[123 etc.] -- split output into separate files according to ECO.",
+      "      E1 : Produce files from ECO letter, A.pgn, B.pgn, ...",
+      "      E2 : Produce files from ECO letter and first digit, A0.pgn, ...",
+      "      E3 : Produce files from full ECO code, A00.pgn, A01.pgn, ...",
+      "      Further digits may be used to produce non-standard further",
+      "      refined division of games.",
+      "      All files are opened in append mode.",
+      "-F -- output a FEN string comment of the final game position.",
+      "-ffile_list  -- file_list contains the list of PGN source files, one per line.",
+      "-h -- print details of the arguments.",
+      "-llogfile  -- Save the diagnostics in logfile rather than using stderr.",
+      "-Llogfile  -- Append all diagnostics to logfile, rather than overwriting.",
+      "-M -- Match only games which end in checkmate.",
+      "-noutputfile -- Write all valid games not otherwise output to outputfile.",
+      "-N -- don't include NAGs in the output. Ordinarily these are retained.",
+      "-ooutputfile -- write extracted games to outputfile (existing contents lost).",
+      "-P -- don't match permutations of the textual variations (-v).",
+      "-Rtagorder -- Use the tag ordering specified in the file tagorder.",
+      "-r -- report any errors but don't extract.",
+      "-S -- Use a simple soundex algorithm for some tag matches. If used",
+      "      this option must precede the -t or -T options.",
+      "-s -- silent mode: don't report each game as it is extracted.",
+      "-ttagfile -- file of player, date, result or FEN extraction criteria.",
+      "-Tcriterion -- player, date, or result extraction criterion.",
+      "-U -- don't output games that only occur once. (See -d).",
+      "-vvariations -- the file variations contains the textual lines of interest.",
+      "-V -- don't include variations in the output. Ordinarily these are retained.",
+      "-wwidth -- set width as an approximate line width for output.",
+      "-W[cm|epd|halg|lalg|elalg|san] -- specify the output format to use.",
+      "      Default is SAN.",
+      "      -W means use the input format.",
+      "      -Wcm is (a possibly obsolete) ChessMaster format.",
+      "      -Wepd is EPD format.",
+      "      -Wsan[PNBRQK] for language specific output.",
+      "      -Whalg is hyphenated long algebraic.",
+      "      -Wlalg is long algebraic.",
+      "      -Welalg is enhanced long algebraic.",
+      "      -Wuci is output compatible with the UCI protocol.",
+      "-xvariations -- the file variations contains the lines resulting in",
+      "                positions of interest.",
+      "-zendings -- the file endings contains the end positions of interest.",
+      "-Z -- use the file virtual.tmp as an external hash table for duplicates.",
+      "      Use when MallocOrDie messages occur with big datasets.",
+
+      "",
+
+      "--addhashcode - output a HashCode tag",
+      "--append - see -a",
+      "--checkfile - see -c",
+      "--checkmate - see -M",
+      "--duplicates - see -d",
+      "--evaluation - include a position evaluation after each move",
+      "--fencomments - include a FEN string after each move",
+      "--fuzzydepth plies - positional duplicates match",
+      "--help - see -h",
+      "--keepbroken - retain games with errors",
+      "--linelength - see -w",
+      "--markmatches - mark positional and material matches with a comment; see -t, -v, and -z",
+      "--nochecks - don't output + and # after moves.",
+      "--nocomments - see -C",
+      "--noduplicates - see -D",
+      "--nomovenumbers - don't output move numbers.",
+      "--nonags - see -N",
+      "--noresults - don't output results.",
+      "--notags - don't output any tags.",
+      "--nounique - see -U",
+      "--novars - see -V",
+      "--output - see -o",
+      "--plylimit - limit the number of plies output.",
+      "--selectonly N - only output the Nth matched game (N > 0)",
+      "--seven - see -7",
+      "--stalemate - only output games that end in stalemate.",
+      "--totalplycount - include a tag with the total number of plies in a game.",
+      "--version - print the current version number and exit.",
+
+      /* Must be NULL terminated. */
+      (char *)NULL,
+  };
+
+  const char **data = help_data;
+
+  fprintf(GlobalState.logfile,
+          "pgn-extract %s (%s): a Portable Game Notation (PGN) manipulator.\n",
+          CURRENT_VERSION,__DATE__);
+  fprintf(GlobalState.logfile,
+          "Copyright (C) 1994-2014 David J. Barnes (d.j.barnes@kent.ac.uk)\n");
+  fprintf(GlobalState.logfile,"%s\n\n",URL);
+  fprintf(GlobalState.logfile,"Usage: pgn-extract [arguments] [file.pgn ...]\n");
+  
+  for(; *data != NULL; data++){
+      fprintf(GlobalState.logfile,"%s\n",*data);
+  }
+  exit(1);
+}
+
+void
+read_args_file(const char *infile)
+{   char *line;
+    FILE *fp = fopen(infile,"r");
+
+    if(fp == NULL){
+        fprintf(GlobalState.logfile,"Cannot open %s for reading.\n",infile);
+        exit(1);
+    }
+    else{
+        ArgType linetype = NO_ARGUMENT_MATCH;
+        ArgType nexttype;
+        while((line = read_line(fp)) != NULL){
+            if(blank_line(line)){
+                (void) free(line);
+                continue;
+            }
+            nexttype = classify_arg(line);
+            if(nexttype == NO_ARGUMENT_MATCH){
+                if(*line == argument_prefix[0]){
+                    /* Treat the line as a source file name. */
+                    add_filename_to_source_list(&line[1],NORMALFILE);
+                }
+                else if(linetype != NO_ARGUMENT_MATCH){
+                    /* Handle the line. */
+                    switch(linetype){
+                        case MOVES_ARGUMENT:
+                            add_textual_variation_from_line(line);
+                            break;
+                        case POSITIONS_ARGUMENT:
+                            add_positional_variation_from_line(line);
+                            break;
+                        case TAGS_ARGUMENT:
+                            process_tag_line(infile,line);
+                            break;
+                        case TAG_ROSTER_ARGUMENT:
+                            process_roster_line(line);
+                            break;
+                        case ENDINGS_ARGUMENT:
+                            process_ending_line(line);
+                            (void) free(line);
+                            break;
+                        default:
+                            fprintf(GlobalState.logfile,
+                                    "Internal error: unknown linetype %d in read_args_file\n",
+                                    linetype);
+                            (void) free(line);
+                            exit(-1);
+                    }
+                }
+                else{
+                    /* It should have been a line applying to the
+                     * current linetype.
+                     */
+                    fprintf(GlobalState.logfile,
+                        "Missing argument type for line %s in the argument file.\n",
+                        line);
+                    exit(1);
+                }
+            }
+            else{
+                switch(nexttype){
+                        /* Arguments with a possible additional
+                         * argument value.
+                         * All of these apply only to the current
+                         * line in the argument file.
+                         */
+                    case WRITE_TO_OUTPUT_FILE_ARGUMENT:
+                    case APPEND_TO_OUTPUT_FILE_ARGUMENT:
+                    case WRITE_TO_LOG_FILE_ARGUMENT:
+                    case APPEND_TO_LOG_FILE_ARGUMENT:
+                    case DUPLICATES_FILE_ARGUMENT:
+                    case USE_ECO_FILE_ARGUMENT:
+                    case CHECK_FILE_ARGUMENT:
+                    case FILE_OF_FILES_ARGUMENT:
+                    case BOUNDS_ARGUMENT:
+                    case GAMES_PER_FILE_ARGUMENT:
+                    case ECO_OUTPUT_LEVEL_ARGUMENT:
+                    case FILE_OF_ARGUMENTS_ARGUMENT:
+                    case NON_MATCHING_GAMES_ARGUMENT:
+                    case TAG_EXTRACTION_ARGUMENT:
+                    case LINE_WIDTH_ARGUMENT:
+                    case OUTPUT_FORMAT_ARGUMENT:
+                        process_argument(line[argument_prefix_len],
+                                         &line[argument_prefix_len+1]);
+                        linetype = NO_ARGUMENT_MATCH;
+                        break;
+                    case LONG_FORM_ARGUMENT:
+                       {
+                           char *arg = &line[argument_prefix_len+1];
+                           char *space = strchr(arg, ' ');
+                           if(space != NULL) {
+                               /* We need to drop an associated value from arg. */
+                               int arglen = space - arg;
+                               char *just_arg = (char *) MallocOrDie(arglen + 1);
+                               strncpy(just_arg, arg, arglen);
+                               just_arg[arglen] = '\0';
+                               process_long_form_argument(just_arg,
+                                                          skip_leading_spaces(space));
+                           }
+                           else {
+                               process_long_form_argument(arg, "");
+                               linetype = NO_ARGUMENT_MATCH;
+                           }
+                       }
+                        break;
+
+                        /* Arguments with no additional
+                         * argument value.
+                         * All of these apply only to the current
+                         * line in the argument file.
+                         */
+                    case SEVEN_TAG_ROSTER_ARGUMENT:
+                    case HELP_ARGUMENT:
+                    case ALTERNATIVE_HELP_ARGUMENT:
+                    case DONT_KEEP_COMMENTS_ARGUMENT:
+                    case DONT_KEEP_DUPLICATES_ARGUMENT:
+                    case DONT_MATCH_PERMUTATIONS_ARGUMENT:
+                    case DONT_KEEP_NAGS_ARGUMENT:
+                    case OUTPUT_FEN_STRING_ARGUMENT:
+                    case CHECK_ONLY_ARGUMENT:
+                    case KEEP_SILENT_ARGUMENT:
+                    case USE_SOUNDEX_ARGUMENT:
+                    case MATCH_CHECKMATE_ARGUMENT:
+                    case SUPPRESS_ORIGINALS_ARGUMENT:
+                    case DONT_KEEP_VARIATIONS_ARGUMENT:
+                    case USE_VIRTUAL_HASH_TABLE_ARGUMENT:
+                        process_argument(line[argument_prefix_len],"");
+                        linetype = NO_ARGUMENT_MATCH;
+                        break;
+
+                        /* Arguments whose values persist beyond
+                         * the current line.
+                         */
+                    case MOVES_ARGUMENT:
+                    case POSITIONS_ARGUMENT:
+                    case ENDINGS_ARGUMENT:
+                    case TAGS_ARGUMENT:
+                    case TAG_ROSTER_ARGUMENT:
+                        process_argument(line[argument_prefix_len],
+                                         &line[argument_prefix_len+1]);
+                        /* Apply this type to subsequent lines. */
+                        linetype = nexttype;
+                        break;
+                    default:
+                        linetype = nexttype;
+                        break;
+                }
+                (void) free(line);
+            }
+        }
+        (void) fclose(fp);
+    }
+}
+
+        /* Determine which (if any) type of argument is
+         * indicated by the contents of the current line.
+         * Arguments are assumed to be surrounded by
+         * square brackets.
+         */
+static ArgType
+classify_arg(const char *line)
+{
+    /* Valid arguments must have at least one character beyond
+     * the prefix.
+     */
+    static const size_t min_argument_length = 1+sizeof(argument_prefix)-1;
+    size_t line_length = strlen(line);
+
+    /* Check for a line of the form:
+     *            :-argument
+     */
+    if((strncmp(line,argument_prefix,argument_prefix_len) == 0) &&
+                   (line_length >= min_argument_length)){
+        char argument_letter = line[argument_prefix_len];
+        switch(argument_letter){
+            case TAGS_ARGUMENT:
+            case MOVES_ARGUMENT:
+            case POSITIONS_ARGUMENT:
+            case ENDINGS_ARGUMENT:
+            case TAG_EXTRACTION_ARGUMENT:
+            case LINE_WIDTH_ARGUMENT:
+            case OUTPUT_FORMAT_ARGUMENT:
+            case SEVEN_TAG_ROSTER_ARGUMENT:
+            case FILE_OF_ARGUMENTS_ARGUMENT:
+            case NON_MATCHING_GAMES_ARGUMENT:
+            case DONT_KEEP_COMMENTS_ARGUMENT:
+            case DONT_KEEP_DUPLICATES_ARGUMENT:
+            case DONT_KEEP_NAGS_ARGUMENT:
+            case DONT_MATCH_PERMUTATIONS_ARGUMENT:
+            case OUTPUT_FEN_STRING_ARGUMENT:
+            case CHECK_ONLY_ARGUMENT:
+            case KEEP_SILENT_ARGUMENT:
+            case USE_SOUNDEX_ARGUMENT:
+            case MATCH_CHECKMATE_ARGUMENT:
+            case SUPPRESS_ORIGINALS_ARGUMENT:
+            case DONT_KEEP_VARIATIONS_ARGUMENT:
+            case WRITE_TO_OUTPUT_FILE_ARGUMENT:
+            case WRITE_TO_LOG_FILE_ARGUMENT:
+            case APPEND_TO_LOG_FILE_ARGUMENT:
+            case APPEND_TO_OUTPUT_FILE_ARGUMENT:
+            case DUPLICATES_FILE_ARGUMENT:
+            case USE_ECO_FILE_ARGUMENT:
+            case CHECK_FILE_ARGUMENT:
+            case FILE_OF_FILES_ARGUMENT:
+            case BOUNDS_ARGUMENT:
+            case GAMES_PER_FILE_ARGUMENT:
+            case ECO_OUTPUT_LEVEL_ARGUMENT:
+            case HELP_ARGUMENT:
+            case ALTERNATIVE_HELP_ARGUMENT:
+            case TAG_ROSTER_ARGUMENT:
+            case LONG_FORM_ARGUMENT:
+                return (ArgType) argument_letter;
+            default:
+                fprintf(GlobalState.logfile,
+                        "Unrecognized argument: %s in the argument file.\n",
+                        line);
+                exit(1);
+                return NO_ARGUMENT_MATCH;
+        }
+    }
+    else{
+        return NO_ARGUMENT_MATCH;
+    }
+}
+
+    /* Process the argument character and its associated value.
+     * This function processes arguments from the command line and
+     * from an argument file associated with the -A argument.
+     *
+     * An argument -ofile.pgn would be passed in as:
+     *                'o' and "file.pgn".
+     * A zero-length string for associated_value is not necessarily
+     * an error, e.g. -e has an optional following filename.
+     * NB: If the associated_value is to be used beyond this function,
+     * it must be copied.
+     */
+void
+process_argument(char arg_letter,const char *associated_value)
+{   /* Provide an alias for associated_value because it will
+     * often represent a file name.
+     */
+    const char *filename = skip_leading_spaces(associated_value);
+
+    switch(arg_letter){
+        case WRITE_TO_OUTPUT_FILE_ARGUMENT:
+        case APPEND_TO_OUTPUT_FILE_ARGUMENT:
+          if(GlobalState.ECO_level > 0){
+              fprintf(GlobalState.logfile,"-%c conflicts with -E\n",
+                      arg_letter);
+          }
+          else if(GlobalState.games_per_file > 0){
+              fprintf(GlobalState.logfile,"-%c conflicts with -#\n",
+                      arg_letter);
+          }
+          else if(GlobalState.output_filename != NULL){
+              fprintf(GlobalState.logfile,
+                      "-%c: File %s has already been selected for output.\n",
+                      arg_letter,GlobalState.output_filename);
+              exit(1);
+          }
+          else if(*filename == '\0'){
+              fprintf(GlobalState.logfile,"Usage: -%cfilename.\n",arg_letter);
+              exit(1);
+          }
+          else{
+              if(GlobalState.outputfile != NULL){
+                  (void) fclose(GlobalState.outputfile);
+              }
+              if(arg_letter == WRITE_TO_OUTPUT_FILE_ARGUMENT){
+                  GlobalState.outputfile = must_open_file(filename,"w");
+              }
+              else{
+                  GlobalState.outputfile = must_open_file(filename,"a");
+              }
+              GlobalState.output_filename = filename;
+          }
+          break;
+        case WRITE_TO_LOG_FILE_ARGUMENT:
+        case APPEND_TO_LOG_FILE_ARGUMENT:
+          /* Take precautions against multiple log files. */
+          if((GlobalState.logfile != stderr) && (GlobalState.logfile != NULL)){
+                (void) fclose(GlobalState.logfile);
+          }
+          if(arg_letter == WRITE_TO_LOG_FILE_ARGUMENT){
+                GlobalState.logfile = fopen(filename,"w");
+          }
+          else{
+                GlobalState.logfile = fopen(filename,"a");
+          }
+          if(GlobalState.logfile == NULL){
+                fprintf(stderr,"Unable to open %s for writing.\n",filename);
+                GlobalState.logfile = stderr;
+          }
+          break;
+        case DUPLICATES_FILE_ARGUMENT:
+          if(*filename == '\0'){
+              fprintf(GlobalState.logfile,"Usage: -%cfilename.\n",arg_letter);
+              exit(1);
+          }
+          else if(GlobalState.suppress_duplicates){
+              fprintf(GlobalState.logfile,
+                      "-%c clashes with the -%c flag.\n",arg_letter,
+                      DONT_KEEP_DUPLICATES_ARGUMENT);
+              exit(1);
+          }
+          else{
+              GlobalState.duplicate_file = must_open_file(filename,"w");
+          }
+          break;
+        case USE_ECO_FILE_ARGUMENT:
+          GlobalState.add_ECO = TRUE;
+          if(*filename != '\0'){
+              GlobalState.eco_file = copy_string(filename);
+          }
+          else if((filename = getenv("ECO_FILE")) != NULL){
+              GlobalState.eco_file = filename;
+          }
+          else{
+              /* Use the default which is already set up. */
+          }
+          initEcoTable();
+          break;
+        case ECO_OUTPUT_LEVEL_ARGUMENT:
+          {   unsigned level;
+
+              if(GlobalState.output_filename != NULL){
+                  fprintf(GlobalState.logfile,
+                          "-%c: File %s has already been selected for output.\n",
+                          arg_letter,
+                          GlobalState.output_filename);
+                  exit(1);
+              }
+              else if(GlobalState.games_per_file > 0){
+                  fprintf(GlobalState.logfile,
+                            "-%c conflicts with -#.\n",
+                            arg_letter);
+                  exit(1);
+              }
+              else if(sscanf(associated_value,"%u",&level) != 1){
+                    fprintf(GlobalState.logfile,
+                            "-%c requires a number attached, e.g., -%c1.\n",
+                            arg_letter,arg_letter);
+                     exit(1);
+              }
+              else if((level < MIN_ECO_LEVEL) || (level > MAX_ECO_LEVEL)){
+                    fprintf(GlobalState.logfile,
+                            "-%c level should be between %u and %u.\n",
+                            MIN_ECO_LEVEL,MAX_ECO_LEVEL,arg_letter);
+                    exit(1);
+              }
+              else{
+                    GlobalState.ECO_level = level;
+              }
+          }
+          break;
+        case CHECK_FILE_ARGUMENT:
+          if(*filename != '\0'){
+              /* See if it is a single PGN file, or a list
+               * of files.
+               */
+              size_t len = strlen(filename);
+              /* Check for a .PGN suffix. */
+              const char *suffix = output_file_suffix(SAN);
+
+              if((len > strlen(suffix)) &&
+                    (stringcompare(&filename[len-strlen(suffix)],
+                                            suffix) == 0)){
+                  add_filename_to_source_list(filename,CHECKFILE);
+              }
+              else{
+                  FILE *fp = must_open_file(filename,"r");
+                  add_filename_list_from_file(fp,CHECKFILE);
+                  (void) fclose(fp);
+              }
+          }
+          break;
+        case FILE_OF_FILES_ARGUMENT:
+          if(*filename != '\0'){
+              FILE *fp = must_open_file(filename,"r");
+              add_filename_list_from_file(fp,NORMALFILE);
+              (void) fclose(fp);
+          }
+          else{
+              fprintf(GlobalState.logfile,"Filename expected with -%c\n",
+                      arg_letter);
+          }
+          break;
+        case BOUNDS_ARGUMENT:
+          {
+              /* Bounds on the number of moves are to be found.
+               * "l#" means less-than-or-equal-to.
+               * "g#" means greater-than-or-equal-to.
+               * Otherwise "#" (or "e#") means that number.
+               */
+              /* Equal by default. */
+              char which = 'e';
+              unsigned value;
+              Boolean Ok = TRUE;
+              const char *bound = associated_value;
+
+              switch(*bound){
+                case 'l':
+                case 'u':
+                case 'e':
+                  which = *bound;
+                  bound++;
+                  break;
+                default:
+                  if(!isdigit((int) *bound)){
+                      fprintf(GlobalState.logfile,
+                              "-%c must be followed by e, l, or u.\n",
+                              arg_letter);
+                      Ok = FALSE;
+                  }
+                  break;
+              }
+              if(Ok && (sscanf(bound,"%u",&value) == 1)){
+                GlobalState.check_move_bounds = TRUE;
+                switch(which){
+                  case 'e':
+                        GlobalState.lower_move_bound = value; 
+                        GlobalState.upper_move_bound = value; 
+                        break;
+                  case 'l':
+                    if(value <= GlobalState.upper_move_bound){
+                        GlobalState.lower_move_bound = value; 
+                    }
+                    else{
+                        fprintf(GlobalState.logfile,
+                           "Lower bound is greater than the upper bound; -%c ignored.\n",
+                           arg_letter);
+                        Ok = FALSE;
+                    }
+                    break;
+                  case 'u':
+                    if(value >= GlobalState.lower_move_bound){
+                        GlobalState.upper_move_bound = value; 
+                    }
+                    else{
+                        fprintf(GlobalState.logfile,
+                           "Upper bound is smaller than the lower bound; -%c ignored.\n",
+                           arg_letter);
+                        Ok = FALSE;
+                    }
+                    break;
+                }
+             }
+             else{
+               fprintf(GlobalState.logfile,
+                       "-%c should be in the form -%c[elu]number.\n",
+                       arg_letter,arg_letter);
+               Ok = FALSE;
+             }
+             if(!Ok){
+                exit(1);
+             }
+         }
+         break;
+        case GAMES_PER_FILE_ARGUMENT:
+          if(GlobalState.ECO_level > 0){
+              fprintf(GlobalState.logfile,
+                      "-%c conflicts with -E.\n",arg_letter);
+              exit(1);
+          }
+          else if(GlobalState.output_filename != NULL){
+              fprintf(GlobalState.logfile,
+                        "-%c: File %s has already been selected for output.\n",
+                        arg_letter,
+                        GlobalState.output_filename);
+              exit(1);
+          }
+          else if(sscanf(associated_value,"%u",
+                       &GlobalState.games_per_file) != 1){
+            fprintf(GlobalState.logfile,
+                    "-%c should be followed by an unsigned integer.\n",
+                    arg_letter);
+            exit(1);
+          }
+          else{
+            /* Value set. */
+          }
+          break;
+        case FILE_OF_ARGUMENTS_ARGUMENT:
+          if(*filename != '\0'){
+              /* @@@ Potentially recursive call. Is this safe? */
+              read_args_file(filename);
+          }
+          else{
+              fprintf(GlobalState.logfile,"Usage: -%cfilename.\n",
+                      arg_letter);
+          }
+          break;
+        case NON_MATCHING_GAMES_ARGUMENT:
+          if(*filename != '\0'){
+              if(GlobalState.non_matching_file != NULL){
+                  (void) fclose(GlobalState.non_matching_file);
+              }
+              GlobalState.non_matching_file = must_open_file(filename,"w");
+          }
+          else{
+              fprintf(GlobalState.logfile,"Usage: -%cfilename.\n",arg_letter);
+              exit(1);
+          }
+          break;
+        case TAG_EXTRACTION_ARGUMENT:
+            /* A single tag extraction criterion. */
+            extract_tag_argument(associated_value);
+            break;
+        case LINE_WIDTH_ARGUMENT:
+            { /* Specify an output line width. */
+              unsigned length;
+
+              if(sscanf(associated_value,"%u",&length) > 0){
+                  set_output_line_length(length);
+              }
+              else{
+                  fprintf(GlobalState.logfile,
+                          "-%c should be followed by an unsigned integer.\n",
+                          arg_letter);
+                  exit(1);
+              }
+            }
+            break;
+        case HELP_ARGUMENT:
+            usage_and_exit();
+            break;
+        case OUTPUT_FORMAT_ARGUMENT:
+            /* Whether to use the source form of moves or
+             * rewrite them into another format.
+             */
+           {
+               OutputFormat format = which_output_format(associated_value);
+               if(format == UCI) {
+                   /* Rewrite the game in a format suitable for input to
+                    * a UCI-compatible engine.
+                    * This is actually LALG but involves adjusting a lot of
+                    * the other statuses, too.
+                    */
+                   GlobalState.keep_NAGs = FALSE;
+                   GlobalState.keep_comments = FALSE;
+                   GlobalState.keep_move_numbers = FALSE;
+                   GlobalState.keep_checks = FALSE;
+                   GlobalState.keep_variations = FALSE;
+                   set_output_line_length(5000);
+                   format = LALG;
+               }
+               GlobalState.output_format = format;
+           }
+            break;
+        case SEVEN_TAG_ROSTER_ARGUMENT:
+            if(GlobalState.tag_output_format == ALL_TAGS ||
+               GlobalState.tag_output_format == SEVEN_TAG_ROSTER) {
+                GlobalState.tag_output_format = SEVEN_TAG_ROSTER;
+            }
+            else {
+                fprintf(GlobalState.logfile,
+                        "-%c clashes with another argument.\n",
+                        SEVEN_TAG_ROSTER_ARGUMENT);
+                exit(1);
+            }
+            break;
+        case DONT_KEEP_COMMENTS_ARGUMENT:
+            GlobalState.keep_comments = FALSE;
+            break;
+        case DONT_KEEP_DUPLICATES_ARGUMENT:
+            /* Make sure that this doesn't clash with -d. */
+            if(GlobalState.duplicate_file == NULL){
+                GlobalState.suppress_duplicates = TRUE;
+            }
+            else{
+                fprintf(GlobalState.logfile,
+                            "-%c clashes with -%c flag.\n",
+                            DONT_KEEP_DUPLICATES_ARGUMENT,
+                            DUPLICATES_FILE_ARGUMENT);
+                exit(1);
+            }
+            break;
+        case DONT_MATCH_PERMUTATIONS_ARGUMENT:
+            GlobalState.match_permutations = FALSE;
+            break;
+        case DONT_KEEP_NAGS_ARGUMENT:
+            GlobalState.keep_NAGs = FALSE;
+            break;
+        case OUTPUT_FEN_STRING_ARGUMENT:
+            /* Output a FEN string of the final position.
+             * This is displayed in a comment.
+             */
+           if(GlobalState.add_FEN_comments) {
+               /* Already implied. */
+               GlobalState.output_FEN_string = FALSE;
+           }
+           else {
+               GlobalState.output_FEN_string = TRUE;
+           }
+            break;
+        case CHECK_ONLY_ARGUMENT:
+            /* Report errors, but don't convert. */
+            GlobalState.check_only = TRUE;
+            break;
+        case KEEP_SILENT_ARGUMENT:
+            /* Turn off progress reporting. */
+            GlobalState.verbose = FALSE;
+            break;
+        case USE_SOUNDEX_ARGUMENT:
+            /* Use soundex matches for player tags. */
+            GlobalState.use_soundex = TRUE;
+            break;
+        case MATCH_CHECKMATE_ARGUMENT:
+            /* Match only games that end in checkmate. */
+            GlobalState.match_only_checkmate = TRUE;
+            break;
+        case SUPPRESS_ORIGINALS_ARGUMENT:
+            GlobalState.suppress_originals = TRUE;
+            break;
+        case DONT_KEEP_VARIATIONS_ARGUMENT:
+            GlobalState.keep_variations = FALSE;
+            break;
+        case USE_VIRTUAL_HASH_TABLE_ARGUMENT:
+            GlobalState.use_virtual_hash_table = TRUE;
+            break;
+
+        case TAGS_ARGUMENT:
+            if(*filename != '\0'){
+                read_tag_file(filename);
+            }
+            break;
+        case TAG_ROSTER_ARGUMENT:
+            if(*filename != '\0'){
+                read_tag_roster_file(filename);
+            }
+            break;
+        case MOVES_ARGUMENT:
+            if(*filename != '\0'){
+                /* Where the list of variations of interest are kept. */
+                FILE *variation_file = must_open_file(filename,"r");
+                /* We wish to search for particular variations. */
+                add_textual_variations_from_file(variation_file);
+                fclose(variation_file);
+            }
+            break;
+        case POSITIONS_ARGUMENT:
+            if(*filename != '\0'){
+                FILE *variation_file = must_open_file(filename,"r");
+                /* We wish to search for positional variations. */
+                add_positional_variations_from_file(variation_file);
+                fclose(variation_file);
+            }
+            break;
+        case ENDINGS_ARGUMENT:
+            if(*filename != '\0'){
+                if(!build_endings(filename)){
+                    exit(1);
+                }
+            }
+            break;
+        default:
+            fprintf(GlobalState.logfile,
+                    "Unrecognized argument -%c\n", arg_letter);
+    }
+}
+
+    /* The argument has been expressed in a long-form, i.e. prefixed
+     * by --
+     * Decode and act on the argument.
+     * The associated_value will only be required by some arguments.
+     * Return whether one or both were required.
+     */
+int
+process_long_form_argument(const char *argument, const char *associated_value)
+{
+    if(stringcompare(argument, "addhashcode") == 0) {
+        GlobalState.add_hashcode_tag = TRUE;
+        return 1;
+    }
+    else if(stringcompare(argument, "append") == 0) {
+        process_argument(APPEND_TO_OUTPUT_FILE_ARGUMENT, associated_value);
+        return 2;
+    }
+    else if(stringcompare(argument, "checkfile") == 0) {
+        process_argument(CHECK_FILE_ARGUMENT, associated_value);
+        return 2;
+    }
+    else if(stringcompare(argument, "checkmate") == 0) {
+        process_argument(MATCH_CHECKMATE_ARGUMENT, "");
+        return 1;
+    }
+    else if(stringcompare(argument, "duplicates") == 0) {
+        process_argument(DUPLICATES_FILE_ARGUMENT, associated_value);
+        return 2;
+    }
+    else if(stringcompare(argument, "evaluation") == 0) {
+        /* Output an evaluation is required with each move. */
+        GlobalState.output_evaluation = TRUE;
+        return 1;
+    }
+    else if(stringcompare(argument, "fencomments") == 0) {
+        /* Output an evaluation is required with each move. */
+        GlobalState.add_FEN_comments = TRUE;
+       /* Turn off any separate setting of output_FEN_comment. */
+       GlobalState.output_FEN_string = FALSE;
+        return 1;
+    }
+    else if(stringcompare(argument, "fuzzydepth") == 0) {
+        /* Extract the depth. */
+        int depth = 0;
+
+        if(sscanf(associated_value, "%d",&depth) == 1){
+            if(depth >= 0) {
+               GlobalState.fuzzy_match_duplicates = TRUE;
+                GlobalState.fuzzy_match_depth = depth;
+            }
+            else {
+                fprintf(GlobalState.logfile,
+                        "--%s requires a number greater than or equal to zero.\n", argument);
+                exit(1);
+            }
+        }
+        else {
+            fprintf(GlobalState.logfile,
+                    "--%s requires a number following it.\n", argument);
+            exit(1);
+        }
+        return 2;
+    }
+    else if(stringcompare(argument, "help") == 0) {
+        process_argument(HELP_ARGUMENT, "");
+        return 1;
+    }
+    else if(stringcompare(argument, "keepbroken") == 0) {
+        GlobalState.keep_broken_games = TRUE;
+        return 1;
+    }
+    else if(stringcompare(argument, "linelength") == 0) {
+        process_argument(LINE_WIDTH_ARGUMENT,
+                         associated_value);
+        return 2;
+    }
+    else if(stringcompare(argument, "markmatches") == 0) {
+        if(*associated_value != '\0') {
+           GlobalState.add_position_match_comments = TRUE;
+           GlobalState.position_match_comment = copy_string(associated_value);
+       }
+       else {
+              fprintf(GlobalState.logfile,
+                        "--markmatches requires a comment string following it.\n");
+              exit(1);
+       }
+       return 2;
+    }
+    else if(stringcompare(argument, "nochecks") == 0) {
+        GlobalState.keep_checks = FALSE;
+        return 1;
+    }
+    else if(stringcompare(argument, "nocomments") == 0) {
+        process_argument(DONT_KEEP_COMMENTS_ARGUMENT, "");
+        return 1;
+    }
+    else if(stringcompare(argument, "noduplicates") == 0) {
+        process_argument(DONT_KEEP_DUPLICATES_ARGUMENT, "");
+        return 1;
+    }
+    else if(stringcompare(argument, "nomovenumbers") == 0) {
+        GlobalState.keep_move_numbers = FALSE;
+        return 1;
+    }
+    else if(stringcompare(argument, "nonags") == 0) {
+        process_argument(DONT_KEEP_NAGS_ARGUMENT, "");
+        return 1;
+    }
+    else if(stringcompare(argument, "noresults") == 0) {
+        GlobalState.keep_results = FALSE;
+        return 1;
+    }
+    else if(stringcompare(argument, "notags") == 0) {
+        if(GlobalState.tag_output_format == ALL_TAGS ||
+           GlobalState.tag_output_format == NO_TAGS) {
+            GlobalState.tag_output_format = NO_TAGS;
+        }
+        else {
+            fprintf(GlobalState.logfile,
+                    "--notags clashes with another argument.\n");
+            exit(1);
+        }
+        return 1;
+    }
+    else if(stringcompare(argument, "nounique") == 0) {
+        process_argument(SUPPRESS_ORIGINALS_ARGUMENT, "");
+        return 1;
+    }
+    else if(stringcompare(argument, "novars") == 0) {
+        process_argument(DONT_KEEP_VARIATIONS_ARGUMENT, "");
+        return 1;
+    }
+    else if(stringcompare(argument, "selectonly") == 0) {
+          unsigned long selection = 0;
+
+          /* Extract the selected match number. */
+          if(sscanf(associated_value, "%lu",&selection) == 1){
+              if(selection > 0) {
+                  GlobalState.matching_game_number = selection;
+              }
+              else {
+                  fprintf(GlobalState.logfile,
+                        "--%s requires a number greater than zero.\n", argument);
+                  exit(1);
+              }
+          }
+          else {
+              fprintf(GlobalState.logfile,
+                        "--%s requires a number greater than zero following it.\n", argument);
+              exit(1);
+          }
+          return 2;
+    }
+    else if(stringcompare(argument, "output") == 0) {
+        process_argument(WRITE_TO_OUTPUT_FILE_ARGUMENT, associated_value);
+        return 2;
+    }
+    else if(stringcompare(argument, "plylimit") == 0) {
+          int limit = 0;
+
+          /* Extract the limit. */
+          if(sscanf(associated_value, "%d",&limit) == 1){
+              if(limit >= 0) {
+                  GlobalState.output_ply_limit = limit;
+              }
+              else {
+                  fprintf(GlobalState.logfile,
+                        "--%s requires a number greater than or equal to zero.\n", argument);
+                  exit(1);
+              }
+          }
+          else {
+              fprintf(GlobalState.logfile,
+                        "--%s requires a number following it.\n", argument);
+              exit(1);
+          }
+          return 2;
+    }
+    else if(stringcompare(argument, "seven") == 0) {
+        process_argument(SEVEN_TAG_ROSTER_ARGUMENT, "");
+        return 1;
+    }
+    else if(stringcompare(argument, "stalemate") == 0) {
+        GlobalState.match_only_stalemate = TRUE;
+        return 1;
+    }
+    else if(stringcompare(argument, "totalplycount") == 0) {
+        GlobalState.output_total_plycount = TRUE;
+        return 1;
+    }
+    else if(stringcompare(argument, "version") == 0) {
+        fprintf(GlobalState.logfile, "pgn-extract %s\n", CURRENT_VERSION);
+       exit(0);
+        return 1;
+    }
+    else {
+        fprintf(GlobalState.logfile,
+                "Unrecognised long-form argument: --%s\n",
+                argument);
+        exit(1);
+        return 1;
+    }
+}
diff --git a/argsfile.h b/argsfile.h
new file mode 100644 (file)
index 0000000..9c1eb59
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+/* Classifications for the arguments allowed in an argsfile. */
+typedef enum {
+    SEVEN_TAG_ROSTER_ARGUMENT = '7',
+    GAMES_PER_FILE_ARGUMENT = '#',
+    ALTERNATIVE_HELP_ARGUMENT = '?',
+    LONG_FORM_ARGUMENT = '-',
+    APPEND_TO_OUTPUT_FILE_ARGUMENT = 'a',
+    BOUNDS_ARGUMENT = 'b',
+    CHECK_FILE_ARGUMENT = 'c',
+    DUPLICATES_FILE_ARGUMENT = 'd',
+    USE_ECO_FILE_ARGUMENT = 'e',
+    FILE_OF_FILES_ARGUMENT = 'f',
+    HELP_ARGUMENT = 'h',
+    WRITE_TO_LOG_FILE_ARGUMENT = 'l',
+    NON_MATCHING_GAMES_ARGUMENT = 'n',
+    WRITE_TO_OUTPUT_FILE_ARGUMENT = 'o',
+    CHECK_ONLY_ARGUMENT = 'r',
+    KEEP_SILENT_ARGUMENT = 's',
+    TAGS_ARGUMENT = 't',
+    MOVES_ARGUMENT = 'v',
+    LINE_WIDTH_ARGUMENT = 'w',
+    POSITIONS_ARGUMENT = 'x',
+    ENDINGS_ARGUMENT = 'z',
+    FILE_OF_ARGUMENTS_ARGUMENT = 'A',
+    DONT_KEEP_COMMENTS_ARGUMENT = 'C',
+    DONT_KEEP_DUPLICATES_ARGUMENT = 'D',
+    ECO_OUTPUT_LEVEL_ARGUMENT = 'E',
+    OUTPUT_FEN_STRING_ARGUMENT = 'F',
+    APPEND_TO_LOG_FILE_ARGUMENT = 'L',
+    MATCH_CHECKMATE_ARGUMENT = 'M',
+    DONT_KEEP_NAGS_ARGUMENT = 'N',
+    DONT_MATCH_PERMUTATIONS_ARGUMENT = 'P',
+    TAG_ROSTER_ARGUMENT = 'R',
+    USE_SOUNDEX_ARGUMENT = 'S',
+    TAG_EXTRACTION_ARGUMENT = 'T',
+    SUPPRESS_ORIGINALS_ARGUMENT = 'U',
+    DONT_KEEP_VARIATIONS_ARGUMENT = 'V',
+    OUTPUT_FORMAT_ARGUMENT = 'W',
+    USE_VIRTUAL_HASH_TABLE_ARGUMENT = 'Z',
+    NO_ARGUMENT_MATCH = '\0'        /* No argument match. */
+} ArgType;
+
+void read_args_file(const char *infile);
+void process_argument(char arg_letter,const char *associated_value);
+int process_long_form_argument(const char *argument, const char *associated_value);
diff --git a/bool.h b/bool.h
new file mode 100644 (file)
index 0000000..abffaad
--- /dev/null
+++ b/bool.h
@@ -0,0 +1,26 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+        /* Define a type for Booleans.
+         * This is used everywhere.
+         */
+typedef enum { FALSE, TRUE } Boolean;
diff --git a/decode.c b/decode.c
new file mode 100644 (file)
index 0000000..fa87d3d
--- /dev/null
+++ b/decode.c
@@ -0,0 +1,653 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+            /* This file contains functions concerned with decoding
+             * the original text of a move in order to determine
+             *                 which MoveClass it is in,
+             *                any start and end square information.
+             * It extracts this information purely from the move text
+             * rather than analysing the move within the context of
+             * a board position.
+             * This information is later refined by the semantic analysis
+             * phase of the program as part of the checking of a game score.
+             */
+
+#include <stdio.h>
+#include <string.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "decode.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "lex.h"
+
+        /* Does the character represent a column of the board? */
+Boolean
+is_col(char c)
+{
+    return (FIRSTCOL <= c) && (c <= LASTCOL);
+}
+
+        /* Does the character represent a rank of the board? */
+Boolean
+is_rank(char c)
+{
+    return (FIRSTRANK <= c) && (c <= LASTRANK);
+}
+
+        /* What kind of piece is *move likely to represent?
+         * Note, the provision for double-character pieces,
+         * like a Russian King, means we need access to a
+         * string rather than a single char.
+         */
+Piece
+is_piece(const unsigned char *move)
+{   Piece piece = EMPTY;
+
+    switch(*move){
+        case 'K': case 'k':
+            piece = KING;
+            break;
+        case 'Q': case 'q':
+        case 'D': /* Dutch/German. */
+        case RUSSIAN_QUEEN:
+            piece = QUEEN;
+            break;
+        case 'R': case 'r':
+        case 'T': /* Dutch/German. */
+        case RUSSIAN_ROOK:
+            piece = ROOK;
+            break;
+        case 'N': case 'n':
+        case 'P': /* Dutch. */
+        case 'S': /* German. */
+            piece = KNIGHT;
+            break;
+        case 'B': 
+        case 'L': /* Dutch/German. */
+        case RUSSIAN_BISHOP:
+            /* Lower case 'b' is most likely to be a pawn reference. */
+            piece = BISHOP;
+            break;
+        case RUSSIAN_KNIGHT_OR_KING:
+            if(RUSSIAN_PIECE_CHECK(*(move+1)) == RUSSIAN_KING_SECOND_LETTER){
+                piece = KING;
+            }
+            else{
+                piece = KNIGHT;
+            }
+            break;
+    }
+    return piece;
+}
+
+        /* Is the symbol a capturing one?
+         * In fact, this is used to recognise any general separator
+         * between two parts of a move, e.g.:
+         *        Nxc3, e2-e4, etc.
+         */
+
+static Boolean
+is_capture(char c)
+{
+    return (c == 'x') || (c == 'X') || (c == ':') || (c == '-');
+}
+
+static Boolean
+is_castling_character(char c)
+{
+    return (c == 'O') || (c == '0') || (c == 'o');
+}
+
+Boolean
+is_check(char c)
+{
+    return (c == '+') || (c == '#');
+}
+
+        /* Allocate space in which to return the information that
+         * has been gleaned from the move.
+         */
+Move *
+new_move_structure(void)
+{   Move *move = (Move *)MallocOrDie(sizeof(Move));
+
+    move->terminating_result = NULL;
+    move->epd = NULL;
+    move->Nags = NULL;
+    move->Comment = NULL;
+    move->Variants = NULL;
+    move->next = NULL;
+    return move;
+}
+
+        /* Work out whatever can be gleaned from move_string of
+         * the starting and ending points of the given move.
+         * The move may be any legal string.
+         * The scanning here is libertarian, so it relies heavily on
+         * illegal moves having already been filtered out by the process
+         * of lexical analysis.
+         */
+Move *
+decode_move(const unsigned char *move_string)
+{   /* The four components of the co-ordinates when known. */
+    Rank from_rank = 0, to_rank = 0;
+    Col from_col = 0, to_col = 0;
+    MoveClass class;
+    Boolean Ok = TRUE;
+    /* Temporary locations until known whether they are from_ or to_. */
+    Col col = 0;
+    Rank rank = 0;
+    /* A pointer to move along the move string. */
+    const unsigned char *move = move_string;
+    /* A pointer to the structure containing the details to be returned. */
+    Move *move_details;
+    Piece piece_to_move = EMPTY;
+
+    /* Make an initial distinction between pawn moves and piece moves. */
+    if(is_col(*move)){
+        /* Pawn move. */
+        class = PAWN_MOVE;
+        piece_to_move = PAWN;
+        col = *move;
+        move++;
+        if(is_rank(*move)){
+            /* e4, e2e4 */
+            rank = *move;
+            move++;
+            if(is_capture(*move)){
+                move++;
+            }
+            if(is_col(*move)){
+                from_col = col;
+                from_rank = rank;
+                to_col = *move;
+                move++;
+                if(is_rank(*move)){
+                    to_rank = *move;
+                    move++;
+                }
+            }
+            else{
+                to_col = col;
+                to_rank = rank;
+            }
+        }
+        else{
+            if(is_capture(*move)){
+                /* axb */
+                move++;
+            }
+            if(is_col(*move)){
+                /* ab, or bg8 for liberal bishop moves. */
+                from_col = col;
+                to_col = *move;
+                move++;
+                if(is_rank(*move)){
+                    to_rank = *move;
+                    move++;
+                    /* Check the sanity of this. */
+                    if((from_col != 'b') &&
+                            (from_col != (to_col+1)) && (from_col != (to_col-1))){
+                        Ok = FALSE;
+                    }
+                }
+                else{
+                    /* Check the sanity of this. */
+                    if((from_col != (to_col+1)) && (from_col != (to_col-1))){
+                        Ok = FALSE;
+                    }
+                }
+            }
+            else{
+                print_error_context(GlobalState.logfile);
+                fprintf(GlobalState.logfile,"Unknown pawn move %s.\n",move_string);
+                Ok = FALSE;
+            }
+        }
+        if(Ok){
+            /* Look for promotions. */
+            if(*move == '='){
+                move++;
+            }
+            if(is_piece(move) != EMPTY){
+                class = PAWN_MOVE_WITH_PROMOTION;
+                /* @@@ Strictly speaking, if the piece is a RUSSIAN_KING
+                 * then we should skip two chars.
+                 */
+                move++;
+            }
+        }
+    }
+    else if((piece_to_move = is_piece(move)) != EMPTY){
+        class = PIECE_MOVE;
+        /* Check for a two-character piece. */
+        if((RUSSIAN_PIECE_CHECK(*move) == RUSSIAN_KNIGHT_OR_KING) &&
+                                (piece_to_move == KING)){
+            move++;
+        }
+        move++;
+        if(is_rank(*move)){
+            /* A disambiguating rank.
+             * R1e1, R1xe3.
+             */
+            from_rank = *move;
+            move++;
+            if(is_capture(*move)){
+                move++;
+            }
+            if(is_col(*move)){
+                to_col = *move;
+                move++;
+                if(is_rank(*move)){
+                    to_rank = *move;
+                    move++;
+                }
+            }
+            else{
+                Ok = FALSE;
+                print_error_context(GlobalState.logfile);
+                fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
+            }
+        }
+        else{
+            if(is_capture(*move)){
+                /* Rxe1 */
+                move++;
+                if(is_col(*move)){
+                    to_col = *move;
+                    move++;
+                    if(is_rank(*move)){
+                        to_rank = *move;
+                        move++;
+                    }
+                    else{
+                        Ok = FALSE;
+                        print_error_context(GlobalState.logfile);
+                        fprintf(GlobalState.logfile,
+                                        "Unknown piece move %s.\n",move_string);
+                    }
+                }
+                else{
+                    Ok = FALSE;
+                    print_error_context(GlobalState.logfile);
+                    fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
+                }
+            }
+            else if(is_col(*move)){
+                col = *move;
+                move++;
+                if(is_capture(*move)){
+                    move++;
+                }
+                if(is_rank(*move)){
+                    /* Re1, Re1d1, Re1xd1 */
+                    rank = *move;
+                    move++;
+                    if(is_capture(*move)){
+                        move++;
+                    }
+                    if(is_col(*move)){
+                        /* Re1d1 */
+                        from_col = col;
+                        from_rank = rank;
+                        to_col = *move;
+                        move++;
+                        if(is_rank(*move)){
+                            to_rank = *move;
+                            move++;
+                        }
+                        else{
+                            Ok = FALSE;
+                            print_error_context(GlobalState.logfile);
+                            fprintf(GlobalState.logfile,
+                                        "Unknown piece move %s.\n",move_string);
+                        }
+                    }
+                    else{
+                        to_col = col;
+                        to_rank = rank;
+                    }
+                }
+                else if(is_col(*move)){
+                    /* Rae1 */
+                    from_col = col;
+                    to_col = *move;
+                    move++;
+                    if(is_rank(*move)){
+                        to_rank = *move;
+                        move++;
+                    }
+                }
+                else{
+                    Ok = FALSE;
+                    print_error_context(GlobalState.logfile);
+                    fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
+                }
+            }
+            else{
+                Ok = FALSE;
+                print_error_context(GlobalState.logfile);
+                fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
+            }
+        }
+    }
+    else if(is_castling_character(*move)){
+         /* Some form of castling. */
+         move++;
+         /* Allow separators to be optional. */
+         if(*move == '-'){
+             move++;
+         }
+         if(is_castling_character(*move)){
+             move++;
+             if(*move == '-'){
+                 move++;
+             }
+             if(is_castling_character(*move)){
+                 class = QUEENSIDE_CASTLE;
+                 move++;
+             }
+             else{
+                 class = KINGSIDE_CASTLE;
+             }
+         }
+         else{
+             print_error_context(GlobalState.logfile);
+             fprintf(GlobalState.logfile,"Unknown castling move %s.\n",move_string);
+             Ok = FALSE;
+         }
+    }
+    else if(strcmp((char *) move_string, NULL_MOVE_STRING) == 0) {
+        class = NULL_MOVE;
+    }
+    else{
+        print_error_context(GlobalState.logfile);
+        fprintf(GlobalState.logfile,"Unknown move %s.\n",move_string);
+        Ok = FALSE;
+    }
+    if(Ok && class != NULL_MOVE){
+        /* Allow trailing checks. */
+        while(is_check(*move)){
+            move++;
+        }
+        if(*move == '\0'){
+            /* Nothing more to check. */
+        }
+        else if(((strcmp((const char *) move,"ep") == 0) ||
+                            (strcmp((const char *) move,"e.p.") == 0)) &&
+                (class == PAWN_MOVE)){
+            /* These are ok. */
+            class = ENPASSANT_PAWN_MOVE;
+        }
+        else{
+            Ok = FALSE;
+            print_error_context(GlobalState.logfile);
+            fprintf(GlobalState.logfile,
+                "Unknown text trailing move %s <%s>.\n",move_string,move);
+        }
+    }
+    /* Store all of the details gathered, even if the move is illegal. */
+    if(!Ok){
+        class = UNKNOWN_MOVE;
+    }
+    move_details = new_move_structure();
+    strcpy((char *) move_details->move,(const char *) move_string);
+    move_details->class = class;
+    move_details->piece_to_move = piece_to_move;
+    move_details->from_col = from_col;
+    move_details->from_rank = from_rank;
+    move_details->to_col = to_col;
+    move_details->to_rank = to_rank;
+    move_details->captured_piece = EMPTY;
+    move_details->check_status = NOCHECK;
+    return move_details;
+}
+
+Move *
+decode_algebraic(Move *move_details, Board *board)
+{   short from_r = RankConvert(move_details->from_rank);
+    short from_c = ColConvert(move_details->from_col);
+    Piece piece_to_move = EXTRACT_PIECE(board->board[from_r][from_c]);
+
+    if(piece_to_move != EMPTY){
+        /* Check for the special case of castling. */
+        if((piece_to_move == KING) && (move_details->from_col == 'e')){
+           if(move_details->to_col == 'g'){
+                move_details->class = KINGSIDE_CASTLE;
+            }
+            else if(move_details->to_col == 'c'){
+                move_details->class = QUEENSIDE_CASTLE;
+            }
+            else{
+                move_details->class = PIECE_MOVE;
+                move_details->piece_to_move = piece_to_move;
+            }
+        }
+        else{
+            if(piece_to_move == PAWN){
+                move_details->class = PAWN_MOVE;
+            }
+            else{
+                move_details->class = PIECE_MOVE;
+            }
+            move_details->piece_to_move = piece_to_move;
+        }
+        move_details->captured_piece = EMPTY;
+        move_details->check_status = NOCHECK;
+    }
+    return move_details;
+}
+
+        /* See if move_string seems to represent the text of a valid move.
+         * Don't print any error messages, just return TRUE or FALSE.
+         */
+Boolean
+move_seems_valid(const unsigned char *move_string)
+{   MoveClass class;
+    Boolean Ok = TRUE;
+    /* A pointer to move along the move string. */
+    unsigned const char *move = move_string;
+
+    /* Make an initial distinction between pawn moves and piece moves. */
+    if(is_col(*move)){
+        /* Pawn move. */
+        class = PAWN_MOVE;
+        move++;
+        if(is_rank(*move)){
+            /* e4, e2e4 */
+            move++;
+            if(is_capture(*move)){
+                move++;
+            }
+            if(is_col(*move)){
+                move++;
+                if(is_rank(*move)){
+                    move++;
+                }
+            }
+            else{
+            }
+        }
+        else{
+            if(is_capture(*move)){
+                /* axb */
+                move++;
+            }
+            if(is_col(*move)){
+                /* ab */
+                move++;
+                if(is_rank(*move)){
+                    move++;
+                }
+            }
+            else{
+                Ok = FALSE;
+            }
+        }
+        if(Ok){
+            /* Look for promotions. */
+            if(*move == '='){
+                move++;
+            }
+            if(is_piece(move) != EMPTY){
+                class = PAWN_MOVE_WITH_PROMOTION;
+                /* @@@ Strictly speaking, if the piece is a RUSSIAN_KING
+                 * then we should skip two chars.
+                 */
+                move++;
+            }
+        }
+    }
+    else if(is_piece(move) != EMPTY){
+        class = PIECE_MOVE;
+        /* Check for a two-character piece. */
+        if((RUSSIAN_PIECE_CHECK(*move) == RUSSIAN_KNIGHT_OR_KING) &&
+                        (is_piece(move) == KING)){
+            move++;
+        }
+        move++;
+        if(is_rank(*move)){
+            /* A disambiguating rank.
+             * R1e1, R1xe3.
+             */
+            move++;
+            if(is_capture(*move)){
+                move++;
+            }
+            if(is_col(*move)){
+                move++;
+                if(is_rank(*move)){
+                    move++;
+                }
+            }
+            else{
+                Ok = FALSE;
+            }
+        }
+        else{
+            if(is_capture(*move)){
+                /* Rxe1 */
+                move++;
+                if(is_col(*move)){
+                    move++;
+                    if(is_rank(*move)){
+                        move++;
+                    }
+                    else{
+                        Ok = FALSE;
+                    }
+                }
+                else{
+                    Ok = FALSE;
+                }
+            }
+            else if(is_col(*move)){
+                move++;
+                if(is_capture(*move)){
+                    move++;
+                }
+                if(is_rank(*move)){
+                    /* Re1, Re1d1, Re1xd1 */
+                    move++;
+                    if(is_capture(*move)){
+                        move++;
+                    }
+                    if(is_col(*move)){
+                        /* Re1d1 */
+                        move++;
+                        if(is_rank(*move)){
+                            move++;
+                        }
+                        else{
+                            Ok = FALSE;
+                        }
+                    }
+                }
+                else if(is_col(*move)){
+                    /* Rae1 */
+                    move++;
+                    if(is_rank(*move)){
+                        move++;
+                    }
+                    else{
+                        Ok = FALSE;
+                    }
+                }
+                else{
+                    Ok = FALSE;
+                }
+            }
+            else{
+                Ok = FALSE;
+            }
+        }
+    }
+    else if(is_castling_character(*move)){
+         /* Some form of castling. */
+         move++;
+         /* Allow separators to be optional. */
+         if(*move == '-'){
+             move++;
+         }
+         if(is_castling_character(*move)){
+             move++;
+             if(*move == '-'){
+                 move++;
+             }
+             if(is_castling_character(*move)){
+                 class = QUEENSIDE_CASTLE;
+                 move++;
+             }
+             else{
+                 class = KINGSIDE_CASTLE;
+             }
+         }
+         else{
+             Ok = FALSE;
+         }
+    }
+    else{
+        Ok = FALSE;
+    }
+    if(Ok){
+        /* Allow trailing checks. */
+        while(is_check(*move)){
+            move++;
+        }
+        if(*move == '\0'){
+            /* Nothing more to check. */
+        }
+        else if(((strcmp((const char *) move,"ep") == 0) ||
+                        (strcmp((const char *) move,"e.p.") == 0)) &&
+                (class == PAWN_MOVE)){
+            /* These are ok. */
+            class = ENPASSANT_PAWN_MOVE;
+        }
+        else{
+            Ok = FALSE;
+        }
+    }
+    return Ok;
+}
diff --git a/decode.h b/decode.h
new file mode 100644 (file)
index 0000000..6b5ff2a
--- /dev/null
+++ b/decode.h
@@ -0,0 +1,30 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+Move *new_move_structure(void);
+Piece is_piece(const unsigned char *move);
+Move *decode_move(const unsigned char *move_string);
+Move *decode_algebraic(Move *move_details, Board *board);
+Boolean is_check(char c);
+Boolean is_col(char c);
+Boolean is_rank(char c);
+Boolean move_seems_valid(const unsigned char *move_string);
diff --git a/defs.h b/defs.h
new file mode 100644 (file)
index 0000000..e98a7f7
--- /dev/null
+++ b/defs.h
@@ -0,0 +1,129 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+
+/* These colour values are used as modifiers of the Piece values to
+ * produce pieces of the appropriate colours.
+ * A coloured piece is formed by shifting the piece value and setting the
+ * bottom bit to either 0 (BLACK) or 1 (WHITE).
+ */
+typedef enum { BLACK, WHITE } Colour;
+typedef enum {
+    OFF, EMPTY,
+    /* The order of these is important and used in several places.
+     * In particular, several for-loops iterate from PAWN to KING.
+     */
+    PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING,
+    /* Must be last. */
+    NUM_PIECE_VALUES
+} Piece;
+/* Different classes of move determined by the lexical analyser. */
+typedef enum { PAWN_MOVE, PAWN_MOVE_WITH_PROMOTION, ENPASSANT_PAWN_MOVE,
+               PIECE_MOVE, KINGSIDE_CASTLE, QUEENSIDE_CASTLE,
+              NULL_MOVE,
+               UNKNOWN_MOVE
+             } MoveClass;
+
+/* Types for algebraic rank and column. */
+typedef char Rank;
+typedef char Col;
+
+/* Define the base characters for ranks and columns. */
+#define RANKBASE '1'
+#define COLBASE 'a'
+#define FIRSTRANK (RANKBASE)
+#define LASTRANK (RANKBASE+BOARDSIZE-1)
+#define FIRSTCOL (COLBASE)
+#define LASTCOL (COLBASE+BOARDSIZE-1)
+
+/* Convert the given rank to the correct index into a board. */
+#define RankConvert(rank) ((FIRSTRANK <= (rank)) && ((rank) <= LASTRANK)?\
+                                        ((rank)-RANKBASE+HEDGE):0)
+/* Convert the given column to the correct index into a board. */
+#define ColConvert(col) ((FIRSTCOL <= (col)) && ((col) <= LASTCOL)?\
+                                        ((col)-COLBASE+HEDGE):0)
+
+/* Convert a board index back to Rank or Col form. */
+#define ToRank(r) ((r)+RANKBASE-HEDGE)
+#define ToCol(c) ((c)+COLBASE-HEDGE)
+#define COLOUR_OFFSET(colour) (((colour) == WHITE)? 1 : -1)
+
+#define BOARDSIZE 8
+/* Define the size of a hedge around the board.
+ * This should have a size of 2 to make calculation of Knight moves easier.
+ */
+#define HEDGE 2
+
+/* Define a type for position hashing. */
+typedef unsigned long HashCode;
+
+typedef struct {
+    Piece board[HEDGE+BOARDSIZE+HEDGE][HEDGE+BOARDSIZE+HEDGE];
+    /* Who has the next move. */
+    Colour to_move;
+    /* The current move number. */
+    unsigned move_number;
+    /* Are the following castling options available? */
+    Boolean WKingCastle, WQueenCastle;
+    Boolean BKingCastle, BQueenCastle;
+    /* Keep track of where the two kings are, to make check-detection
+     * simple.
+     */
+    Col WKingCol; Rank WKingRank;
+    Col BKingCol; Rank BKingRank;
+    /* Is EnPassant capture possible?  If so then ep_rank and ep_col have
+     * the square on which this can be made.
+     */
+    Boolean EnPassant;
+    Rank ep_rank;
+    Col ep_col;
+    HashCode hash_value;
+    /* The half-move clock since the last pawn move or capture. */
+    unsigned halfmove_clock;
+} Board;
+
+/* Define a type that can be used to create a list of possible source
+ * squares for a move.
+ */
+typedef struct move_pair {
+    Col from_col;
+    Rank from_rank;
+    Col to_col;
+    Rank to_rank;
+    struct move_pair *next;
+} MovePair;
+    
+/* Conversion macros. */
+#define PIECE_SHIFT 3
+#define MAKE_COLOURED_PIECE(colour,piece) (((piece) << PIECE_SHIFT) | (colour))
+#define W(piece) MAKE_COLOURED_PIECE(WHITE,piece)
+#define B(piece) MAKE_COLOURED_PIECE(BLACK,piece)
+/* Conversion macro, from one colour to another. */
+#define OPPOSITE_COLOUR(colour) (!(colour))
+#define EXTRACT_COLOUR(coloured_piece) ((coloured_piece) & 0x01)
+#define EXTRACT_PIECE(coloured_piece) ((coloured_piece) >> PIECE_SHIFT)
+
+/* The string for internally representing the non-standard PGN
+ * notation for null moves.
+ */
+#define NULL_MOVE_STRING ("--")
+
diff --git a/eco.c b/eco.c
new file mode 100644 (file)
index 0000000..6a0d920
--- /dev/null
+++ b/eco.c
@@ -0,0 +1,328 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "map.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "lex.h"
+#include "eco.h"
+#include "apply.h"
+
+/* Place a limit on how distant a position may be from the ECO line
+ * it purports to match. This is to try to stop collisions way past
+ * where the line could still be active.
+ */
+#define ECO_HALF_MOVE_LIMIT 6
+/* Keep track of the longest ECO line, in half moves, plus
+ * ECO_HALF_MOVE_LIMIT.
+ * If a line exceeds this length, don't bother attempting
+ * a match.
+ */
+static unsigned maximum_half_moves = ECO_HALF_MOVE_LIMIT;
+
+/* Define a table to hold hash values of the ECO positions.
+ * This is used to enable duplicate detection.
+ */
+#define ECO_TABLE_SIZE 4096
+static EcoLog **EcoTable;
+
+#if INCLUDE_UNUSED_FUNCTIONS
+static void
+dumpEcoTable(void)
+{   unsigned ix;
+    for(ix = 0; ix < ECO_TABLE_SIZE; ix++){
+        if(EcoTable[ix] != NULL){
+            EcoLog *entry = NULL;
+            for(entry = EcoTable[ix]; entry != NULL; entry = entry->next){
+                fprintf(stderr,"%s %lu %lu ",entry->ECO_tag,
+                                entry->required_hash_value,
+                                entry->cumulative_hash_value);
+            }
+            fprintf(stderr,"\n");
+        }
+    }
+}
+
+        /* Return at how many points this match works.
+         *        required_hash_value
+         *            cumulative_hash_value
+         * This is a heuristic attempt to permit later
+         * longer matches to be chosen in preference to
+         * earlier shorter matches, while avoiding the
+         * greater probability of false matches when there
+         * are a lot of ECO lines and we are further into
+         * a game.
+         */
+static int
+eco_match_level(EcoLog *entry,HashCode current_hash_value,
+                HashCode cumulative_hash_value,unsigned half_moves_played)
+{
+    int level = 0;
+    if(entry != NULL){
+        if(entry->required_hash_value == current_hash_value){
+            level++;
+            if(entry->cumulative_hash_value == cumulative_hash_value){
+            level++;
+                if(entry->half_moves == half_moves_played){
+                    level++;
+                }
+            }
+        }
+    }
+    return level;
+}
+
+/* Quality values for aspects of an ECO match.
+ * Currently unused.
+ */
+static int ECO_REQUIRED_HASH_VALUE = 1;
+static int ECO_HALF_MOVE_VALUE = 1;
+static int ECO_CUMULATIVE_HASH_VALUE = 0;
+
+/* Rate the quality of the given match.
+ * Currently unused.
+ */
+static int eco_match_quality(EcoLog* entry,
+                      HashCode current_hash_value,
+                      HashCode cumulative_hash_value,
+                      int half_moves_played)
+{
+    int quality = 0;
+    if(entry->required_hash_value == current_hash_value){
+        quality += ECO_REQUIRED_HASH_VALUE;
+        if(abs(half_moves_played - entry->half_moves) <= ECO_HALF_MOVE_LIMIT) {
+            quality += ECO_HALF_MOVE_VALUE;
+        }
+        if(entry->cumulative_hash_value == cumulative_hash_value){
+            quality += ECO_CUMULATIVE_HASH_VALUE;
+        }
+    }
+    return quality;
+}
+#endif
+
+void initEcoTable(void)
+{
+    /* Avoid multiple calls. */
+    if(EcoTable == NULL){
+        int i;
+        EcoTable = (EcoLog **) MallocOrDie(ECO_TABLE_SIZE*sizeof(EcoLog *));
+
+        for(i = 0; i < ECO_TABLE_SIZE; i++){
+            EcoTable[i] = NULL;
+        }
+    }
+}
+
+        /* Enter the ECO details of game into EcoTable.
+         */
+void
+save_eco_details(Game game_details,unsigned number_of_half_moves)
+{   unsigned ix = game_details.final_hash_value % ECO_TABLE_SIZE;
+    EcoLog *entry = NULL;
+    /* Assume that it can be saved: that there is no collision. */
+    Boolean can_save = TRUE;
+    /* In an effort to save string space, keep a record of the
+     * last entry stored, because there is a good chance that it
+     * will have the same ECO_tag and Opening_tag as the next
+     * one.
+     */
+    static EcoLog *last_entry = NULL;
+
+    for(entry = EcoTable[ix]; (entry != NULL) && can_save; entry = entry->next){
+        if((entry->required_hash_value == game_details.final_hash_value) &&
+            (entry->half_moves == number_of_half_moves) &&
+            (entry->cumulative_hash_value == game_details.cumulative_hash_value)){
+            const char *tag = entry->ECO_tag,
+                       *opening = entry->Opening_tag,
+                       *variation = entry->Variation_tag;
+            if(tag == NULL){
+                tag = "";
+            }
+            if(opening == NULL){
+                opening = "";
+            }
+            if(variation == NULL){
+                variation = "";
+            }
+            fprintf(GlobalState.logfile,"ECO hash collision of ");
+            fprintf(GlobalState.logfile,"%s %s %s",tag,opening,variation);
+            fprintf(GlobalState.logfile," against ");
+            tag = game_details.tags[ECO_TAG];
+            opening = game_details.tags[OPENING_TAG];
+            variation = game_details.tags[VARIATION_TAG];
+            if(tag == NULL){
+                tag = "";
+            }
+            if(opening == NULL){
+                opening = "";
+            }
+            if(variation == NULL){
+                variation = "";
+            }
+            fprintf(GlobalState.logfile,"%s %s %s\n",tag,opening,variation);
+            fprintf(GlobalState.logfile,"Possible duplicate move sequences.\n");
+
+            can_save = FALSE;
+        }
+    }
+
+    if(can_save){
+        /* First occurrence, so add it to the log. */
+        entry = (EcoLog *)MallocOrDie(sizeof(*entry));
+
+        entry->required_hash_value = game_details.final_hash_value;
+        entry->cumulative_hash_value = game_details.cumulative_hash_value;
+        /* Keep a record of the current move number as a sanity
+         * check on matches.
+         */
+        entry->half_moves = number_of_half_moves;
+        /* Check for a new greater depth. */
+        if(number_of_half_moves+ECO_HALF_MOVE_LIMIT > maximum_half_moves){
+            maximum_half_moves = number_of_half_moves+ECO_HALF_MOVE_LIMIT;
+        }
+        if(game_details.tags[ECO_TAG] != NULL){
+            if((last_entry != NULL) && (last_entry->ECO_tag != NULL) &&
+                    (strcmp(last_entry->ECO_tag,game_details.tags[ECO_TAG]) == 0)){
+                /* Share the last entry's tag. */
+                entry->ECO_tag = last_entry->ECO_tag;
+            }
+            else{
+                entry->ECO_tag = copy_string(game_details.tags[ECO_TAG]);
+            }
+        }
+        else{
+            entry->ECO_tag = NULL;
+        }
+        if(game_details.tags[OPENING_TAG] != NULL){
+            if((last_entry != NULL) && (last_entry->Opening_tag != NULL) &&
+                    (strcmp(last_entry->Opening_tag,
+                                        game_details.tags[OPENING_TAG]) == 0)){
+                /* Share the last entry's tag. */
+                entry->Opening_tag = last_entry->Opening_tag;
+            }
+            else{
+                entry->Opening_tag = copy_string(game_details.tags[OPENING_TAG]);
+            }
+        }
+        else{
+            entry->Opening_tag = NULL;
+        }
+        if(game_details.tags[VARIATION_TAG] != NULL){
+            entry->Variation_tag = copy_string(game_details.tags[VARIATION_TAG]);
+        }
+        else{
+            entry->Variation_tag = NULL;
+        }
+        if(game_details.tags[SUB_VARIATION_TAG] != NULL){
+            entry->Sub_Variation_tag =
+                        copy_string(game_details.tags[SUB_VARIATION_TAG]);
+        }
+        else{
+            entry->Sub_Variation_tag = NULL;
+        }
+        /* Link it into the head at this index. */
+        entry->next =  EcoTable[ix];
+        EcoTable[ix] = entry;
+        /* Keep this one for next time around. */
+        last_entry = entry;
+    }
+}
+
+
+        /* Look in EcoTable for current_hash_value.
+         * Use cumulative_hash_value to refine the match.
+         * An exact match is preferable to a partial match.
+         */
+EcoLog *
+eco_matches(HashCode current_hash_value, HashCode cumulative_hash_value,
+            unsigned half_moves_played)
+{
+    EcoLog *possible = NULL;
+
+    /* Don't bother trying if we are too far on in the game.  */
+    if(half_moves_played <= maximum_half_moves){
+        /* Where to look. */
+        unsigned ix = current_hash_value % ECO_TABLE_SIZE;
+        EcoLog *entry;
+
+        for(entry = EcoTable[ix]; entry != NULL; entry = entry->next){
+            if(entry->required_hash_value == current_hash_value){
+                /* See if we have a full match. */
+                if(half_moves_played == entry->half_moves &&
+                       entry->cumulative_hash_value == cumulative_hash_value){
+                    return entry;
+                }
+                else if(abs(half_moves_played-entry->half_moves) <=
+                            ECO_HALF_MOVE_LIMIT){
+                        /* Retain this as a possible. */
+                        possible = entry;
+                }
+                else{
+                    /* Ignore it, as the lines are too distant. */
+                }
+            }
+        }
+    }
+    return possible;
+} 
+
+        /* Depending upon the ECO_level and the eco string of the
+         * current game, open the correctly named ECO file.
+         */
+FILE *
+open_eco_output_file(EcoDivision ECO_level,const char *eco)
+{   /* Allow space for the maximum number of
+     * ECO digits plus a .pgn suffix.
+     */
+    static const char suffix[] = ".pgn";
+    enum { MAXNAME = MAX_ECO_LEVEL+sizeof(suffix)-1 };
+    static char filename[MAXNAME+1];
+
+    if((eco == NULL) || !isalpha((int) *eco)){
+        strcpy(filename,"noeco.pgn");
+    }
+    else if(ECO_level == DONT_DIVIDE){
+       fprintf(GlobalState.logfile,
+           "Internal error: ECO division in open_eco_output_file\n");
+       strcpy(filename,"noeco");
+    }
+    else if(ECO_level == DONT_DIVIDE){
+       fprintf(GlobalState.logfile,
+           "Internal error: ECO division in open_eco_output_file\n");
+       strcpy(filename,"noeco");
+    }
+    else{
+       strncpy(filename,eco,ECO_level);
+       filename[ECO_level] = '\0';
+       strcat(filename,suffix);
+    }
+    return must_open_file(filename,"a");
+}
diff --git a/eco.h b/eco.h
new file mode 100644 (file)
index 0000000..54afb0b
--- /dev/null
+++ b/eco.h
@@ -0,0 +1,46 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+        /* Define a type to hold hash values of interest. */
+typedef struct EcoLog {
+    HashCode required_hash_value;
+    /* cumulative_hash_value is used to disambiguate clashing
+     * final hash values in duplicate detection.
+     */
+    HashCode cumulative_hash_value;
+    /* How deep the line is, from the half_moves associated with
+     * the board when the line is played out.
+     */
+    unsigned half_moves;
+    const char *ECO_tag;
+    const char *Opening_tag;
+    const char *Variation_tag;
+    const char *Sub_Variation_tag;
+    struct EcoLog *next;
+} EcoLog;
+
+EcoLog *eco_matches(HashCode current_hash_value, HashCode cumulative_hash_value,
+                    unsigned half_moves_played);
+Boolean add_ECO(Game game_details);
+FILE *open_eco_output_file(EcoDivision ECO_level,const char *eco);
+void initEcoTable(void);
+void save_eco_details(Game game_details,unsigned number_of_moves);
diff --git a/eco.pgn b/eco.pgn
new file mode 100644 (file)
index 0000000..2c3fa4d
--- /dev/null
+++ b/eco.pgn
@@ -0,0 +1,12142 @@
+{
+A PGN file of ECO classifications distributed with the PGN extraction
+program, extract. I believe that the original file from which I
+generated this was put together by Ewart Shaw, Franz Hemmer and others,
+to whom appropriate thanks and acknowledgement is due.  Permission has
+been granted for its inclusion with the extract program, which is
+available from caissa.onenet.net and ftp.pitt.edu.
+
+David Barnes (D.J.Barnes@ukc.ac.uk)
+}
+
+[ECO "A00"]
+[Opening "Polish (Sokolsky) opening"]
+
+1. b4 *
+
+[ECO "A00"]
+[Opening "Polish"]
+[Variation "Tuebingen variation"]
+
+1. b4 Nh6 *
+
+[ECO "A00"]
+[Opening "Polish"]
+[Variation "Outflank variation"]
+
+1. b4 c6 *
+
+[ECO "A00"]
+[Opening "Benko's opening"]
+
+1. g3 *
+
+[ECO "A00"]
+[Opening "Lasker simul special"]
+
+1. g3 h5 *
+
+[ECO "A00"]
+[Opening "Benko's opening"]
+[Variation "reversed Alekhine"]
+
+1. g3 e5 2. Nf3 *
+
+[ECO "A00"]
+[Opening "Grob's attack"]
+
+1. g4 *
+
+[ECO "A00"]
+[Opening "Grob"]
+[Variation "spike attack"]
+
+1. g4 d5 2. Bg2 c6 3. g5 *
+
+[ECO "A00"]
+[Opening "Grob"]
+[Variation "Fritz gambit"]
+
+1. g4 d5 2. Bg2 Bxg4 3. c4 *
+
+[ECO "A00"]
+[Opening "Grob"]
+[Variation "Romford counter-gambit"]
+
+1. g4 d5 2. Bg2 Bxg4 3. c4 d4 *
+
+[ECO "A00"]
+[Opening "Clemenz (Mead's, Basman's or de Klerk's) opening"]
+
+1. h3 *
+
+[ECO "A00"]
+[Opening "Global opening"]
+
+1. h3 e5 2. a3 *
+
+[ECO "A00"]
+[Opening "Amar (Paris) opening"]
+
+1. Nh3 *
+
+[ECO "A00"]
+[Opening "Amar gambit"]
+
+1. Nh3 d5 2. g3 e5 3. f4 Bxh3 4. Bxh3 exf4 *
+
+[ECO "A00"]
+[Opening "Dunst (Sleipner, Heinrichsen) opening"]
+
+1. Nc3 *
+
+[ECO "A00"]
+[Opening "Dunst (Sleipner, Heinrichsen) opening"]
+
+1. Nc3 e5 *
+
+[ECO "A00"]
+[Opening "Battambang opening"]
+
+1. Nc3 e5 2. a3 *
+
+[ECO "A00"]
+[Opening "Novosibirsk opening"]
+
+1. Nc3 c5 2. d4 cxd4 3. Qxd4 Nc6 4. Qh4 *
+
+[ECO "A00"]
+[Opening "Anderssen's opening"]
+
+1. a3 *
+
+[ECO "A00"]
+[Opening "Ware (Meadow Hay) opening"]
+
+1. a4 *
+
+[ECO "A00"]
+[Opening "Crab opening"]
+
+1. a4 e5 2. h4 *
+
+[ECO "A00"]
+[Opening "Saragossa opening"]
+
+1. c3 *
+
+[ECO "A00"]
+[Opening "Mieses opening"]
+
+1. d3 *
+
+[ECO "A00"]
+[Opening "Mieses opening"]
+
+1. d3 e5 *
+
+[ECO "A00"]
+[Opening "Valencia opening"]
+
+1. d3 e5 2. Nd2 *
+
+[ECO "A00"]
+[Opening "Venezolana opening"]
+
+1. d3 c5 2. Nc3 Nc6 3. g3 *
+
+[ECO "A00"]
+[Opening "Van't Kruijs opening"]
+
+1. e3 *
+
+[ECO "A00"]
+[Opening "Amsterdam attack"]
+
+1. e3 e5 2. c4 d6 3. Nc3 Nc6 4. b3 Nf6 *
+
+[ECO "A00"]
+[Opening "Gedult's opening"]
+
+1. f3 *
+
+[ECO "A00"]
+[Opening "Hammerschlag (Fried fox/Pork chop opening)"]
+
+1. f3 e5 2. Kf2 *
+
+[ECO "A00"]
+[Opening "Anti-Borg (Desprez) opening"]
+
+1. h4 *
+
+[ECO "A00"]
+[Opening "Durkin's attack"]
+
+1. Na3 *
+
+[ECO "A01"]
+[Opening "Nimzovich-Larsen attack"]
+
+1. b3 *
+
+[ECO "A01"]
+[Opening "Nimzovich-Larsen attack"]
+[Variation "modern variation"]
+
+1. b3 e5 *
+
+[ECO "A01"]
+[Opening "Nimzovich-Larsen attack"]
+[Variation "Indian variation"]
+
+1. b3 Nf6 *
+
+[ECO "A01"]
+[Opening "Nimzovich-Larsen attack"]
+[Variation "classical variation"]
+
+1. b3 d5 *
+
+[ECO "A01"]
+[Opening "Nimzovich-Larsen attack"]
+[Variation "English variation"]
+
+1. b3 c5 *
+
+[ECO "A01"]
+[Opening "Nimzovich-Larsen attack"]
+[Variation "Dutch variation"]
+
+1. b3 f5 *
+
+[ECO "A01"]
+[Opening "Nimzovich-Larsen attack"]
+[Variation "Polish variation"]
+
+1. b3 b5 *
+
+[ECO "A01"]
+[Opening "Nimzovich-Larsen attack"]
+[Variation "symmetrical variation"]
+
+1. b3 b6 *
+
+[ECO "A02"]
+[Opening "Bird's opening"]
+
+1. f4 *
+
+[ECO "A02"]
+[Opening "Bird"]
+[Variation "From gambit"]
+
+1. f4 e5 *
+
+[ECO "A02"]
+[Opening "Bird"]
+[Variation "From gambit, Lasker variation"]
+
+1. f4 e5 2. fxe5 d6 3. exd6 Bxd6 4. Nf3 g5 *
+
+[ECO "A02"]
+[Opening "Bird"]
+[Variation "From gambit, Lipke variation"]
+
+1. f4 e5 2. fxe5 d6 3. exd6 Bxd6 4. Nf3 Nh6 5. d4 *
+
+[ECO "A02"]
+[Opening "Bird's opening, Swiss gambit"]
+
+1. f4 f5 2. e4 fxe4 3. Nc3 Nf6 4. g4 *
+
+[ECO "A02"]
+[Opening "Bird"]
+[Variation "Hobbs gambit"]
+
+1. f4 g5 *
+
+[ECO "A03"]
+[Opening "Bird's opening"]
+
+1. f4 d5 *
+
+[ECO "A03"]
+[Opening "Mujannah opening"]
+
+1. f4 d5 2. c4 *
+
+[ECO "A03"]
+[Opening "Bird's opening"]
+[Variation "Williams gambit"]
+
+1. f4 d5 2. e4 *
+
+[ECO "A03"]
+[Opening "Bird's opening"]
+[Variation "Lasker variation"]
+
+1. f4 d5 2. Nf3 Nf6 3. e3 c5 *
+
+[ECO "A04"]
+[Opening "Reti opening"]
+
+1. Nf3 *
+
+[ECO "A04"]
+[Opening "Reti v Dutch"]
+
+1. Nf3 f5 *
+
+[ECO "A04"]
+[Opening "Reti"]
+[Variation "Pirc-Lisitsin gambit"]
+
+1. Nf3 f5 2. e4 *
+
+[ECO "A04"]
+[Opening "Reti"]
+[Variation "Lisitsin gambit deferred"]
+
+1. Nf3 f5 2. d3 Nf6 3. e4 *
+
+[ECO "A04"]
+[Opening "Reti opening"]
+
+1. Nf3 d6 *
+
+[ECO "A04"]
+[Opening "Reti"]
+[Variation "Wade defence"]
+
+1. Nf3 d6 2. e4 Bg4 *
+
+[ECO "A04"]
+[Opening "Reti"]
+[Variation "Herrstroem gambit"]
+
+1. Nf3 g5 *
+
+[ECO "A05"]
+[Opening "Reti opening"]
+
+1. Nf3 Nf6 *
+
+[ECO "A05"]
+[Opening "Reti"]
+[Variation "King's Indian attack, Spassky's variation"]
+
+1. Nf3 Nf6 2. g3 b5 *
+
+[ECO "A05"]
+[Opening "Reti"]
+[Variation "King's Indian attack"]
+
+1. Nf3 Nf6 2. g3 g6 *
+
+[ECO "A05"]
+[Opening "Reti"]
+[Variation "King's Indian attack, Reti-Smyslov variation"]
+
+1. Nf3 Nf6 2. g3 g6 3. b4 *
+
+[ECO "A06"]
+[Opening "Reti opening"]
+
+1. Nf3 d5 *
+
+[ECO "A06"]
+[Opening "Reti"]
+[Variation "old Indian attack"]
+
+1. Nf3 d5 2. d3 *
+
+[ECO "A06"]
+[Opening "Santasiere's folly"]
+
+1. Nf3 d5 2. b4 *
+
+[ECO "A06"]
+[Opening "Tennison (Lemberg, Zukertort) gambit"]
+
+1. Nf3 d5 2. e4 *
+
+[ECO "A06"]
+[Opening "Reti"]
+[Variation "Nimzovich-Larsen attack"]
+
+1. Nf3 d5 2. b3 *
+
+[ECO "A07"]
+[Opening "Reti"]
+[Variation "King's Indian attack (Barcza system)"]
+
+1. Nf3 d5 2. g3 *
+
+[ECO "A07"]
+[Opening "Reti"]
+[Variation "King's Indian attack, Yugoslav variation"]
+
+1. Nf3 d5 2. g3 Nf6 3. Bg2 c6 4. O-O Bg4 *
+
+[ECO "A07"]
+[Opening "Reti"]
+[Variation "King's Indian attack, Keres variation"]
+
+1. Nf3 d5 2. g3 Bg4 3. Bg2 Nd7 *
+
+[ECO "A07"]
+[Opening "Reti"]
+[Variation "King's Indian attack"]
+
+1. Nf3 d5 2. g3 g6 *
+
+[ECO "A07"]
+[Opening "Reti"]
+[Variation "King's Indian attack, Pachman system"]
+
+1. Nf3 d5 2. g3 g6 3. Bg2 Bg7 4. O-O e5 5. d3 Ne7 *
+
+[ECO "A07"]
+[Opening "Reti"]
+[Variation "King's Indian attack (with ...c5)"]
+
+1. Nf3 d5 2. g3 c5 *
+
+[ECO "A08"]
+[Opening "Reti"]
+[Variation "King's Indian attack"]
+
+1. Nf3 d5 2. g3 c5 3. Bg2 *
+
+[ECO "A08"]
+[Opening "Reti"]
+[Variation "King's Indian attack, French variation"]
+
+1. Nf3 d5 2. g3 c5 3. Bg2 Nc6 4. O-O e6 5. d3 Nf6 6. Nbd2 Be7 7. e4 O-O 8.
+Re1 *
+
+[ECO "A09"]
+[Opening "Reti opening"]
+
+1. Nf3 d5 2. c4 *
+
+[ECO "A09"]
+[Opening "Reti"]
+[Variation "advance variation"]
+
+1. Nf3 d5 2. c4 d4 *
+
+[ECO "A09"]
+[Opening "Reti accepted"]
+
+1. Nf3 d5 2. c4 dxc4 *
+
+[ECO "A09"]
+[Opening "Reti accepted"]
+[Variation "Keres variation"]
+
+1. Nf3 d5 2. c4 dxc4 3. e3 Be6 *
+
+[ECO "A10"]
+[Opening "English opening"]
+
+1. c4 *
+
+[ECO "A10"]
+[Opening "English opening"]
+
+1. c4 g6 *
+
+[ECO "A10"]
+[Opening "English"]
+[Variation "Adorjan defence"]
+
+1. c4 g6 2. e4 e5 *
+
+[ECO "A10"]
+[Opening "English"]
+[Variation "Jaenisch gambit"]
+
+1. c4 b5 *
+
+[ECO "A10"]
+[Opening "English"]
+[Variation "Anglo-Dutch defense"]
+
+1. c4 f5 *
+
+[ECO "A11"]
+[Opening "English"]
+[Variation "Caro-Kann defensive system"]
+
+1. c4 c6 *
+
+[ECO "A12"]
+[Opening "English"]
+[Variation "Caro-Kann defensive system"]
+
+1. c4 c6 2. Nf3 d5 3. b3 *
+
+[ECO "A12"]
+[Opening "English"]
+[Variation "Torre defensive system"]
+
+1. c4 c6 2. Nf3 d5 3. b3 Nf6 4. g3 Bg4 *
+
+[ECO "A12"]
+[Opening "English"]
+[Variation "London defensive system"]
+
+1. c4 c6 2. Nf3 d5 3. b3 Nf6 4. g3 Bf5 *
+
+[ECO "A12"]
+[Opening "English"]
+[Variation "Caro-Kann defensive system"]
+
+1. c4 c6 2. Nf3 d5 3. b3 Nf6 4. Bb2 *
+
+[ECO "A12"]
+[Opening "English"]
+[Variation "Bled variation"]
+
+1. c4 c6 2. Nf3 d5 3. b3 Nf6 4. Bb2 g6 *
+
+[ECO "A12"]
+[Opening "English"]
+[Variation "New York (London) defensive system"]
+
+1. c4 c6 2. Nf3 d5 3. b3 Nf6 4. Bb2 Bf5 *
+
+[ECO "A12"]
+[Opening "English"]
+[Variation "Capablanca's variation"]
+
+1. c4 c6 2. Nf3 d5 3. b3 Nf6 4. Bb2 Bg4 *
+
+[ECO "A12"]
+[Opening "English"]
+[Variation "Caro-Kann defensive system, Bogolyubov variation"]
+
+1. c4 c6 2. Nf3 d5 3. b3 Bg4 *
+
+[ECO "A13"]
+[Opening "English opening"]
+
+1. c4 e6 *
+
+[ECO "A13"]
+[Opening "English"]
+[Variation "Romanishin gambit"]
+
+1. c4 e6 2. Nf3 Nf6 3. g3 a6 4. Bg2 b5 *
+
+[ECO "A13"]
+[Opening "English opening"]
+[Variation "Agincourt variation"]
+
+1. c4 e6 2. Nf3 d5 *
+
+[ECO "A13"]
+[Opening "English"]
+[Variation "Wimpey system"]
+
+1. c4 e6 2. Nf3 d5 3. b3 Nf6 4. Bb2 c5 5. e3 *
+
+[ECO "A13"]
+[Opening "English opening"]
+[Variation "Agincourt variation"]
+
+1. c4 e6 2. Nf3 d5 3. g3 *
+
+[ECO "A13"]
+[Opening "English"]
+[Variation "Kurajica defence"]
+
+1. c4 e6 2. Nf3 d5 3. g3 c6 *
+
+[ECO "A13"]
+[Opening "English"]
+[Variation "Neo-Catalan"]
+
+1. c4 e6 2. Nf3 d5 3. g3 Nf6 *
+
+[ECO "A13"]
+[Opening "English"]
+[Variation "Neo-Catalan accepted"]
+
+1. c4 e6 2. Nf3 d5 3. g3 Nf6 4. Bg2 dxc4 *
+
+[ECO "A14"]
+[Opening "English"]
+[Variation "Neo-Catalan declined"]
+
+1. c4 e6 2. Nf3 d5 3. g3 Nf6 4. Bg2 Be7 5. O-O *
+
+[ECO "A14"]
+[Opening "English"]
+[Variation "Symmetrical, Keres defence"]
+
+1. c4 e6 2. Nf3 d5 3. g3 Nf6 4. Bg2 Be7 5. O-O c5 6. cxd5 Nxd5 7. Nc3 Nc6 *
+
+[ECO "A15"]
+[Opening "English, 1...Nf6 (Anglo-Indian defense)"]
+
+1. c4 Nf6 *
+
+[ECO "A15"]
+[Opening "English orang-utan"]
+
+1. c4 Nf6 2. b4 *
+
+[ECO "A15"]
+[Opening "English opening"]
+
+1. c4 Nf6 2. Nf3 *
+
+[ECO "A16"]
+[Opening "English opening"]
+
+1. c4 Nf6 2. Nc3 *
+
+[ECO "A16"]
+[Opening "English"]
+[Variation "Anglo-Gruenfeld defense"]
+
+1. c4 Nf6 2. Nc3 d5 *
+
+[ECO "A16"]
+[Opening "English"]
+[Variation "Anglo-Gruenfeld, Smyslov defense"]
+
+1. c4 Nf6 2. Nc3 d5 3. cxd5 Nxd5 4. g3 g6 5. Bg2 Nxc3 *
+
+[ECO "A16"]
+[Opening "English"]
+[Variation "Anglo-Gruenfeld, Czech defense"]
+
+1. c4 Nf6 2. Nc3 d5 3. cxd5 Nxd5 4. g3 g6 5. Bg2 Nb6 *
+
+[ECO "A16"]
+[Opening "English"]
+[Variation "Anglo-Gruenfeld defense"]
+
+1. c4 Nf6 2. Nc3 d5 3. cxd5 Nxd5 4. Nf3 *
+
+[ECO "A16"]
+[Opening "English"]
+[Variation "Anglo-Gruenfeld defense, Korchnoi variation"]
+
+1. c4 Nf6 2. Nc3 d5 3. cxd5 Nxd5 4. Nf3 g6 5. g3 Bg7 6. Bg2 e5 *
+
+[ECO "A17"]
+[Opening "English opening"]
+
+1. c4 Nf6 2. Nc3 e6 *
+
+[ECO "A17"]
+[Opening "English"]
+[Variation "Queens Indian formation"]
+
+1. c4 Nf6 2. Nc3 e6 3. Nf3 b6 *
+
+[ECO "A17"]
+[Opening "English"]
+[Variation "Queens Indian, Romanishin variation"]
+
+1. c4 Nf6 2. Nc3 e6 3. Nf3 b6 4. e4 Bb7 5. Bd3 *
+
+[ECO "A17"]
+[Opening "English"]
+[Variation "Nimzo-English opening"]
+
+1. c4 Nf6 2. Nc3 e6 3. Nf3 Bb4 *
+
+[ECO "A18"]
+[Opening "English"]
+[Variation "Mikenas-Carls variation"]
+
+1. c4 Nf6 2. Nc3 e6 3. e4 *
+
+[ECO "A18"]
+[Opening "English"]
+[Variation "Mikenas-Carls, Flohr variation"]
+
+1. c4 Nf6 2. Nc3 e6 3. e4 d5 4. e5 *
+
+[ECO "A18"]
+[Opening "English"]
+[Variation "Mikenas-Carls, Kevitz variation"]
+
+1. c4 Nf6 2. Nc3 e6 3. e4 Nc6 *
+
+[ECO "A19"]
+[Opening "English"]
+[Variation "Mikenas-Carls, Sicilian variation"]
+
+1. c4 Nf6 2. Nc3 e6 3. e4 c5 *
+
+[ECO "A20"]
+[Opening "English opening"]
+
+1. c4 e5 *
+
+[ECO "A20"]
+[Opening "English, Nimzovich variation"]
+
+1. c4 e5 2. Nf3 *
+
+[ECO "A20"]
+[Opening "English, Nimzovich, Flohr variation"]
+
+1. c4 e5 2. Nf3 e4 *
+
+[ECO "A21"]
+[Opening "English opening"]
+
+1. c4 e5 2. Nc3 *
+
+[ECO "A21"]
+[Opening "English, Troeger defence"]
+
+1. c4 e5 2. Nc3 d6 3. g3 Be6 4. Bg2 Nc6 *
+
+[ECO "A21"]
+[Opening "English, Keres variation"]
+
+1. c4 e5 2. Nc3 d6 3. g3 c6 *
+
+[ECO "A21"]
+[Opening "English opening"]
+
+1. c4 e5 2. Nc3 d6 3. Nf3 *
+
+[ECO "A21"]
+[Opening "English, Smyslov defence"]
+
+1. c4 e5 2. Nc3 d6 3. Nf3 Bg4 *
+
+[ECO "A21"]
+[Opening "English, Kramnik-Shirov counterattack"]
+
+1. c4 e5 2. Nc3 Bb4 *
+
+[ECO "A22"]
+[Opening "English opening"]
+
+1. c4 e5 2. Nc3 Nf6 *
+
+[ECO "A22"]
+[Opening "English"]
+[Variation "Bellon gambit"]
+
+1. c4 e5 2. Nc3 Nf6 3. Nf3 e4 4. Ng5 b5 *
+
+[ECO "A22"]
+[Opening "English"]
+[Variation "Carls' Bremen system"]
+
+1. c4 e5 2. Nc3 Nf6 3. g3 *
+
+[ECO "A22"]
+[Opening "English"]
+[Variation "Bremen, reverse dragon"]
+
+1. c4 e5 2. Nc3 Nf6 3. g3 d5 *
+
+[ECO "A22"]
+[Opening "English"]
+[Variation "Bremen, Smyslov system"]
+
+1. c4 e5 2. Nc3 Nf6 3. g3 Bb4 *
+
+[ECO "A23"]
+[Opening "English"]
+[Variation "Bremen system, Keres variation"]
+
+1. c4 e5 2. Nc3 Nf6 3. g3 c6 *
+
+[ECO "A24"]
+[Opening "English"]
+[Variation "Bremen system with ...g6"]
+
+1. c4 e5 2. Nc3 Nf6 3. g3 g6 *
+
+[ECO "A25"]
+[Opening "English"]
+[Variation "Sicilian reversed"]
+
+1. c4 e5 2. Nc3 Nc6 *
+
+[ECO "A25"]
+[Opening "English"]
+[Variation "closed system"]
+
+1. c4 e5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 *
+
+[ECO "A25"]
+[Opening "English"]
+[Variation "closed, Taimanov variation"]
+
+1. c4 e5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. e3 d6 6. Nge2 Nh6 *
+
+[ECO "A25"]
+[Opening "English"]
+[Variation "closed, Hort variation"]
+
+1. c4 e5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. e3 d6 6. Nge2 Be6 *
+
+[ECO "A25"]
+[Opening "English"]
+[Variation "closed, 5.Rb1"]
+
+1. c4 e5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. Rb1 *
+
+[ECO "A25"]
+[Opening "English"]
+[Variation "closed, 5.Rb1 Taimanov variation"]
+
+1. c4 e5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. Rb1 Nh6 *
+
+[ECO "A25"]
+[Opening "English"]
+[Variation "closed system (without ...d6)"]
+
+1. c4 e5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. d3 *
+
+[ECO "A26"]
+[Opening "English"]
+[Variation "closed system"]
+
+1. c4 e5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. d3 d6 *
+
+[ECO "A26"]
+[Opening "English"]
+[Variation "Botvinnik system"]
+
+1. c4 e5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. d3 d6 6. e4 *
+
+[ECO "A27"]
+[Opening "English"]
+[Variation "three knights system"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 *
+
+[ECO "A28"]
+[Opening "English"]
+[Variation "four knights system"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 Nf6 *
+
+[ECO "A28"]
+[Opening "English"]
+[Variation "Nenarokov variation"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 Nf6 4. d4 exd4 5. Nxd4 Bb4 6. Bg5 h6 7. Bh4 
+Bxc3+ 8. bxc3 Ne5 *
+
+[ECO "A28"]
+[Opening "English"]
+[Variation "Bradley Beach variation"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 Nf6 4. d4 e4 *
+
+[ECO "A28"]
+[Opening "English"]
+[Variation "four knights, Nimzovich variation"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 Nf6 4. e4 *
+
+[ECO "A28"]
+[Opening "English"]
+[Variation "four knights, Marini variation"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 Nf6 4. a3 *
+
+[ECO "A28"]
+[Opening "English"]
+[Variation "four knights, Capablanca variation"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 Nf6 4. d3 *
+
+[ECO "A28"]
+[Opening "English"]
+[Variation "four knights, 4.e3"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 Nf6 4. e3 *
+
+[ECO "A28"]
+[Opening "English"]
+[Variation "four knights, Stean variation"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 Nf6 4. e3 Bb4 5. Qc2 O-O 6. Nd5 Re8 7. Qf5 *
+
+[ECO "A28"]
+[Opening "English"]
+[Variation "four knights, Romanishin variation"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 Nf6 4. e3 Bb4 5. Qc2 Bxc3 *
+
+[ECO "A29"]
+[Opening "English"]
+[Variation "four knights, kingside fianchetto"]
+
+1. c4 e5 2. Nc3 Nc6 3. Nf3 Nf6 4. g3 *
+
+[ECO "A30"]
+[Opening "English"]
+[Variation "symmetrical variation"]
+
+1. c4 c5 *
+
+[ECO "A30"]
+[Opening "English"]
+[Variation "symmetrical, hedgehog system"]
+
+1. c4 c5 2. Nf3 Nf6 3. g3 b6 4. Bg2 Bb7 5. O-O e6 6. Nc3 Be7 *
+
+[ECO "A30"]
+[Opening "English"]
+[Variation "symmetrical, hedgehog, flexible formation"]
+
+1. c4 c5 2. Nf3 Nf6 3. g3 b6 4. Bg2 Bb7 5. O-O e6 6. Nc3 Be7 7. d4 cxd4 8.
+Qxd4 d6 9. Rd1 a6 10. b3 Nbd7 *
+
+[ECO "A31"]
+[Opening "English"]
+[Variation "symmetrical, Benoni formation"]
+
+1. c4 c5 2. Nf3 Nf6 3. d4 *
+
+[ECO "A32"]
+[Opening "English"]
+[Variation "symmetrical variation"]
+
+1. c4 c5 2. Nf3 Nf6 3. d4 cxd4 4. Nxd4 e6 *
+
+[ECO "A33"]
+[Opening "English"]
+[Variation "symmetrical variation"]
+
+1. c4 c5 2. Nf3 Nf6 3. d4 cxd4 4. Nxd4 e6 5. Nc3 Nc6 *
+
+[ECO "A33"]
+[Opening "English"]
+[Variation "symmetrical, Geller variation"]
+
+1. c4 c5 2. Nf3 Nf6 3. d4 cxd4 4. Nxd4 e6 5. Nc3 Nc6 6. g3 Qb6 *
+
+[ECO "A34"]
+[Opening "English"]
+[Variation "symmetrical variation"]
+
+1. c4 c5 2. Nc3 *
+
+[ECO "A34"]
+[Opening "English"]
+[Variation "symmetrical, three knights system"]
+
+1. c4 c5 2. Nc3 Nf6 3. Nf3 d5 4. cxd5 Nxd5 *
+
+[ECO "A34"]
+[Opening "English"]
+[Variation "symmetrical variation"]
+
+1. c4 c5 2. Nc3 Nf6 3. g3 *
+
+[ECO "A34"]
+[Opening "English"]
+[Variation "symmetrical, Rubinstein system"]
+
+1. c4 c5 2. Nc3 Nf6 3. g3 d5 4. cxd5 Nxd5 5. Bg2 Nc7 *
+
+[ECO "A35"]
+[Opening "English"]
+[Variation "symmetrical variation"]
+
+1. c4 c5 2. Nc3 Nc6 *
+
+[ECO "A35"]
+[Opening "English"]
+[Variation "symmetrical, four knights system"]
+
+1. c4 c5 2. Nc3 Nc6 3. Nf3 Nf6 *
+
+[ECO "A36"]
+[Opening "English"]
+[Variation "symmetrical variation"]
+
+1. c4 c5 2. Nc3 Nc6 3. g3 *
+
+[ECO "A36"]
+[Opening "English"]
+[Variation "ultra-symmetrical variation"]
+
+1. c4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 *
+
+[ECO "A36"]
+[Opening "English"]
+[Variation "symmetrical, Botvinnik system reversed"]
+
+1. c4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. e3 e5 *
+
+[ECO "A36"]
+[Opening "English"]
+[Variation "symmetrical, Botvinnik system"]
+
+1. c4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. e4 *
+
+[ECO "A37"]
+[Opening "English"]
+[Variation "symmetrical variation"]
+
+1. c4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. Nf3 *
+
+[ECO "A37"]
+[Opening "English"]
+[Variation "symmetrical, Botvinnik system reversed"]
+
+1. c4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. Nf3 e5 *
+
+[ECO "A38"]
+[Opening "English"]
+[Variation "symmetrical variation"]
+
+1. c4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. Nf3 Nf6 *
+
+[ECO "A38"]
+[Opening "English"]
+[Variation "symmetrical, main line with d3"]
+
+1. c4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. Nf3 Nf6 6. O-O O-O 7. d3 *
+
+[ECO "A38"]
+[Opening "English"]
+[Variation "symmetrical, main line with b3"]
+
+1. c4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. Nf3 Nf6 6. O-O O-O 7. b3 *
+
+[ECO "A39"]
+[Opening "English"]
+[Variation "symmetrical, main line with d4"]
+
+1. c4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. Nf3 Nf6 6. O-O O-O 7. d4 *
+
+[ECO "A40"]
+[Opening "Queen's pawn"]
+
+1. d4 *
+
+[ECO "A40"]
+[Opening "Queen's pawn"]
+[Variation "Lundin (Kevitz-Mikenas) defence"]
+
+1. d4 Nc6 *
+
+[ECO "A40"]
+[Opening "Queen's pawn"]
+[Variation "Charlick (Englund) gambit"]
+
+1. d4 e5 *
+
+[ECO "A40"]
+[Opening "Queen's pawn"]
+[Variation "Englund gambit"]
+
+1. d4 e5 2. dxe5 Nc6 3. Nf3 Qe7 4. Qd5 f6 5. exf6 Nxf6 *
+
+[ECO "A40"]
+[Opening "Queen's pawn"]
+[Variation "English defence"]
+
+1. d4 b6 *
+
+[ECO "A40"]
+[Opening "Polish defence"]
+
+1. d4 b5 *
+
+[ECO "A40"]
+[Opening "Queen's pawn"]
+
+1. d4 e6 *
+
+[ECO "A40"]
+[Opening "Queen's pawn"]
+[Variation "Keres defence"]
+
+1. d4 e6 2. c4 b6 *
+
+[ECO "A40"]
+[Opening "Queen's pawn"]
+[Variation "Franco-Indian (Keres) defence"]
+
+1. d4 e6 2. c4 Bb4+ *
+
+[ECO "A40"]
+[Opening "Modern defence"]
+
+1. d4 g6 *
+
+[ECO "A40"]
+[Opening "Beefeater defence"]
+
+1. d4 g6 2. c4 Bg7 3. Nc3 c5 4. d5 Bxc3+ 5. bxc3 f5 *
+
+[ECO "A41"]
+[Opening "Queen's Pawn"]
+
+1. d4 d6 *
+
+[ECO "A41"]
+[Opening "Old Indian"]
+[Variation "Tartakower (Wade) variation"]
+
+1. d4 d6 2. Nf3 Bg4 *
+
+[ECO "A41"]
+[Opening "Old Indian defence"]
+
+1. d4 d6 2. c4 *
+
+[ECO "A41"]
+[Opening "Modern defence"]
+
+1. d4 d6 2. c4 g6 3. Nc3 Bg7 *
+
+[ECO "A41"]
+[Opening "Robatsch defence"]
+[Variation "Rossolimo variation"]
+
+1. e4 g6 2. d4 Bg7 3. Nf3 d6 4. c4 Bg4 *
+
+[ECO "A42"]
+[Opening "Modern defence"]
+[Variation "Averbakh system"]
+
+1. d4 d6 2. c4 g6 3. Nc3 Bg7 4. e4 *
+
+[ECO "A42"]
+[Opening "Pterodactyl defence"]
+
+1. d4 d6 2. c4 g6 3. Nc3 Bg7 4. e4 c5 5. Nf3 Qa5 *
+
+[ECO "A42"]
+[Opening "Modern defence"]
+[Variation "Averbakh system, Randspringer variation"]
+
+1. d4 d6 2. c4 g6 3. Nc3 Bg7 4. e4 f5 *
+
+[ECO "A42"]
+[Opening "Modern defence"]
+[Variation "Averbakh system, Kotov variation"]
+
+1. d4 d6 2. c4 g6 3. Nc3 Bg7 4. e4 Nc6 *
+
+[ECO "A43"]
+[Opening "Old Benoni defence"]
+
+1. d4 c5 *
+
+[ECO "A43"]
+[Opening "Old Benoni"]
+[Variation "Franco-Benoni defence"]
+
+1. d4 c5 2. d5 e6 3. e4 *
+
+[ECO "A43"]
+[Opening "Old Benoni"]
+[Variation "Mujannah formation"]
+
+1. d4 c5 2. d5 f5 *
+
+[ECO "A43"]
+[Opening "Old Benoni defence"]
+
+1. d4 c5 2. d5 Nf6 *
+
+[ECO "A43"]
+[Opening "Woozle defence"]
+
+1. d4 c5 2. d5 Nf6 3. Nc3 Qa5 *
+
+[ECO "A43"]
+[Opening "Old Benoni defence"]
+
+1. d4 c5 2. d5 Nf6 3. Nf3 *
+
+[ECO "A43"]
+[Opening "Hawk (Habichd) defence"]
+
+1. d4 c5 2. d5 Nf6 3. Nf3 c4 *
+
+[ECO "A43"]
+[Opening "Old Benoni defence"]
+
+1. d4 c5 2. d5 d6 *
+
+[ECO "A43"]
+[Opening "Old Benoni"]
+[Variation "Schmid's system"]
+
+1. d4 c5 2. d5 d6 3. Nc3 g6 *
+
+[ECO "A44"]
+[Opening "Old Benoni defence"]
+
+1. d4 c5 2. d5 e5 *
+
+[ECO "A44"]
+[Opening "Semi-Benoni (`blockade variation')"]
+
+1. d4 c5 2. d5 e5 3. e4 d6 *
+
+[ECO "A45"]
+[Opening "Queen's pawn game"]
+
+1. d4 Nf6 *
+
+[ECO "A45"]
+[Opening "Queen's pawn"]
+[Variation "Bronstein gambit"]
+
+1. d4 Nf6 2. g4 *
+
+[ECO "A45"]
+[Opening "Canard opening"]
+
+1. d4 Nf6 2. f4 *
+
+[ECO "A45"]
+[Opening "Paleface attack"]
+
+1. d4 Nf6 2. f3 *
+
+[ECO "A45"]
+[Opening "Blackmar-Diemer gambit"]
+
+1. d4 Nf6 2. f3 d5 3. e4 *
+
+[ECO "A45"]
+[Opening "Gedult attack"]
+
+1. d4 Nf6 2. f3 d5 3. g4 *
+
+[ECO "A45"]
+[Opening "Trompovsky attack (Ruth, Opovcensky opening)"]
+
+1. d4 Nf6 2. Bg5 *
+
+[ECO "A46"]
+[Opening "Queen's pawn game"]
+
+1. d4 Nf6 2. Nf3 *
+
+[ECO "A46"]
+[Opening "Queen's pawn"]
+[Variation "Torre attack"]
+
+1. d4 Nf6 2. Nf3 e6 3. Bg5 *
+
+[ECO "A46"]
+[Opening "Queen's pawn"]
+[Variation "Torre attack, Wagner gambit"]
+
+1. d4 Nf6 2. Nf3 e6 3. Bg5 c5 4. e4 *
+
+[ECO "A46"]
+[Opening "Queen's pawn"]
+[Variation "Yusupov-Rubinstein system"]
+
+1. d4 Nf6 2. Nf3 e6 3. e3 *
+
+[ECO "A46"]
+[Opening "Doery defence"]
+
+1. d4 Nf6 2. Nf3 Ne4 *
+
+[ECO "A47"]
+[Opening "Queen's Indian defence"]
+
+1. d4 Nf6 2. Nf3 b6 *
+
+[ECO "A47"]
+[Opening "Queen's Indian"]
+[Variation "Marienbad system"]
+
+1. d4 Nf6 2. Nf3 b6 3. g3 Bb7 4. Bg2 c5 *
+
+[ECO "A47"]
+[Opening "Queen's Indian"]
+[Variation "Marienbad system, Berg variation"]
+
+1. d4 Nf6 2. Nf3 b6 3. g3 Bb7 4. Bg2 c5 5. c4 cxd4 6. Qxd4 *
+
+[ECO "A48"]
+[Opening "King's Indian"]
+[Variation "East Indian defence"]
+
+1. d4 Nf6 2. Nf3 g6 *
+
+[ECO "A48"]
+[Opening "King's Indian"]
+[Variation "Torre attack"]
+
+1. d4 Nf6 2. Nf3 g6 3. Bg5 *
+
+[ECO "A48"]
+[Opening "King's Indian"]
+[Variation "London system"]
+
+1. d4 Nf6 2. Nf3 g6 3. Bf4 *
+
+[ECO "A49"]
+[Opening "King's Indian"]
+[Variation "fianchetto without c4"]
+
+1. d4 Nf6 2. Nf3 g6 3. g3 *
+
+[ECO "A50"]
+[Opening "Queen's pawn game"]
+
+1. d4 Nf6 2. c4 *
+
+[ECO "A50"]
+[Opening "Kevitz-Trajkovich defence"]
+
+1. d4 Nf6 2. c4 Nc6 *
+
+[ECO "A50"]
+[Opening "Queen's Indian accelerated"]
+
+1. d4 Nf6 2. c4 b6 *
+
+[ECO "A51"]
+[Opening "Budapest defence declined"]
+
+1. d4 Nf6 2. c4 e5 *
+
+[ECO "A51"]
+[Opening "Budapest"]
+[Variation "Fajarowicz variation"]
+
+1. d4 Nf6 2. c4 e5 3. dxe5 Ne4 *
+
+[ECO "A51"]
+[Opening "Budapest"]
+[Variation "Fajarowicz, Steiner variation"]
+
+1. d4 Nf6 2. c4 e5 3. dxe5 Ne4 4. Qc2 *
+
+[ECO "A52"]
+[Opening "Budapest defence"]
+
+1. d4 Nf6 2. c4 e5 3. dxe5 Ng4 *
+
+[ECO "A52"]
+[Opening "Budapest"]
+[Variation "Adler variation"]
+
+1. d4 Nf6 2. c4 e5 3. dxe5 Ng4 4. Nf3 *
+
+[ECO "A52"]
+[Opening "Budapest"]
+[Variation "Rubinstein variation"]
+
+1. d4 Nf6 2. c4 e5 3. dxe5 Ng4 4. Bf4 *
+
+[ECO "A52"]
+[Opening "Budapest"]
+[Variation "Alekhine variation"]
+
+1. d4 Nf6 2. c4 e5 3. dxe5 Ng4 4. e4 *
+
+[ECO "A52"]
+[Opening "Budapest"]
+[Variation "Alekhine, Abonyi variation"]
+
+1. d4 Nf6 2. c4 e5 3. dxe5 Ng4 4. e4 Nxe5 5. f4 Nec6 *
+
+[ECO "A52"]
+[Opening "Budapest"]
+[Variation "Alekhine variation, Balogh gambit"]
+
+1. d4 Nf6 2. c4 e5 3. dxe5 Ng4 4. e4 d6 *
+
+[ECO "A53"]
+[Opening "Old Indian defence"]
+
+1. d4 Nf6 2. c4 d6 *
+
+[ECO "A53"]
+[Opening "Old Indian"]
+[Variation "Janowski variation"]
+
+1. d4 Nf6 2. c4 d6 3. Nc3 Bf5 *
+
+[ECO "A54"]
+[Opening "Old Indian"]
+[Variation "Ukrainian variation"]
+
+1. d4 Nf6 2. c4 d6 3. Nc3 e5 *
+
+[ECO "A54"]
+[Opening "Old Indian"]
+[Variation "Dus-Khotimirsky variation"]
+
+1. d4 Nf6 2. c4 d6 3. Nc3 e5 4. e3 Nbd7 5. Bd3 *
+
+[ECO "A54"]
+[Opening "Old Indian"]
+[Variation "Ukrainian variation, 4.Nf3"]
+
+1. d4 Nf6 2. c4 d6 3. Nc3 e5 4. Nf3 *
+
+[ECO "A55"]
+[Opening "Old Indian"]
+[Variation "main line"]
+
+1. d4 Nf6 2. c4 d6 3. Nc3 e5 4. Nf3 Nbd7 5. e4 *
+
+[ECO "A56"]
+[Opening "Benoni defence"]
+
+1. d4 Nf6 2. c4 c5 *
+
+[ECO "A56"]
+[Opening "Benoni defence, Hromodka system"]
+
+1. d4 Nf6 2. c4 c5 3. d5 d6 *
+
+[ECO "A56"]
+[Opening "Vulture defence"]
+
+1. d4 Nf6 2. c4 c5 3. d5 Ne4 *
+
+[ECO "A56"]
+[Opening "Czech Benoni defence"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e5 *
+
+[ECO "A56"]
+[Opening "Czech Benoni"]
+[Variation "King's Indian system"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e5 4. Nc3 d6 5. e4 g6 *
+
+[ECO "A57"]
+[Opening "Benko gambit"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 *
+
+[ECO "A57"]
+[Opening "Benko gambit half accepted"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 4. cxb5 a6 *
+
+[ECO "A57"]
+[Opening "Benko gambit"]
+[Variation "Zaitsev system"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 4. cxb5 a6 5. Nc3 *
+
+[ECO "A57"]
+[Opening "Benko gambit"]
+[Variation "Nescafe Frappe attack"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 4. cxb5 a6 5. Nc3 axb5 6. e4 b4 7. Nb5 d6 8. 
+Bc4 *
+
+[ECO "A58"]
+[Opening "Benko gambit accepted"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 4. cxb5 a6 5. bxa6 *
+
+[ECO "A58"]
+[Opening "Benko gambit"]
+[Variation "Nd2 variation"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 4. cxb5 a6 5. bxa6 Bxa6 6. Nc3 d6 7. Nf3 g6 8.
+Nd2 *
+
+[ECO "A58"]
+[Opening "Benko gambit"]
+[Variation "fianchetto variation"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 4. cxb5 a6 5. bxa6 Bxa6 6. Nc3 d6 7. Nf3 g6 8.
+g3 *
+
+[ECO "A59"]
+[Opening "Benko gambit"]
+[Variation "7.e4"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 4. cxb5 a6 5. bxa6 Bxa6 6. Nc3 d6 7. e4 *
+
+[ECO "A59"]
+[Opening "Benko gambit"]
+[Variation "Ne2 variation"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 4. cxb5 a6 5. bxa6 Bxa6 6. Nc3 d6 7. e4 Bxf1 8.
+Kxf1 g6 9. Nge2 *
+
+[ECO "A59"]
+[Opening "Benko gambit"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 4. cxb5 a6 5. bxa6 Bxa6 6. Nc3 d6 7. e4 Bxf1 8.
+Kxf1 g6 9. g3 *
+
+[ECO "A59"]
+[Opening "Benko gambit"]
+[Variation "main line"]
+
+1. d4 Nf6 2. c4 c5 3. d5 b5 4. cxb5 a6 5. bxa6 Bxa6 6. Nc3 d6 7. e4 Bxf1 8.
+Kxf1 g6 9. g3 Bg7 10. Kg2 O-O 11. Nf3 *
+
+[ECO "A60"]
+[Opening "Benoni defence"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 *
+
+[ECO "A61"]
+[Opening "Benoni defence"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. Nf3 g6 *
+
+[ECO "A61"]
+[Opening "Benoni"]
+[Variation "Uhlmann variation"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. Nf3 g6 7. Bg5 *
+
+[ECO "A61"]
+[Opening "Benoni"]
+[Variation "Nimzovich (knight's tour) variation"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. Nf3 g6 7. Nd2 *
+
+[ECO "A61"]
+[Opening "Benoni"]
+[Variation "fianchetto variation"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. Nf3 g6 7. g3 *
+
+[ECO "A62"]
+[Opening "Benoni"]
+[Variation "fianchetto variation"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. Nf3 g6 7. g3 Bg7 8. 
+Bg2 O-O *
+
+[ECO "A63"]
+[Opening "Benoni"]
+[Variation "fianchetto, 9...Nbd7"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. Nf3 g6 7. g3 Bg7 8. 
+Bg2 O-O 9. O-O Nbd7 *
+
+[ECO "A64"]
+[Opening "Benoni"]
+[Variation "fianchetto, 11...Re8"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. Nf3 g6 7. g3 Bg7 8. 
+Bg2 O-O 9. O-O Nbd7 10. Nd2 a6 11. a4 Re8 *
+
+[ECO "A65"]
+[Opening "Benoni"]
+[Variation "6.e4"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 *
+
+[ECO "A66"]
+[Opening "Benoni"]
+[Variation "pawn storm variation"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. f4 *
+
+[ECO "A66"]
+[Opening "Benoni"]
+[Variation "Mikenas variation"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. f4 Bg7 8. e5
+*
+
+[ECO "A67"]
+[Opening "Benoni"]
+[Variation "Taimanov variation"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. f4 Bg7 8. 
+Bb5+ *
+
+[ECO "A68"]
+[Opening "Benoni"]
+[Variation "four pawns attack"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. f4 Bg7 8. 
+Nf3 O-O *
+
+[ECO "A69"]
+[Opening "Benoni"]
+[Variation "four pawns attack, main line"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. f4 Bg7 8. 
+Nf3 O-O 9. Be2 Re8 *
+
+[ECO "A70"]
+[Opening "Benoni"]
+[Variation "classical with e4 and Nf3"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 *
+
+[ECO "A70"]
+[Opening "Benoni"]
+[Variation "classical without 9.O-O"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 Bg7 8. 
+Be2 *
+
+[ECO "A71"]
+[Opening "Benoni"]
+[Variation "classical, 8.Bg5"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 Bg7 8. 
+Bg5 *
+
+[ECO "A72"]
+[Opening "Benoni"]
+[Variation "classical without 9.O-O"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 Bg7 8. 
+Be2 O-O *
+
+[ECO "A73"]
+[Opening "Benoni"]
+[Variation "classical, 9.O-O"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 Bg7 8. 
+Be2 O-O 9. O-O *
+
+[ECO "A74"]
+[Opening "Benoni"]
+[Variation "classical, 9...a6, 10.a4"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 Bg7 8. 
+Be2 O-O 9. O-O a6 10. a4 *
+
+[ECO "A75"]
+[Opening "Benoni"]
+[Variation "classical with ...a6 and 10...Bg4"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 Bg7 8. 
+Be2 O-O 9. O-O a6 10. a4 Bg4 *
+
+[ECO "A76"]
+[Opening "Benoni"]
+[Variation "classical, 9...Re8"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 Bg7 8. 
+Be2 O-O 9. O-O Re8 *
+
+[ECO "A77"]
+[Opening "Benoni"]
+[Variation "classical, 9...Re8, 10.Nd2"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 Bg7 8. 
+Be2 O-O 9. O-O Re8 10. Nd2 *
+
+[ECO "A78"]
+[Opening "Benoni"]
+[Variation "classical with ...Re8 and ...Na6"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 Bg7 8. 
+Be2 O-O 9. O-O Re8 10. Nd2 Na6 *
+
+[ECO "A79"]
+[Opening "Benoni"]
+[Variation "classical, 11.f3"]
+
+1. d4 Nf6 2. c4 c5 3. d5 e6 4. Nc3 exd5 5. cxd5 d6 6. e4 g6 7. Nf3 Bg7 8. 
+Be2 O-O 9. O-O Re8 10. Nd2 Na6 11. f3 *
+
+[ECO "A80"]
+[Opening "Dutch"]
+
+1. d4 f5 *
+
+[ECO "A80"]
+[Opening "Dutch, Spielmann gambit"]
+
+1. d4 f5 2. Nc3 Nf6 3. g4 *
+
+[ECO "A80"]
+[Opening "Dutch, Manhattan (Alapin, Ulvestad) variation"]
+
+1. d4 f5 2. Qd3 *
+
+[ECO "A80"]
+[Opening "Dutch, Von Pretzel gambit"]
+
+1. d4 f5 2. Qd3 e6 3. g4 *
+
+[ECO "A80"]
+[Opening "Dutch, Korchnoi attack"]
+
+1. d4 f5 2. h3 *
+
+[ECO "A80"]
+[Opening "Dutch, Krejcik gambit"]
+
+1. d4 f5 2. g4 *
+
+[ECO "A80"]
+[Opening "Dutch, 2.Bg5 variation"]
+
+1. d4 f5 2. Bg5 *
+
+[ECO "A81"]
+[Opening "Dutch defence"]
+
+1. d4 f5 2. g3 *
+
+[ECO "A81"]
+[Opening "Dutch defence, Blackburne variation"]
+
+1. d4 f5 2. g3 Nf6 3. Bg2 e6 4. Nh3 *
+
+[ECO "A81"]
+[Opening "Dutch defence"]
+
+1. d4 f5 2. g3 Nf6 3. Bg2 g6 *
+
+[ECO "A81"]
+[Opening "Dutch"]
+[Variation "Leningrad, Basman system"]
+
+1. d4 f5 2. g3 g6 3. Bg2 Bg7 4. Nf3 c6 5. O-O Nh6 *
+
+[ECO "A81"]
+[Opening "Dutch"]
+[Variation "Leningrad, Karlsbad variation"]
+
+1. d4 f5 2. g3 g6 3. Bg2 Bg7 4. Nh3 *
+
+[ECO "A82"]
+[Opening "Dutch"]
+[Variation "Staunton gambit"]
+
+1. d4 f5 2. e4 *
+
+[ECO "A82"]
+[Opening "Dutch"]
+[Variation "Balogh defence"]
+
+1. d4 f5 2. e4 d6 *
+
+[ECO "A82"]
+[Opening "Dutch"]
+[Variation "Staunton gambit"]
+
+1. d4 f5 2. e4 fxe4 *
+
+[ECO "A82"]
+[Opening "Dutch"]
+[Variation "Staunton gambit, Tartakower variation"]
+
+1. d4 f5 2. e4 fxe4 3. Nc3 Nf6 4. g4 *
+
+[ECO "A83"]
+[Opening "Dutch"]
+[Variation "Staunton gambit, Staunton's line"]
+
+1. d4 f5 2. e4 fxe4 3. Nc3 Nf6 4. Bg5 *
+
+[ECO "A83"]
+[Opening "Dutch"]
+[Variation "Staunton gambit, Alekhine variation"]
+
+1. d4 f5 2. e4 fxe4 3. Nc3 Nf6 4. Bg5 g6 5. h4 *
+
+[ECO "A83"]
+[Opening "Dutch"]
+[Variation "Staunton gambit, Lasker variation"]
+
+1. d4 f5 2. e4 fxe4 3. Nc3 Nf6 4. Bg5 g6 5. f3 *
+
+[ECO "A83"]
+[Opening "Dutch"]
+[Variation "Staunton gambit, Chigorin variation"]
+
+1. d4 f5 2. e4 fxe4 3. Nc3 Nf6 4. Bg5 c6 *
+
+[ECO "A83"]
+[Opening "Dutch"]
+[Variation "Staunton gambit, Nimzovich variation"]
+
+1. d4 f5 2. e4 fxe4 3. Nc3 Nf6 4. Bg5 b6 *
+
+[ECO "A84"]
+[Opening "Dutch defence"]
+
+1. d4 f5 2. c4 *
+
+[ECO "A84"]
+[Opening "Dutch defence"]
+[Variation "Bladel variation"]
+
+1. d4 f5 2. c4 g6 3. Nc3 Nh6 *
+
+[ECO "A84"]
+[Opening "Dutch defence"]
+
+1. d4 f5 2. c4 e6 *
+
+[ECO "A84"]
+[Opening "Dutch defence, Rubinstein variation"]
+
+1. d4 f5 2. c4 e6 3. Nc3 *
+
+[ECO "A84"]
+[Opening "Dutch"]
+[Variation "Staunton gambit deferred"]
+
+1. d4 f5 2. c4 e6 3. e4 *
+
+[ECO "A84"]
+[Opening "Dutch defence"]
+
+1. d4 f5 2. c4 Nf6 *
+
+[ECO "A85"]
+[Opening "Dutch with c4 & Nc3"]
+
+1. d4 f5 2. c4 Nf6 3. Nc3 *
+
+[ECO "A86"]
+[Opening "Dutch with c4 & g3"]
+
+1. d4 f5 2. c4 Nf6 3. g3 *
+
+[ECO "A86"]
+[Opening "Dutch"]
+[Variation "Hort-Antoshin system"]
+
+1. d4 f5 2. c4 Nf6 3. g3 d6 4. Bg2 c6 5. Nc3 Qc7 *
+
+[ECO "A86"]
+[Opening "Dutch"]
+[Variation "Leningrad variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 g6 *
+
+[ECO "A87"]
+[Opening "Dutch"]
+[Variation "Leningrad, main variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 g6 4. Bg2 Bg7 5. Nf3 *
+
+[ECO "A88"]
+[Opening "Dutch"]
+[Variation "Leningrad, main variation with c6"]
+
+1. d4 f5 2. c4 Nf6 3. g3 g6 4. Bg2 Bg7 5. Nf3 O-O 6. O-O d6 7. Nc3 c6 *
+
+[ECO "A89"]
+[Opening "Dutch"]
+[Variation "Leningrad, main variation with Nc6"]
+
+1. d4 f5 2. c4 Nf6 3. g3 g6 4. Bg2 Bg7 5. Nf3 O-O 6. O-O d6 7. Nc3 Nc6 *
+
+[ECO "A90"]
+[Opening "Dutch defence"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 *
+
+[ECO "A90"]
+[Opening "Dutch defence"]
+[Variation "Dutch-Indian (Nimzo-Dutch) variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Bb4+ *
+
+[ECO "A90"]
+[Opening "Dutch-Indian, Alekhine variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Bb4+ 5. Bd2 Be7 *
+
+[ECO "A91"]
+[Opening "Dutch defence"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 *
+
+[ECO "A92"]
+[Opening "Dutch defence"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O *
+
+[ECO "A92"]
+[Opening "Dutch defence, Alekhine variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O Ne4 *
+
+[ECO "A92"]
+[Opening "Dutch"]
+[Variation "stonewall variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d5 *
+
+[ECO "A92"]
+[Opening "Dutch"]
+[Variation "stonewall with Nc3"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d5 7. Nc3 *
+
+[ECO "A93"]
+[Opening "Dutch"]
+[Variation "stonewall, Botwinnik variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d5 7. b3 *
+
+[ECO "A94"]
+[Opening "Dutch"]
+[Variation "stonewall with Ba3"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d5 7. b3 c6 8. Ba3
+*
+
+[ECO "A95"]
+[Opening "Dutch"]
+[Variation "stonewall with Nc3"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d5 7. Nc3 c6 *
+
+[ECO "A95"]
+[Opening "Dutch"]
+[Variation "stonewall: Chekhover variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d5 7. Nc3 c6 8. 
+Qc2 Qe8 9. Bg5 *
+
+[ECO "A96"]
+[Opening "Dutch"]
+[Variation "classical variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d6 *
+
+[ECO "A97"]
+[Opening "Dutch"]
+[Variation "Ilyin-Genevsky variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d6 7. Nc3 Qe8 *
+
+[ECO "A97"]
+[Opening "Dutch"]
+[Variation "Ilyin-Genevsky, Winter variation"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d6 7. Nc3 Qe8 8. 
+Re1 *
+
+[ECO "A98"]
+[Opening "Dutch"]
+[Variation "Ilyin-Genevsky variation with Qc2"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d6 7. Nc3 Qe8 8. 
+Qc2 *
+
+[ECO "A99"]
+[Opening "Dutch"]
+[Variation "Ilyin-Genevsky variation with b3"]
+
+1. d4 f5 2. c4 Nf6 3. g3 e6 4. Bg2 Be7 5. Nf3 O-O 6. O-O d6 7. Nc3 Qe8 8. 
+b3 *
+
+[ECO "B00"]
+[Opening "King's pawn opening"]
+
+1. e4 *
+
+[ECO "B00"]
+[Opening "Hippopotamus defence"]
+
+1. e4 Nh6 2. d4 g6 3. c4 f6 *
+
+[ECO "B00"]
+[Opening "Corn stalk defence"]
+
+1. e4 a5 *
+
+[ECO "B00"]
+[Opening "Lemming defence"]
+
+1. e4 Na6 *
+
+[ECO "B00"]
+[Opening "Fred"]
+
+1. e4 f5 *
+
+[ECO "B00"]
+[Opening "Barnes defence"]
+
+1. e4 f6 *
+
+[ECO "B00"]
+[Opening "Fried fox defence"]
+
+1. e4 f6 2. d4 Kf7 *
+
+[ECO "B00"]
+[Opening "Carr's defence"]
+
+1. e4 h6 *
+
+[ECO "B00"]
+[Opening "Reversed Grob (Borg/Basman defence/macho Grob)"]
+
+1. e4 g5 *
+
+[ECO "B00"]
+[Opening "St. George (Baker) defence"]
+
+1. e4 a6 *
+
+[ECO "B00"]
+[Opening "Owen defence"]
+
+1. e4 b6 *
+
+[ECO "B00"]
+[Opening "Guatemala defence"]
+
+1. e4 b6 2. d4 Ba6 *
+
+[ECO "B00"]
+[Opening "KP"]
+[Variation "Nimzovich defence"]
+
+1. e4 Nc6 *
+
+[ECO "B00"]
+[Opening "KP"]
+[Variation "Nimzovich defence, Wheeler gambit"]
+
+1. e4 Nc6 2. b4 Nxb4 3. c3 Nc6 4. d4 *
+
+[ECO "B00"]
+[Opening "KP"]
+[Variation "Nimzovich defence"]
+
+1. e4 Nc6 2. Nf3 *
+
+[ECO "B00"]
+[Opening "KP"]
+[Variation "Colorado counter"]
+
+1. e4 Nc6 2. Nf3 f5 *
+
+[ECO "B00"]
+[Opening "KP"]
+[Variation "Nimzovich defence"]
+
+1. e4 Nc6 2. d4 *
+
+[ECO "B00"]
+[Opening "KP"]
+[Variation "Nimzovich defence, Marshall gambit"]
+
+1. e4 Nc6 2. d4 d5 3. exd5 Qxd5 4. Nc3 *
+
+[ECO "B00"]
+[Opening "KP"]
+[Variation "Nimzovich defence, Bogolyubov variation"]
+
+1. e4 Nc6 2. d4 d5 3. Nc3 *
+
+[ECO "B00"]
+[Opening "KP"]
+[Variation "Neo-Mongoloid defence"]
+
+1. e4 Nc6 2. d4 f6 *
+
+[ECO "B01"]
+[Opening "Scandinavian (centre counter) defence"]
+
+1. e4 d5 *
+
+[ECO "B01"]
+[Opening "Scandinavian defence, Lasker variation"]
+
+1. e4 d5 2. exd5 Qxd5 3. Nc3 Qa5 4. d4 Nf6 5. Nf3 Bg4 6. h3 *
+
+[ECO "B01"]
+[Opening "Scandinavian defence"]
+
+1. e4 d5 2. exd5 Qxd5 3. Nc3 Qa5 4. d4 Nf6 5. Nf3 Bf5 *
+
+[ECO "B01"]
+[Opening "Scandinavian defence, Gruenfeld variation"]
+
+1. e4 d5 2. exd5 Qxd5 3. Nc3 Qa5 4. d4 Nf6 5. Nf3 Bf5 6. Ne5 c6 7. g4 *
+
+[ECO "B01"]
+[Opening "Scandinavian"]
+[Variation "Anderssen counter-attack"]
+
+1. e4 d5 2. exd5 Qxd5 3. Nc3 Qa5 4. d4 e5 *
+
+[ECO "B01"]
+[Opening "Scandinavian"]
+[Variation "Anderssen counter-attack orthodox attack"]
+
+1. e4 d5 2. exd5 Qxd5 3. Nc3 Qa5 4. d4 e5 5. dxe5 Bb4 6. Bd2 Nc6 7. Nf3 *
+
+[ECO "B01"]
+[Opening "Scandinavian"]
+[Variation "Anderssen counter-attack, Goteborg system"]
+
+1. e4 d5 2. exd5 Qxd5 3. Nc3 Qa5 4. d4 e5 5. Nf3 *
+
+[ECO "B01"]
+[Opening "Scandinavian"]
+[Variation "Anderssen counter-attack, Collijn variation"]
+
+1. e4 d5 2. exd5 Qxd5 3. Nc3 Qa5 4. d4 e5 5. Nf3 Bg4 *
+
+[ECO "B01"]
+[Opening "Scandinavian, Mieses-Kotrvc gambit"]
+
+1. e4 d5 2. exd5 Qxd5 3. Nc3 Qa5 4. b4 *
+
+[ECO "B01"]
+[Opening "Scandinavian"]
+[Variation "Pytel-Wade variation"]
+
+1. e4 d5 2. exd5 Qxd5 3. Nc3 Qd6 *
+
+[ECO "B01"]
+[Opening "Scandinavian defence"]
+
+1. e4 d5 2. exd5 Nf6 *
+
+[ECO "B01"]
+[Opening "Scandinavian"]
+[Variation "Icelandic gambit"]
+
+1. e4 d5 2. exd5 Nf6 3. c4 e6 *
+
+[ECO "B01"]
+[Opening "Scandinavian gambit"]
+
+1. e4 d5 2. exd5 Nf6 3. c4 c6 *
+
+[ECO "B01"]
+[Opening "Scandinavian defence"]
+
+1. e4 d5 2. exd5 Nf6 3. d4 *
+
+[ECO "B01"]
+[Opening "Scandinavian"]
+[Variation "Marshall variation"]
+
+1. e4 d5 2. exd5 Nf6 3. d4 Nxd5 *
+
+[ECO "B01"]
+[Opening "Scandinavian"]
+[Variation "Kiel variation"]
+
+1. e4 d5 2. exd5 Nf6 3. d4 Nxd5 4. c4 Nb4 *
+
+[ECO "B01"]
+[Opening "Scandinavian"]
+[Variation "Richter variation"]
+
+1. e4 d5 2. exd5 Nf6 3. d4 g6 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+
+1. e4 Nf6 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "Scandinavian variation"]
+
+1. e4 Nf6 2. Nc3 d5 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "Spielmann variation"]
+
+1. e4 Nf6 2. Nc3 d5 3. e5 Nfd7 4. e6 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "Maroczy variation"]
+
+1. e4 Nf6 2. d3 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "Krejcik variation"]
+
+1. e4 Nf6 2. Bc4 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "Mokele Mbembe (Buecker) variation"]
+
+1. e4 Nf6 2. e5 Ne4 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "Brooklyn defence"]
+
+1. e4 Nf6 2. e5 Ng8 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+
+1. e4 Nf6 2. e5 Nd5 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "Kmoch variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. Bc4 Nb6 4. Bb3 c5 5. d3 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "Saemisch attack"]
+
+1. e4 Nf6 2. e5 Nd5 3. Nc3 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "Welling variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. b3 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+
+1. e4 Nf6 2. e5 Nd5 3. c4 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "Steiner variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. c4 Nb6 4. b3 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "two pawns' (Lasker's) attack"]
+
+1. e4 Nf6 2. e5 Nd5 3. c4 Nb6 4. c5 *
+
+[ECO "B02"]
+[Opening "Alekhine's defence"]
+[Variation "two pawns' attack, Mikenas variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. c4 Nb6 4. c5 Nd5 5. Bc4 e6 6. Nc3 d6 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "O'Sullivan gambit"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 b5 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "Balogh variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Bc4 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "exchange variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. exd6 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "exchange, Karpov variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. exd6 cxd6 6. Nf3 g6 7. Be2 Bg7 8.
+O-O O-O 9. h3 Nc6 10. Nc3 Bf5 11. Bf4 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "four pawns attack"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. f4 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "four pawns attack, Korchnoi variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. f4 dxe5 6. fxe5 Bf5 7. Nc3 e6 8.
+Nf3 Be7 9. Be2 O-O 10. O-O f6 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "four pawns attack, 6...Nc6"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. f4 dxe5 6. fxe5 Nc6 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "four pawns attack, Ilyin-Genevsky var."]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. f4 dxe5 6. fxe5 Nc6 7. Nf3 Bg4 8.
+e6 fxe6 9. c5 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "four pawns attack, 7.Be3"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. f4 dxe5 6. fxe5 Nc6 7. Be3 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "four pawns attack, Tartakower variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. f4 dxe5 6. fxe5 Nc6 7. Be3 Bf5 8.
+Nc3 e6 9. Nf3 Qd7 10. Be2 O-O-O 11. O-O Be7 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "four pawns attack, Planinc variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. f4 g5 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "four pawns attack, fianchetto variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. f4 g6 *
+
+[ECO "B03"]
+[Opening "Alekhine's defence"]
+[Variation "four pawns attack, Trifunovic variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. c4 Nb6 5. f4 Bf5 *
+
+[ECO "B04"]
+[Opening "Alekhine's defence"]
+[Variation "modern variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 *
+
+[ECO "B04"]
+[Opening "Alekhine's defence"]
+[Variation "modern, Larsen variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 dxe5 *
+
+[ECO "B04"]
+[Opening "Alekhine's defence"]
+[Variation "modern, Schmid variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 Nb6 *
+
+[ECO "B04"]
+[Opening "Alekhine's defence"]
+[Variation "modern, fianchetto variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 g6 *
+
+[ECO "B04"]
+[Opening "Alekhine's defence"]
+[Variation "modern, Keres variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 g6 5. Bc4 Nb6 6. Bb3 Bg7 7. a4 *
+
+[ECO "B05"]
+[Opening "Alekhine's defence"]
+[Variation "modern variation, 4...Bg4"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 Bg4 *
+
+[ECO "B05"]
+[Opening "Alekhine's defence"]
+[Variation "modern, Flohr variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 Bg4 5. Be2 c6 *
+
+[ECO "B05"]
+[Opening "Alekhine's defence"]
+[Variation "modern, Panov variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 Bg4 5. h3 *
+
+[ECO "B05"]
+[Opening "Alekhine's defence"]
+[Variation "modern, Alekhine variation"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 Bg4 5. c4 *
+
+[ECO "B05"]
+[Opening "Alekhine's defence"]
+[Variation "modern, Vitolins attack"]
+
+1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 Bg4 5. c4 Nb6 6. d5 *
+
+[ECO "B06"]
+[Opening "Robatsch (modern) defence"]
+
+1. e4 g6 *
+
+[ECO "B06"]
+[Opening "Norwegian defence"]
+
+1. e4 g6 2. d4 Nf6 3. e5 Nh5 4. g4 Ng7 *
+
+[ECO "B06"]
+[Opening "Robatsch (modern) defence"]
+
+1. e4 g6 2. d4 Bg7 *
+
+[ECO "B06"]
+[Opening "Robatsch defence"]
+[Variation "three pawns attack"]
+
+1. e4 g6 2. d4 Bg7 3. f4 *
+
+[ECO "B06"]
+[Opening "Robatsch defence"]
+
+1. e4 g6 2. d4 Bg7 3. Nc3 *
+
+[ECO "B06"]
+[Opening "Robatsch defence"]
+[Variation "Gurgenidze variation"]
+
+1. e4 g6 2. d4 Bg7 3. Nc3 c6 4. f4 d5 5. e5 h5 *
+
+[ECO "B06"]
+[Opening "Robatsch (modern) defence"]
+
+1. e4 g6 2. d4 Bg7 3. Nc3 d6 *
+
+[ECO "B06"]
+[Opening "Robatsch defence"]
+[Variation "two knights variation"]
+
+1. e4 g6 2. d4 Bg7 3. Nc3 d6 4. Nf3 *
+
+[ECO "B06"]
+[Opening "Robatsch defence"]
+[Variation "two knights, Suttles variation"]
+
+1. e4 g6 2. d4 Bg7 3. Nc3 d6 4. Nf3 c6 *
+
+[ECO "B06"]
+[Opening "Robatsch defence"]
+[Variation "Pseudo-Austrian attack"]
+
+1. e4 g6 2. d4 Bg7 3. Nc3 d6 4. f4 *
+
+[ECO "B07"]
+[Opening "Pirc defence"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 *
+
+[ECO "B07"]
+[Opening "Pirc"]
+[Variation "Ufimtsev-Pytel variation"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 c6 *
+
+[ECO "B07"]
+[Opening "Pirc defence"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 *
+
+[ECO "B07"]
+[Opening "Pirc"]
+[Variation "150 attack"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Be3 c6 5. Qd2 *
+
+[ECO "B07"]
+[Opening "Pirc"]
+[Variation "Sveshnikov system"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. g3 *
+
+[ECO "B07"]
+[Opening "Pirc"]
+[Variation "Holmov system"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Bc4 *
+
+[ECO "B07"]
+[Opening "Pirc"]
+[Variation "Byrne variation"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Bg5 *
+
+[ECO "B07"]
+[Opening "Pirc defence"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Be2 *
+
+[ECO "B07"]
+[Opening "Pirc"]
+[Variation "Chinese variation"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Be2 Bg7 5. g4 *
+
+[ECO "B07"]
+[Opening "Pirc"]
+[Variation "bayonet (Mariotti) attack"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Be2 Bg7 5. h4 *
+
+[ECO "B07"]
+[Opening "Robatsch defence"]
+[Variation "Geller's system"]
+
+1. e4 g6 2. d4 Bg7 3. Nf3 d6 4. c3 *
+
+[ECO "B08"]
+[Opening "Pirc"]
+[Variation "classical (two knights) system"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Nf3 *
+
+[ECO "B08"]
+[Opening "Pirc"]
+[Variation "classical (two knights) system"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Nf3 Bg7 *
+
+[ECO "B08"]
+[Opening "Pirc"]
+[Variation "classical, h3 system"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Nf3 Bg7 5. h3 *
+
+[ECO "B08"]
+[Opening "Pirc"]
+[Variation "classical system, 5.Be2"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. Nf3 Bg7 5. Be2 *
+
+[ECO "B09"]
+[Opening "Pirc"]
+[Variation "Austrian attack"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. f4 *
+
+[ECO "B09"]
+[Opening "Pirc"]
+[Variation "Austrian attack"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. f4 Bg7 5. Nf3 O-O *
+
+[ECO "B09"]
+[Opening "Pirc"]
+[Variation "Austrian attack, 6.e5"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. f4 Bg7 5. Nf3 O-O 6. e5 *
+
+[ECO "B09"]
+[Opening "Pirc"]
+[Variation "Austrian attack, 6.Be3"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. f4 Bg7 5. Nf3 O-O 6. Be3 *
+
+[ECO "B09"]
+[Opening "Pirc"]
+[Variation "Austrian attack, 6.Bd3"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. f4 Bg7 5. Nf3 O-O 6. Bd3 *
+
+[ECO "B09"]
+[Opening "Pirc"]
+[Variation "Austrian attack, dragon formation"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. f4 Bg7 5. Nf3 c5 *
+
+[ECO "B09"]
+[Opening "Pirc"]
+[Variation "Austrian attack, Ljubojevic variation"]
+
+1. e4 d6 2. d4 Nf6 3. Nc3 g6 4. f4 Bg7 5. Bc4 *
+
+[ECO "B10"]
+[Opening "Caro-Kann defence"]
+
+1. e4 c6 *
+
+[ECO "B10"]
+[Opening "Caro-Kann"]
+[Variation "Hillbilly attack"]
+
+1. e4 c6 2. Bc4 *
+
+[ECO "B10"]
+[Opening "Caro-Kann"]
+[Variation "anti-Caro-Kann defence"]
+
+1. e4 c6 2. c4 *
+
+[ECO "B10"]
+[Opening "Caro-Kann"]
+[Variation "anti-anti-Caro-Kann defence"]
+
+1. e4 c6 2. c4 d5 *
+
+[ECO "B10"]
+[Opening "Caro-Kann"]
+[Variation "closed (Breyer) variation"]
+
+1. e4 c6 2. d3 *
+
+[ECO "B10"]
+[Opening "Caro-Kann defence"]
+
+1. e4 c6 2. Nc3 *
+
+[ECO "B10"]
+[Opening "Caro-Kann"]
+[Variation "Goldman (Spielmann) variation"]
+
+1. e4 c6 2. Nc3 d5 3. Qf3 *
+
+[ECO "B10"]
+[Opening "Caro-Kann"]
+[Variation "two knights variation"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 *
+
+[ECO "B11"]
+[Opening "Caro-Kann"]
+[Variation "two knights, 3...Bg4"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 *
+
+[ECO "B12"]
+[Opening "Caro-Kann defence"]
+
+1. e4 c6 2. d4 *
+
+[ECO "B12"]
+[Opening "de Bruycker defence"]
+
+1. e4 c6 2. d4 Na6 3. Nc3 Nc7 *
+
+[ECO "B12"]
+[Opening "Caro-Masi defence"]
+
+1. e4 c6 2. d4 Nf6 *
+
+[ECO "B12"]
+[Opening "Caro-Kann defence"]
+
+1. e4 c6 2. d4 d5 *
+
+[ECO "B12"]
+[Opening "Caro-Kann"]
+[Variation "Tartakower (fantasy) variation"]
+
+1. e4 c6 2. d4 d5 3. f3 *
+
+[ECO "B12"]
+[Opening "Caro-Kann"]
+[Variation "3.Nd2"]
+
+1. e4 c6 2. d4 d5 3. Nd2 *
+
+[ECO "B12"]
+[Opening "Caro-Kann"]
+[Variation "Edinburgh variation"]
+
+1. e4 c6 2. d4 d5 3. Nd2 Qb6 *
+
+[ECO "B12"]
+[Opening "Caro-Kann"]
+[Variation "advance variation"]
+
+1. e4 c6 2. d4 d5 3. e5 *
+
+[ECO "B12"]
+[Opening "Caro-Kann"]
+[Variation "advance, Short variation"]
+
+1. e4 c6 2. d4 d5 3. e5 Bf5 4. c3 e6 5. Be2 *
+
+[ECO "B13"]
+[Opening "Caro-Kann"]
+[Variation "exchange variation"]
+
+1. e4 c6 2. d4 d5 3. exd5 *
+
+[ECO "B13"]
+[Opening "Caro-Kann"]
+[Variation "exchange, Rubinstein variation"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 *
+
+[ECO "B13"]
+[Opening "Caro-Kann"]
+[Variation "Panov-Botvinnik attack"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 *
+
+[ECO "B13"]
+[Opening "Caro-Kann"]
+[Variation "Panov-Botvinnik, Gunderam attack"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. c5 *
+
+[ECO "B13"]
+[Opening "Caro-Kann"]
+[Variation "Panov-Botvinnik attack"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 *
+
+[ECO "B13"]
+[Opening "Caro-Kann"]
+[Variation "Panov-Botvinnik, Herzog defence"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Bg5 dxc4 7. d5 Na5 *
+
+[ECO "B13"]
+[Opening "Caro-Kann"]
+[Variation "Panov-Botvinnik, normal variation"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Bg5 e6 *
+
+[ECO "B13"]
+[Opening "Caro-Kann"]
+[Variation "Panov-Botvinnik, Czerniak variation"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Bg5 Qa5 *
+
+[ECO "B13"]
+[Opening "Caro-Kann"]
+[Variation "Panov-Botvinnik, Reifir (Spielmann) variation"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Bg5 Qb6 *
+
+[ECO "B14"]
+[Opening "Caro-Kann"]
+[Variation "Panov-Botvinnik attack, 5...e6"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 *
+
+[ECO "B14"]
+[Opening "Caro-Kann"]
+[Variation "Panov-Botvinnik attack, 5...g6"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 *
+
+[ECO "B15"]
+[Opening "Caro-Kann defence"]
+
+1. e4 c6 2. d4 d5 3. Nc3 *
+
+[ECO "B15"]
+[Opening "Caro-Kann"]
+[Variation "Gurgenidze counter-attack"]
+
+1. e4 c6 2. d4 d5 3. Nc3 b5 *
+
+[ECO "B15"]
+[Opening "Caro-Kann"]
+[Variation "Gurgenidze system"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 *
+
+[ECO "B15"]
+[Opening "Caro-Kann"]
+[Variation "Rasa-Studier gambit"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. f3 *
+
+[ECO "B15"]
+[Opening "Caro-Kann defence"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 *
+
+[ECO "B15"]
+[Opening "Caro-Kann"]
+[Variation "Alekhine gambit"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nf6 5. Bd3 *
+
+[ECO "B15"]
+[Opening "Caro-Kann"]
+[Variation "Tartakower (Nimzovich) variation"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 *
+
+[ECO "B15"]
+[Opening "Caro-Kann"]
+[Variation "Forgacs variation"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 *
+
+[ECO "B16"]
+[Opening "Caro-Kann"]
+[Variation "Bronstein-Larsen variation"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nf6 5. Nxf6+ gxf6 *
+
+[ECO "B17"]
+[Opening "Caro-Kann"]
+[Variation "Steinitz variation"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 *
+
+[ECO "B18"]
+[Opening "Caro-Kann"]
+[Variation "classical variation"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 *
+
+[ECO "B18"]
+[Opening "Caro-Kann"]
+[Variation "classical, Flohr variation"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 *
+
+[ECO "B18"]
+[Opening "Caro-Kann"]
+[Variation "classical, Maroczy attack"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. f4 *
+
+[ECO "B18"]
+[Opening "Caro-Kann"]
+[Variation "classical, 6.h4"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 *
+
+[ECO "B19"]
+[Opening "Caro-Kann"]
+[Variation "classical, 7...Nd7"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 *
+
+[ECO "B19"]
+[Opening "Caro-Kann"]
+[Variation "classical, Spassky variation"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+h5 *
+
+[ECO "B20"]
+[Opening "Sicilian defence"]
+
+1. e4 c5 *
+
+[ECO "B20"]
+[Opening "Sicilian"]
+[Variation "Gloria variation"]
+
+1. e4 c5 2. c4 d6 3. Nc3 Nc6 4. g3 h5 *
+
+[ECO "B20"]
+[Opening "Sicilian"]
+[Variation "Steinitz variation"]
+
+1. e4 c5 2. g3 *
+
+[ECO "B20"]
+[Opening "Sicilian"]
+[Variation "wing gambit"]
+
+1. e4 c5 2. b4 *
+
+[ECO "B20"]
+[Opening "Sicilian"]
+[Variation "wing gambit, Santasiere variation"]
+
+1. e4 c5 2. b4 cxb4 3. c4 *
+
+[ECO "B20"]
+[Opening "Sicilian"]
+[Variation "wing gambit, Marshall variation"]
+
+1. e4 c5 2. b4 cxb4 3. a3 *
+
+[ECO "B20"]
+[Opening "Sicilian"]
+[Variation "wing gambit, Marienbad variation"]
+
+1. e4 c5 2. b4 cxb4 3. a3 d5 4. exd5 Qxd5 5. Bb2 *
+
+[ECO "B20"]
+[Opening "Sicilian"]
+[Variation "wing gambit, Carlsbad variation"]
+
+1. e4 c5 2. b4 cxb4 3. a3 bxa3 *
+
+[ECO "B20"]
+[Opening "Sicilian"]
+[Variation "Keres variation (2.Ne2)"]
+
+1. e4 c5 2. Ne2 *
+
+[ECO "B21"]
+[Opening "Sicilian"]
+[Variation "Grand Prix attack"]
+
+1. e4 c5 2. f4 *
+
+[ECO "B21"]
+[Opening "Sicilian"]
+[Variation "Smith-Morra gambit"]
+
+1. e4 c5 2. d4 *
+
+[ECO "B21"]
+[Opening "Sicilian"]
+[Variation "Andreaschek gambit"]
+
+1. e4 c5 2. d4 cxd4 3. Nf3 e5 4. c3 *
+
+[ECO "B21"]
+[Opening "Sicilian"]
+[Variation "Smith-Morra gambit"]
+
+1. e4 c5 2. d4 cxd4 3. c3 *
+
+[ECO "B21"]
+[Opening "Sicilian"]
+[Variation "Smith-Morra gambit, Chicago defence"]
+
+1. e4 c5 2. d4 cxd4 3. c3 dxc3 4. Nxc3 Nc6 5. Nf3 d6 6. Bc4 e6 7. O-O a6 8.
+Qe2 b5 9. Bb3 Ra7 *
+
+[ECO "B22"]
+[Opening "Sicilian"]
+[Variation "Alapin's variation (2.c3)"]
+
+1. e4 c5 2. c3 *
+
+[ECO "B22"]
+[Opening "Sicilian"]
+[Variation "2.c3, Heidenfeld variation"]
+
+1. e4 c5 2. c3 Nf6 3. e5 Nd5 4. Nf3 Nc6 5. Na3 *
+
+[ECO "B23"]
+[Opening "Sicilian"]
+[Variation "closed"]
+
+1. e4 c5 2. Nc3 *
+
+[ECO "B23"]
+[Opening "Sicilian"]
+[Variation "closed, Korchnoi variation"]
+
+1. e4 c5 2. Nc3 e6 3. g3 d5 *
+
+[ECO "B23"]
+[Opening "Sicilian"]
+[Variation "closed, 2...Nc6"]
+
+1. e4 c5 2. Nc3 Nc6 *
+
+[ECO "B23"]
+[Opening "Sicilian"]
+[Variation "chameleon variation"]
+
+1. e4 c5 2. Nc3 Nc6 3. Nge2 *
+
+[ECO "B23"]
+[Opening "Sicilian"]
+[Variation "Grand Prix attack"]
+
+1. e4 c5 2. Nc3 Nc6 3. f4 *
+
+[ECO "B23"]
+[Opening "Sicilian"]
+[Variation "Grand Prix attack, Schofman variation"]
+
+1. e4 c5 2. Nc3 Nc6 3. f4 g6 4. Nf3 Bg7 5. Bc4 e6 6. f5 *
+
+[ECO "B24"]
+[Opening "Sicilian"]
+[Variation "closed"]
+
+1. e4 c5 2. Nc3 Nc6 3. g3 *
+
+[ECO "B24"]
+[Opening "Sicilian"]
+[Variation "closed, Smyslov variation"]
+
+1. e4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. d3 e6 6. Be3 Nd4 7. Nce2 *
+
+[ECO "B25"]
+[Opening "Sicilian"]
+[Variation "closed"]
+
+1. e4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. d3 d6 *
+
+[ECO "B25"]
+[Opening "Sicilian"]
+[Variation "closed, 6.Ne2 e5 (Botvinnik)"]
+
+1. e4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. d3 d6 6. Nge2 e5 *
+
+[ECO "B25"]
+[Opening "Sicilian"]
+[Variation "closed, 6.f4"]
+
+1. e4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. d3 d6 6. f4 *
+
+[ECO "B25"]
+[Opening "Sicilian"]
+[Variation "closed, 6.f4 e5 (Botvinnik)"]
+
+1. e4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. d3 d6 6. f4 e5 *
+
+[ECO "B26"]
+[Opening "Sicilian"]
+[Variation "closed, 6.Be3"]
+
+1. e4 c5 2. Nc3 Nc6 3. g3 g6 4. Bg2 Bg7 5. d3 d6 6. Be3 *
+
+[ECO "B27"]
+[Opening "Sicilian defence"]
+
+1. e4 c5 2. Nf3 *
+
+[ECO "B27"]
+[Opening "Sicilian"]
+[Variation "Stiletto (Althouse) variation"]
+
+1. e4 c5 2. Nf3 Qa5 *
+
+[ECO "B27"]
+[Opening "Sicilian"]
+[Variation "Quinteros variation"]
+
+1. e4 c5 2. Nf3 Qc7 *
+
+[ECO "B27"]
+[Opening "Sicilian"]
+[Variation "Katalimov variation"]
+
+1. e4 c5 2. Nf3 b6 *
+
+[ECO "B27"]
+[Opening "Sicilian"]
+[Variation "Hungarian variation"]
+
+1. e4 c5 2. Nf3 g6 *
+
+[ECO "B27"]
+[Opening "Sicilian"]
+[Variation "Acton extension"]
+
+1. e4 c5 2. Nf3 g6 3. c4 Bh6 *
+
+[ECO "B28"]
+[Opening "Sicilian"]
+[Variation "O'Kelly variation"]
+
+1. e4 c5 2. Nf3 a6 *
+
+[ECO "B29"]
+[Opening "Sicilian"]
+[Variation "Nimzovich-Rubinstein variation"]
+
+1. e4 c5 2. Nf3 Nf6 *
+
+[ECO "B29"]
+[Opening "Sicilian"]
+[Variation "Nimzovich-Rubinstein; Rubinstein counter-gambit"]
+
+1. e4 c5 2. Nf3 Nf6 3. e5 Nd5 4. Nc3 e6 5. Nxd5 exd5 6. d4 Nc6 *
+
+[ECO "B30"]
+[Opening "Sicilian defence"]
+
+1. e4 c5 2. Nf3 Nc6 *
+
+[ECO "B30"]
+[Opening "Sicilian"]
+[Variation "Nimzovich-Rossolimo attack (without ...d6)"]
+
+1. e4 c5 2. Nf3 Nc6 3. Bb5 *
+
+[ECO "B31"]
+[Opening "Sicilian"]
+[Variation "Nimzovich-Rossolimo attack (with ...g6, without ...d6)"]
+
+1. e4 c5 2. Nf3 Nc6 3. Bb5 g6 *
+
+[ECO "B31"]
+[Opening "Sicilian"]
+[Variation "Nimzovich-Rossolimo attack, Gurgenidze variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. Bb5 g6 4. O-O Bg7 5. Re1 e5 6. b4 *
+
+[ECO "B32"]
+[Opening "Sicilian defence"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 *
+
+[ECO "B32"]
+[Opening "Sicilian"]
+[Variation "Flohr variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 Qc7 *
+
+[ECO "B32"]
+[Opening "Sicilian"]
+[Variation "Nimzovich variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 d5 *
+
+[ECO "B32"]
+[Opening "Sicilian"]
+[Variation "Labourdonnais-Loewenthal variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 e5 *
+
+[ECO "B32"]
+[Opening "Sicilian"]
+[Variation "Labourdonnais-Loewenthal (Kalashnikov) variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 e5 5. Nb5 d6 *
+
+[ECO "B33"]
+[Opening "Sicilian defence"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 Nf6 *
+
+[ECO "B33"]
+[Opening "Sicilian"]
+[Variation "Pelikan (Lasker/Sveshnikov) variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e5 *
+
+[ECO "B33"]
+[Opening "Sicilian"]
+[Variation "Pelikan, Bird variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e5 6. Ndb5 d6 7. Bg5 a6 
+8. Na3 Be6 *
+
+[ECO "B33"]
+[Opening "Sicilian"]
+[Variation "Pelikan, Chelyabinsk variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e5 6. Ndb5 d6 7. Bg5 a6 
+8. Na3 b5 *
+
+[ECO "B33"]
+[Opening "Sicilian"]
+[Variation "Sveshnikov variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e5 6. Ndb5 d6 7. Bg5 a6 
+8. Na3 b5 9. Bxf6 gxf6 10. Nd5 f5 *
+
+[ECO "B34"]
+[Opening "Sicilian"]
+[Variation "accelerated fianchetto, exchange variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 g6 5. Nxc6 *
+
+[ECO "B34"]
+[Opening "Sicilian"]
+[Variation "accelerated fianchetto, modern variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 g6 5. Nc3 *
+
+[ECO "B35"]
+[Opening "Sicilian"]
+[Variation "accelerated fianchetto, modern variation with Bc4"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 g6 5. Nc3 Bg7 6. Be3 Nf6 7. Bc4 *
+
+[ECO "B36"]
+[Opening "Sicilian"]
+[Variation "accelerated fianchetto, Maroczy bind"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 g6 5. c4 *
+
+[ECO "B36"]
+[Opening "Sicilian"]
+[Variation "accelerated fianchetto, Gurgenidze variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 g6 5. c4 Nf6 6. Nc3 Nxd4 7. Qxd4 d6
+*
+
+[ECO "B37"]
+[Opening "Sicilian"]
+[Variation "accelerated fianchetto, Maroczy bind, 5...Bg7"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 g6 5. c4 Bg7 *
+
+[ECO "B37"]
+[Opening "Sicilian"]
+[Variation "accelerated fianchetto, Simagin variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 g6 5. c4 Bg7 6. Nc2 d6 7. Be2 Nh6 *
+
+[ECO "B38"]
+[Opening "Sicilian"]
+[Variation "accelerated fianchetto, Maroczy bind, 6.Be3"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 g6 5. c4 Bg7 6. Be3 *
+
+[ECO "B39"]
+[Opening "Sicilian"]
+[Variation "accelerated fianchetto, Breyer variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 g6 5. c4 Bg7 6. Be3 Nf6 7. Nc3 Ng4 *
+
+[ECO "B40"]
+[Opening "Sicilian defence"]
+
+1. e4 c5 2. Nf3 e6 *
+
+[ECO "B40"]
+[Opening "Sicilian"]
+[Variation "Marshall variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 d5 *
+
+[ECO "B40"]
+[Opening "Sicilian defence"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 *
+
+[ECO "B40"]
+[Opening "Sicilian"]
+[Variation "Anderssen variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nf6 *
+
+[ECO "B40"]
+[Opening "Sicilian"]
+[Variation "Pin variation (Sicilian counter-attack)"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Bb4 *
+
+[ECO "B40"]
+[Opening "Sicilian"]
+[Variation "Pin, Jaffe variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Bb4 6. Bd3 e5 *
+
+[ECO "B40"]
+[Opening "Sicilian"]
+[Variation "Pin, Koch variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Bb4 6. e5 *
+
+[ECO "B41"]
+[Opening "Sicilian"]
+[Variation "Kan variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 a6 *
+
+[ECO "B41"]
+[Opening "Sicilian"]
+[Variation "Kan, Maroczy bind (Reti variation)"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 a6 5. c4 *
+
+[ECO "B41"]
+[Opening "Sicilian"]
+[Variation "Kan, Maroczy bind - Bronstein variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 a6 5. c4 Nf6 6. Nc3 Bb4 7. Bd3 Nc6 8.
+Bc2 *
+
+[ECO "B42"]
+[Opening "Sicilian"]
+[Variation "Kan, 5.Bd3"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 a6 5. Bd3 *
+
+[ECO "B42"]
+[Opening "Sicilian"]
+[Variation "Kan, Gipslis variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 a6 5. Bd3 Nf6 6. O-O d6 7. c4 g6 *
+
+[ECO "B42"]
+[Opening "Sicilian"]
+[Variation "Kan, Polugaievsky variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 a6 5. Bd3 Bc5 *
+
+[ECO "B42"]
+[Opening "Sicilian"]
+[Variation "Kan, Swiss cheese variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 a6 5. Bd3 g6 *
+
+[ECO "B43"]
+[Opening "Sicilian"]
+[Variation "Kan, 5.Nc3"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 a6 5. Nc3 *
+
+[ECO "B44"]
+[Opening "Sicilian defence"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc6 *
+
+[ECO "B44"]
+[Opening "Sicilian, Szen (`anti-Taimanov') variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc6 5. Nb5 *
+
+[ECO "B44"]
+[Opening "Sicilian, Szen, hedgehog variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc6 5. Nb5 d6 6. c4 Nf6 7. N1c3 a6 8.
+Na3 Be7 9. Be2 O-O 10. O-O b6 *
+
+[ECO "B44"]
+[Opening "Sicilian, Szen variation, Dely-Kasparov gambit"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc6 5. Nb5 d6 6. c4 Nf6 7. N1c3 a6 8.
+Na3 d5 *
+
+[ECO "B45"]
+[Opening "Sicilian"]
+[Variation "Taimanov variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc6 5. Nc3 *
+
+[ECO "B45"]
+[Opening "Sicilian"]
+[Variation "Taimanov, American attack"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc6 5. Nc3 Nf6 6. Ndb5 Bb4 7. Nd6+ *
+
+[ECO "B46"]
+[Opening "Sicilian"]
+[Variation "Taimanov variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc6 5. Nc3 a6 *
+
+[ECO "B47"]
+[Opening "Sicilian"]
+[Variation "Taimanov (Bastrikov) variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc6 5. Nc3 Qc7 *
+
+[ECO "B48"]
+[Opening "Sicilian"]
+[Variation "Taimanov variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc6 5. Nc3 Qc7 6. Be3 *
+
+[ECO "B49"]
+[Opening "Sicilian"]
+[Variation "Taimanov variation"]
+
+1. e4 c5 2. Nf3 e6 3. d4 cxd4 4. Nxd4 Nc6 5. Nc3 Qc7 6. Be3 a6 7. Be2 *
+
+[ECO "B50"]
+[Opening "Sicilian"]
+
+1. e4 c5 2. Nf3 d6 *
+
+[ECO "B50"]
+[Opening "Sicilian"]
+[Variation "wing gambit deferred"]
+
+1. e4 c5 2. Nf3 d6 3. b4 *
+
+[ECO "B51"]
+[Opening "Sicilian"]
+[Variation "Canal-Sokolsky (Nimzovich-Rossolimo, Moscow) attack"]
+
+1. e4 c5 2. Nf3 d6 3. Bb5+ *
+
+[ECO "B52"]
+[Opening "Sicilian"]
+[Variation "Canal-Sokolsky attack, 3...Bd7"]
+
+1. e4 c5 2. Nf3 d6 3. Bb5+ Bd7 *
+
+[ECO "B52"]
+[Opening "Sicilian"]
+[Variation "Canal-Sokolsky attack, Bronstein gambit"]
+
+1. e4 c5 2. Nf3 d6 3. Bb5+ Bd7 4. Bxd7+ Qxd7 5. O-O Nc6 6. c3 Nf6 7. d4 *
+
+[ECO "B52"]
+[Opening "Sicilian"]
+[Variation "Canal-Sokolsky attack, Sokolsky variation"]
+
+1. e4 c5 2. Nf3 d6 3. Bb5+ Bd7 4. Bxd7+ Qxd7 5. c4 *
+
+[ECO "B53"]
+[Opening "Sicilian, Chekhover variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Qxd4 *
+
+[ECO "B53"]
+[Opening "Sicilian"]
+[Variation "Chekhover, Zaitsev variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Qxd4 Nc6 5. Bb5 Qd7 *
+
+[ECO "B54"]
+[Opening "Sicilian"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 *
+
+[ECO "B54"]
+[Opening "Sicilian"]
+[Variation "Prins (Moscow) variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. f3 *
+
+[ECO "B55"]
+[Opening "Sicilian"]
+[Variation "Prins variation, Venice attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. f3 e5 6. Bb5+ *
+
+[ECO "B56"]
+[Opening "Sicilian"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 *
+
+[ECO "B56"]
+[Opening "Sicilian"]
+[Variation "Venice attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e5 6. Bb5+ *
+
+[ECO "B56"]
+[Opening "Sicilian"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 *
+
+[ECO "B57"]
+[Opening "Sicilian"]
+[Variation "Sozin, not Scheveningen"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bc4 *
+
+[ECO "B57"]
+[Opening "Sicilian"]
+[Variation "Magnus Smith trap"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bc4 g6 7. Nxc6 bxc6
+8. e5 *
+
+[ECO "B57"]
+[Opening "Sicilian"]
+[Variation "Sozin, Benko variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bc4 Qb6 *
+
+[ECO "B58"]
+[Opening "Sicilian"]
+[Variation "classical"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 d6 6. Be2 *
+
+[ECO "B58"]
+[Opening "Sicilian"]
+[Variation "Boleslavsky variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 d6 6. Be2 e5 *
+
+[ECO "B58"]
+[Opening "Sicilian"]
+[Variation "Boleslavsky, Louma variation"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 d6 6. Be2 e5 7. Nxc6 *
+
+[ECO "B59"]
+[Opening "Sicilian"]
+[Variation "Boleslavsky variation, 7.Nb3"]
+
+1. e4 c5 2. Nf3 Nc6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 d6 6. Be2 e5 7. Nb3 *
+
+[ECO "B60"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 *
+
+[ECO "B60"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Bondarevsky variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 g6 *
+
+[ECO "B60"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Larsen variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 Bd7 *
+
+[ECO "B61"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Larsen variation, 7.Qd2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 Bd7 7. Qd2 *
+
+[ECO "B62"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, 6...e6"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 *
+
+[ECO "B62"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Podvebrady variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Nb3 *
+
+[ECO "B62"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Margate (Alekhine) variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Bb5 *
+
+[ECO "B62"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Richter attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Nxc6 *
+
+[ECO "B62"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Keres variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd3 *
+
+[ECO "B63"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Rauzer attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd2 *
+
+[ECO "B63"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Rauzer attack, 7...Be7"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd2 Be7 *
+
+[ECO "B64"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Rauzer attack, 7...Be7 defence, 9.f4"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd2 Be7 
+8. O-O-O O-O 9. f4 *
+
+[ECO "B64"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Rauzer attack, Geller variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd2 Be7 
+8. O-O-O O-O 9. f4 e5 *
+
+[ECO "B65"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Rauzer attack, 7...Be7 defence, 9...Nxd4"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd2 Be7 
+8. O-O-O O-O 9. f4 Nxd4 *
+
+[ECO "B65"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Rauzer attack, 7...Be7 defence, 9...Nxd4"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd2 Be7 
+8. O-O-O O-O 9. f4 Nxd4 10. Qxd4 *
+
+[ECO "B66"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Rauzer attack, 7...a6"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd2 a6 *
+
+[ECO "B67"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Rauzer attack, 7...a6 defence, 8...Bd7"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd2 a6 8.
+O-O-O Bd7 *
+
+[ECO "B68"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Rauzer attack, 7...a6 defence, 9...Be7"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd2 a6 8.
+O-O-O Bd7 9. f4 Be7 *
+
+[ECO "B69"]
+[Opening "Sicilian"]
+[Variation "Richter-Rauzer, Rauzer attack, 7...a6 defence, 11.Bxf6"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 Nc6 6. Bg5 e6 7. Qd2 a6 8.
+O-O-O Bd7 9. f4 Be7 10. Nf3 b5 11. Bxf6 *
+
+[ECO "B70"]
+[Opening "Sicilian"]
+[Variation "dragon variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 *
+
+[ECO "B71"]
+[Opening "Sicilian"]
+[Variation "dragon, Levenfish variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. f4 *
+
+[ECO "B71"]
+[Opening "Sicilian"]
+[Variation "dragon, Levenfish; Flohr variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. f4 Nbd7 *
+
+[ECO "B72"]
+[Opening "Sicilian"]
+[Variation "dragon, 6.Be3"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 *
+
+[ECO "B72"]
+[Opening "Sicilian"]
+[Variation "dragon, classical attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 *
+
+[ECO "B72"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, Amsterdam variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. Qd2 *
+
+[ECO "B72"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, Grigoriev variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. Qd2 O-O 9. O-O-O *
+
+[ECO "B72"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, Nottingham variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. Nb3 *
+
+[ECO "B73"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, 8.O-O"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. O-O *
+
+[ECO "B73"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, Zollner gambit"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. O-O O-O 9. f4 Qb6 10. e5 *
+
+[ECO "B73"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, Richter variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. O-O O-O 9. Qd2 *
+
+[ECO "B74"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, 9.Nb3"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. O-O O-O 9. Nb3 *
+
+[ECO "B74"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, Stockholm attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. O-O O-O 9. Nb3 Be6 10. f4 Na5 11. f5 Bc4 12. Nxa5 Bxe2 13. Qxe2 Qxa5 14.
+g4 *
+
+[ECO "B74"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, Spielmann variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. O-O O-O 9. Nb3 Be6 10. f4 Na5 11. f5 Bc4 12. Bd3 *
+
+[ECO "B74"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, Bernard defence"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. O-O O-O 9. Nb3 Be6 10. f4 Na5 11. f5 Bc4 12. Bd3 Bxd3 13. cxd3 d5 *
+
+[ECO "B74"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, Reti-Tartakower variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. O-O O-O 9. Nb3 Be6 10. f4 Qc8 *
+
+[ECO "B74"]
+[Opening "Sicilian"]
+[Variation "dragon, classical, Alekhine variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. Be2 Nc6 
+8. O-O O-O 9. Nb3 a5 *
+
+[ECO "B75"]
+[Opening "Sicilian"]
+[Variation "dragon, Yugoslav attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. f3 *
+
+[ECO "B76"]
+[Opening "Sicilian"]
+[Variation "dragon, Yugoslav attack, 7...O-O"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. f3 O-O *
+
+[ECO "B76"]
+[Opening "Sicilian"]
+[Variation "dragon, Yugoslav attack, Rauser variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. f3 O-O 8.
+Qd2 Nc6 9. O-O-O *
+
+[ECO "B77"]
+[Opening "Sicilian"]
+[Variation "dragon, Yugoslav attack, 9.Bc4"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. f3 O-O 8.
+Qd2 Nc6 9. Bc4 *
+
+[ECO "B77"]
+[Opening "Sicilian"]
+[Variation "dragon, Yugoslav attack, Byrne variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. f3 O-O 8.
+Qd2 Nc6 9. Bc4 a5 *
+
+[ECO "B77"]
+[Opening "Sicilian"]
+[Variation "dragon, Yugoslav attack, 9...Bd7"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. f3 O-O 8.
+Qd2 Nc6 9. Bc4 Bd7 *
+
+[ECO "B78"]
+[Opening "Sicilian"]
+[Variation "dragon, Yugoslav attack, 10.O-O-O"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. f3 O-O 8.
+Qd2 Nc6 9. Bc4 Bd7 10. O-O-O *
+
+[ECO "B79"]
+[Opening "Sicilian"]
+[Variation "dragon, Yugoslav attack, 12.h4"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 g6 6. Be3 Bg7 7. f3 O-O 8.
+Qd2 Nc6 9. Bc4 Bd7 10. O-O-O Qa5 11. Bb3 Rfc8 12. h4 *
+
+[ECO "B80"]
+[Opening "Sicilian"]
+[Variation "Scheveningen variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 *
+
+[ECO "B80"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, English variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be3 a6 7. Qd2 *
+
+[ECO "B80"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, Vitolins variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Bb5+ *
+
+[ECO "B80"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, fianchetto variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. g3 *
+
+[ECO "B81"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, Keres attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. g4 *
+
+[ECO "B82"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, 6.f4"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. f4 *
+
+[ECO "B82"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, Tal variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. f4 Nc6 7. Be3 Be7 8.
+Qf3 *
+
+[ECO "B83"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, 6.Be2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 *
+
+[ECO "B83"]
+[Opening "Sicilian"]
+[Variation "modern Scheveningen"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 Nc6 *
+
+[ECO "B83"]
+[Opening "Sicilian"]
+[Variation "modern Scheveningen, main line"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 Nc6 7. O-O Be7 
+8. Be3 O-O 9. f4 *
+
+[ECO "B83"]
+[Opening "Sicilian"]
+[Variation "modern Scheveningen, main line with Nb3"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 Nc6 7. O-O Be7 
+8. Be3 O-O 9. f4 Bd7 10. Nb3 *
+
+[ECO "B84"]
+[Opening "Sicilian"]
+[Variation "Scheveningen (Paulsen), classical variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 a6 *
+
+[ECO "B84"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, classical, Nd7 system"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 a6 7. O-O Nbd7 *
+
+[ECO "B84"]
+[Opening "Sicilian"]
+[Variation "Scheveningen (Paulsen), classical variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 a6 7. O-O Qc7 *
+
+[ECO "B85"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, classical variation with ...Qc7 and ...Nc6"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 a6 7. O-O Qc7 8.
+f4 Nc6 *
+
+[ECO "B85"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, classical, Maroczy system"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 a6 7. O-O Qc7 8.
+f4 Nc6 9. Kh1 Be7 10. a4 *
+
+[ECO "B85"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, classical"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 a6 7. O-O Qc7 8.
+f4 Nc6 9. Be3 *
+
+[ECO "B85"]
+[Opening "Sicilian"]
+[Variation "Scheveningen, classical main line"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Be2 a6 7. O-O Qc7 8.
+f4 Nc6 9. Be3 Be7 10. Qe1 O-O *
+
+[ECO "B86"]
+[Opening "Sicilian"]
+[Variation "Sozin attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Bc4 *
+
+[ECO "B87"]
+[Opening "Sicilian"]
+[Variation "Sozin with ...a6 and ...b5"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Bc4 a6 7. Bb3 b5 *
+
+[ECO "B88"]
+[Opening "Sicilian"]
+[Variation "Sozin, Leonhardt variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Bc4 Nc6 *
+
+[ECO "B88"]
+[Opening "Sicilian"]
+[Variation "Sozin, Fischer variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Bc4 Nc6 7. Bb3 Be7 
+8. Be3 O-O 9. f4 *
+
+[ECO "B89"]
+[Opening "Sicilian"]
+[Variation "Sozin, 7.Be3"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Bc4 Nc6 7. Be3 *
+
+[ECO "B89"]
+[Opening "Sicilian"]
+[Variation "Velimirovic attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 e6 6. Bc4 Nc6 7. Be3 Be7 
+8. Qe2 *
+
+[ECO "B90"]
+[Opening "Sicilian"]
+[Variation "Najdorf"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 *
+
+[ECO "B90"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Adams attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. h3 *
+
+[ECO "B90"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Lipnitzky attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bc4 *
+
+[ECO "B90"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Byrne (English) attack"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 *
+
+[ECO "B91"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Zagreb (fianchetto) variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. g3 *
+
+[ECO "B92"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Opovcensky variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be2 *
+
+[ECO "B93"]
+[Opening "Sicilian"]
+[Variation "Najdorf, 6.f4"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. f4 *
+
+[ECO "B94"]
+[Opening "Sicilian"]
+[Variation "Najdorf, 6.Bg5"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 *
+
+[ECO "B94"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Ivkov variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 Nbd7 7. Bc4 Qa5
+8. Qd2 e6 9. O-O-O b5 10. Bb3 Bb7 11. Rhe1 Nc5 12. e5 *
+
+[ECO "B95"]
+[Opening "Sicilian"]
+[Variation "Najdorf, 6...e6"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 *
+
+[ECO "B96"]
+[Opening "Sicilian"]
+[Variation "Najdorf, 7.f4"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 7. f4 *
+
+[ECO "B96"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Polugayevsky variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 7. f4 b5 *
+
+[ECO "B96"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Polugayevsky, Simagin variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 7. f4 b5 8. 
+e5 dxe5 9. fxe5 Qc7 10. Qe2 *
+
+[ECO "B97"]
+[Opening "Sicilian"]
+[Variation "Najdorf, 7...Qb6"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 7. f4 Qb6 *
+
+[ECO "B97"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Poisoned pawn variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 7. f4 Qb6 8.
+Qd2 Qxb2 9. Rb1 Qa3 *
+
+[ECO "B98"]
+[Opening "Sicilian"]
+[Variation "Najdorf, 7...Be7"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 7. f4 Be7 *
+
+[ECO "B98"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Browne variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 7. f4 Be7 8.
+Qf3 h6 9. Bh4 Qc7 *
+
+[ECO "B98"]
+[Opening "Sicilian"]
+[Variation "Najdorf, Goteborg (Argentine) variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 7. f4 Be7 8.
+Qf3 h6 9. Bh4 g5 *
+
+[ECO "B98"]
+[Opening "Sicilian"]
+[Variation "Najdorf variation"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 7. f4 Be7 8.
+Qf3 Qc7 *
+
+[ECO "B99"]
+[Opening "Sicilian"]
+[Variation "Najdorf, 7...Be7 main line"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 e6 7. f4 Be7 8.
+Qf3 Qc7 9. O-O-O Nbd7 *
+
+[ECO "C00"]
+[Opening "French defence"]
+
+1. e4 e6 *
+
+[ECO "C00"]
+[Opening "French defence, Steiner variation"]
+
+1. e4 e6 2. c4 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "Reti (Spielmann) variation"]
+
+1. e4 e6 2. b3 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "Steinitz attack"]
+
+1. e4 e6 2. e5 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "Labourdonnais variation"]
+
+1. e4 e6 2. f4 *
+
+[ECO "C00"]
+[Opening "French defence"]
+
+1. e4 e6 2. Nf3 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "Wing gambit"]
+
+1. e4 e6 2. Nf3 d5 3. e5 c5 4. b4 *
+
+[ECO "C00"]
+[Opening "French defence"]
+
+1. e4 e6 2. Nc3 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "Pelikan variation"]
+
+1. e4 e6 2. Nc3 d5 3. f4 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "Two knights variation"]
+
+1. e4 e6 2. Nc3 d5 3. Nf3 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "Chigorin variation"]
+
+1. e4 e6 2. Qe2 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "King's Indian attack"]
+
+1. e4 e6 2. d3 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "Reversed Philidor formation"]
+
+1. e4 e6 2. d3 d5 3. Nd2 Nf6 4. Ngf3 Nc6 5. Be2 *
+
+[ECO "C00"]
+[Opening "French defence"]
+
+1. e4 e6 2. d4 *
+
+[ECO "C00"]
+[Opening "Lengfellner system"]
+
+1. e4 e6 2. d4 d6 *
+
+[ECO "C00"]
+[Opening "St. George defence"]
+
+1. e4 e6 2. d4 a6 *
+
+[ECO "C00"]
+[Opening "French defence"]
+
+1. e4 e6 2. d4 d5 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "Schlechter variation"]
+
+1. e4 e6 2. d4 d5 3. Bd3 *
+
+[ECO "C00"]
+[Opening "French"]
+[Variation "Alapin variation"]
+
+1. e4 e6 2. d4 d5 3. Be3 *
+
+[ECO "C01"]
+[Opening "French"]
+[Variation "exchange variation"]
+
+1. e4 e6 2. d4 d5 3. exd5 *
+
+[ECO "C01"]
+[Opening "French"]
+[Variation "exchange, Svenonius variation"]
+
+1. e4 e6 2. d4 d5 3. exd5 exd5 4. Nc3 Nf6 5. Bg5 *
+
+[ECO "C01"]
+[Opening "French"]
+[Variation "exchange, Bogolyubov variation"]
+
+1. e4 e6 2. d4 d5 3. exd5 exd5 4. Nc3 Nf6 5. Bg5 Nc6 *
+
+[ECO "C02"]
+[Opening "French"]
+[Variation "advance variation"]
+
+1. e4 e6 2. d4 d5 3. e5 *
+
+[ECO "C02"]
+[Opening "French"]
+[Variation "advance, Steinitz variation"]
+
+1. e4 e6 2. d4 d5 3. e5 c5 4. dxc5 *
+
+[ECO "C02"]
+[Opening "French"]
+[Variation "advance, Nimzovich variation"]
+
+1. e4 e6 2. d4 d5 3. e5 c5 4. Qg4 *
+
+[ECO "C02"]
+[Opening "French"]
+[Variation "advance, Nimzovich system"]
+
+1. e4 e6 2. d4 d5 3. e5 c5 4. Nf3 *
+
+[ECO "C02"]
+[Opening "French"]
+[Variation "advance variation"]
+
+1. e4 e6 2. d4 d5 3. e5 c5 4. c3 *
+
+[ECO "C02"]
+[Opening "French"]
+[Variation "advance, Wade variation"]
+
+1. e4 e6 2. d4 d5 3. e5 c5 4. c3 Qb6 5. Nf3 Bd7 *
+
+[ECO "C02"]
+[Opening "French"]
+[Variation "advance variation"]
+
+1. e4 e6 2. d4 d5 3. e5 c5 4. c3 Nc6 *
+
+[ECO "C02"]
+[Opening "French"]
+[Variation "advance, Paulsen attack"]
+
+1. e4 e6 2. d4 d5 3. e5 c5 4. c3 Nc6 5. Nf3 *
+
+[ECO "C02"]
+[Opening "French"]
+[Variation "advance, Milner-Barry gambit"]
+
+1. e4 e6 2. d4 d5 3. e5 c5 4. c3 Nc6 5. Nf3 Qb6 6. Bd3 *
+
+[ECO "C02"]
+[Opening "French"]
+[Variation "advance, Euwe variation"]
+
+1. e4 e6 2. d4 d5 3. e5 c5 4. c3 Nc6 5. Nf3 Bd7 *
+
+[ECO "C03"]
+[Opening "French"]
+[Variation "Tarrasch"]
+
+1. e4 e6 2. d4 d5 3. Nd2 *
+
+[ECO "C03"]
+[Opening "French"]
+[Variation "Tarrasch, Haberditz variation"]
+
+1. e4 e6 2. d4 d5 3. Nd2 f5 *
+
+[ECO "C03"]
+[Opening "French"]
+[Variation "Tarrasch, Guimard variation"]
+
+1. e4 e6 2. d4 d5 3. Nd2 Nc6 *
+
+[ECO "C04"]
+[Opening "French"]
+[Variation "Tarrasch, Guimard main line"]
+
+1. e4 e6 2. d4 d5 3. Nd2 Nc6 4. Ngf3 Nf6 *
+
+[ECO "C05"]
+[Opening "French"]
+[Variation "Tarrasch, closed variation"]
+
+1. e4 e6 2. d4 d5 3. Nd2 Nf6 *
+
+[ECO "C05"]
+[Opening "French"]
+[Variation "Tarrasch, Botvinnik variation"]
+
+1. e4 e6 2. d4 d5 3. Nd2 Nf6 4. e5 Nfd7 5. Bd3 c5 6. c3 b6 *
+
+[ECO "C05"]
+[Opening "French"]
+[Variation "Tarrasch, closed variation"]
+
+1. e4 e6 2. d4 d5 3. Nd2 Nf6 4. e5 Nfd7 5. Bd3 c5 6. c3 Nc6 *
+
+[ECO "C06"]
+[Opening "French"]
+[Variation "Tarrasch, closed variation, main line"]
+
+1. e4 e6 2. d4 d5 3. Nd2 Nf6 4. e5 Nfd7 5. Bd3 c5 6. c3 Nc6 7. Ne2 cxd4 8.
+cxd4 *
+
+[ECO "C06"]
+[Opening "French"]
+[Variation "Tarrasch, Leningrad variation"]
+
+1. e4 e6 2. d4 d5 3. Nd2 Nf6 4. e5 Nfd7 5. Bd3 c5 6. c3 Nc6 7. Ne2 cxd4 8.
+cxd4 Nb6 *
+
+[ECO "C07"]
+[Opening "French"]
+[Variation "Tarrasch, open variation"]
+
+1. e4 e6 2. d4 d5 3. Nd2 c5 *
+
+[ECO "C07"]
+[Opening "French"]
+[Variation "Tarrasch, Eliskases variation"]
+
+1. e4 e6 2. d4 d5 3. Nd2 c5 4. exd5 Qxd5 5. Ngf3 cxd4 6. Bc4 Qd8 *
+
+[ECO "C08"]
+[Opening "French"]
+[Variation "Tarrasch, open, 4.ed ed"]
+
+1. e4 e6 2. d4 d5 3. Nd2 c5 4. exd5 exd5 *
+
+[ECO "C09"]
+[Opening "French"]
+[Variation "Tarrasch, open variation, main line"]
+
+1. e4 e6 2. d4 d5 3. Nd2 c5 4. exd5 exd5 5. Ngf3 Nc6 *
+
+[ECO "C10"]
+[Opening "French"]
+[Variation "Paulsen variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 *
+
+[ECO "C10"]
+[Opening "French"]
+[Variation "Marshall variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 c5 *
+
+[ECO "C10"]
+[Opening "French"]
+[Variation "Rubinstein variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 dxe4 *
+
+[ECO "C10"]
+[Opening "French"]
+[Variation "Fort Knox variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bd7 5. Nf3 Bc6 *
+
+[ECO "C10"]
+[Opening "French"]
+[Variation "Rubinstein variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 *
+
+[ECO "C10"]
+[Opening "French"]
+[Variation "Rubinstein, Capablanca line"]
+
+1. e4 e6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Ne5
+*
+
+[ECO "C10"]
+[Opening "French"]
+[Variation "Frere (Becker) variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Qd5 *
+
+[ECO "C11"]
+[Opening "French defence"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 *
+
+[ECO "C11"]
+[Opening "French"]
+[Variation "Swiss variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bd3 *
+
+[ECO "C11"]
+[Opening "French"]
+[Variation "Henneberger variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Be3 *
+
+[ECO "C11"]
+[Opening "French"]
+[Variation "Steinitz variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. e5 *
+
+[ECO "C11"]
+[Opening "French"]
+[Variation "Steinitz, Bradford attack"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. e5 Nfd7 5. f4 c5 6. dxc5 Bxc5 7. Qg4 *
+
+[ECO "C11"]
+[Opening "French"]
+[Variation "Steinitz variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. e5 Nfd7 5. f4 c5 6. dxc5 Nc6 *
+
+[ECO "C11"]
+[Opening "French"]
+[Variation "Steinitz, Brodsky-Jones variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. e5 Nfd7 5. f4 c5 6. dxc5 Nc6 7. a3 Bxc5 8.
+Qg4 O-O 9. Nf3 f6 *
+
+[ECO "C11"]
+[Opening "French"]
+[Variation "Steinitz variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. e5 Nfd7 5. f4 c5 6. Nf3 *
+
+[ECO "C11"]
+[Opening "French"]
+[Variation "Steinitz, Boleslavsky variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. e5 Nfd7 5. f4 c5 6. Nf3 Nc6 7. Be3 *
+
+[ECO "C11"]
+[Opening "French"]
+[Variation "Steinitz, Gledhill attack"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. e5 Nfd7 5. Qg4 *
+
+[ECO "C11"]
+[Opening "French"]
+[Variation "Burn variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 dxe4 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, Bogolyubov variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. exd5 Qxd5 6. Bxf6 gxf6 7. Qd2 
+Qa5 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, advance variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. e5 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, Chigorin variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. e5 h6 6. exf6 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, Grigoriev variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. e5 h6 6. exf6 hxg5 7. fxg7 Rg8 
+8. h4 gxh4 9. Qg4 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, Bernstein variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. e5 h6 6. Bh4 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, Janowski variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. e5 h6 6. Be3 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, Dr. Olland (Dutch) variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. e5 h6 6. Bc1 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, Tartakower variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. e5 h6 6. Bd2 Nfd7 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, Lasker variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. e5 h6 6. Bd2 Bxc3 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, Duras variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. e5 h6 6. Bd2 Bxc3 7. bxc3 Ne4 8.
+Qg4 Kf8 9. Bc1 *
+
+[ECO "C12"]
+[Opening "French"]
+[Variation "MacCutcheon, Lasker variation, 8...g6"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Bb4 5. e5 h6 6. Bd2 Bxc3 7. bxc3 Ne4 8.
+Qg4 g6 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "classical"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "classical, Anderssen variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. Bxf6 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "classical, Anderssen-Richter variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. Bxf6 Bxf6 6. e5 Be7 7. Qg4 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "classical, Vistaneckis (Nimzovich) variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Ng8 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "classical, Frankfurt variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Ng8 6. Be3 b6 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "classical, Tartakower variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Ne4 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "Albin-Alekhine-Chatard attack"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. h4 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "Albin-Alekhine-Chatard attack, Maroczy variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. h4 a6 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "Albin-Alekhine-Chatard attack, Breyer variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. h4 c5 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "Albin-Alekhine-Chatard attack, Teichmann variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. h4 f6 *
+
+[ECO "C13"]
+[Opening "French"]
+[Variation "Albin-Alekhine-Chatard attack, Spielmann variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. h4 O-O *
+
+[ECO "C14"]
+[Opening "French"]
+[Variation "classical variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. Bxe7 Qxe7 *
+
+[ECO "C14"]
+[Opening "French"]
+[Variation "classical, Tarrasch variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. Bxe7 Qxe7 7. Bd3 *
+
+[ECO "C14"]
+[Opening "French"]
+[Variation "classical, Rubinstein variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. Bxe7 Qxe7 7. Qd2 *
+
+[ECO "C14"]
+[Opening "French"]
+[Variation "classical, Alapin variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. Bxe7 Qxe7 7. Nb5 *
+
+[ECO "C14"]
+[Opening "French"]
+[Variation "classical, Pollock variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. Bxe7 Qxe7 7. Qg4 *
+
+[ECO "C14"]
+[Opening "French"]
+[Variation "classical, Steinitz variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. Bxe7 Qxe7 7. f4 *
+
+[ECO "C14"]
+[Opening "French"]
+[Variation "classical, Stahlberg variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Nf6 4. Bg5 Be7 5. e5 Nfd7 6. Bxe7 Qxe7 7. f4 O-O 
+8. Nf3 c5 9. Qd2 Nc6 10. O-O-O c4 *
+
+[ECO "C15"]
+[Opening "French"]
+[Variation "Winawer (Nimzovich) variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 *
+
+[ECO "C15"]
+[Opening "French"]
+[Variation "Winawer, Kondratiyev variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. Bd3 c5 5. exd5 Qxd5 6. Bd2 *
+
+[ECO "C15"]
+[Opening "French"]
+[Variation "Winawer, fingerslip variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. Bd2 *
+
+[ECO "C15"]
+[Opening "French"]
+[Variation "Winawer, Alekhine (Maroczy) gambit"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. Ne2 *
+
+[ECO "C15"]
+[Opening "French"]
+[Variation "Winawer, Alekhine gambit, Alatortsev variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. Ne2 dxe4 5. a3 Be7 6. Nxe4 Nf6 7. N2g3 O-O
+8. Be2 Nc6 *
+
+[ECO "C15"]
+[Opening "French"]
+[Variation "Winawer, Alekhine gambit"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. Ne2 dxe4 5. a3 Bxc3+ *
+
+[ECO "C15"]
+[Opening "French"]
+[Variation "Winawer, Alekhine gambit, Kan variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. Ne2 dxe4 5. a3 Bxc3+ 6. Nxc3 Nc6 *
+
+[ECO "C16"]
+[Opening "French"]
+[Variation "Winawer, advance variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 *
+
+[ECO "C16"]
+[Opening "French"]
+[Variation "Winawer, Petrosian variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 Qd7 *
+
+[ECO "C17"]
+[Opening "French"]
+[Variation "Winawer, advance variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 *
+
+[ECO "C17"]
+[Opening "French"]
+[Variation "Winawer, advance, Bogolyubov variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. Bd2 *
+
+[ECO "C17"]
+[Opening "French"]
+[Variation "Winawer, advance, Russian variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. Qg4 *
+
+[ECO "C17"]
+[Opening "French"]
+[Variation "Winawer, advance, 5.a3"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 *
+
+[ECO "C17"]
+[Opening "French"]
+[Variation "Winawer, advance, Rauzer variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 cxd4 6. axb4 dxc3 7. Nf3 *
+
+[ECO "C18"]
+[Opening "French"]
+[Variation "Winawer, advance variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 Bxc3+ 6. bxc3 *
+
+[ECO "C18"]
+[Opening "French"]
+[Variation "Winawer, classical variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 Bxc3+ 6. bxc3 Qc7 *
+
+[ECO "C19"]
+[Opening "French"]
+[Variation "Winawer, advance, 6...Ne7"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 Bxc3+ 6. bxc3 Ne7 *
+
+[ECO "C19"]
+[Opening "French"]
+[Variation "Winawer, advance, Smyslov variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 Bxc3+ 6. bxc3 Ne7 7. a4 *
+
+[ECO "C19"]
+[Opening "French"]
+[Variation "Winawer, advance, positional main line"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 Bxc3+ 6. bxc3 Ne7 7. Nf3 *
+
+[ECO "C19"]
+[Opening "French"]
+[Variation "Winawer, advance, poisoned pawn variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 Bxc3+ 6. bxc3 Ne7 7. Qg4 *
+
+[ECO "C19"]
+[Opening "French"]
+[Variation "Winawer, advance, poisoned pawn, Euwe-Gligoric variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 Bxc3+ 6. bxc3 Ne7 7. Qg4 Qc7 8.
+Qxg7 Rg8 9. Qxh7 cxd4 10. Kd1 *
+
+[ECO "C19"]
+[Opening "French"]
+[Variation "Winawer, advance, poisoned pawn, Konstantinopolsky variation"]
+
+1. e4 e6 2. d4 d5 3. Nc3 Bb4 4. e5 c5 5. a3 Bxc3+ 6. bxc3 Ne7 7. Qg4 Qc7 8.
+Qxg7 Rg8 9. Qxh7 cxd4 10. Ne2 *
+
+[ECO "C20"]
+[Opening "King's pawn game"]
+
+1. e4 e5 *
+
+[ECO "C20"]
+[Opening "KP"]
+[Variation "Indian opening"]
+
+1. e4 e5 2. d3 *
+
+[ECO "C20"]
+[Opening "KP"]
+[Variation "Mengarini's opening"]
+
+1. e4 e5 2. a3 *
+
+[ECO "C20"]
+[Opening "KP"]
+[Variation "King's head opening"]
+
+1. e4 e5 2. f3 *
+
+[ECO "C20"]
+[Opening "KP"]
+[Variation "Patzer opening"]
+
+1. e4 e5 2. Qh5 *
+
+[ECO "C20"]
+[Opening "KP"]
+[Variation "Napoleon's opening"]
+
+1. e4 e5 2. Qf3 *
+
+[ECO "C20"]
+[Opening "KP"]
+[Variation "Lopez opening"]
+
+1. e4 e5 2. c3 *
+
+[ECO "C20"]
+[Opening "Alapin's opening"]
+
+1. e4 e5 2. Ne2 *
+
+[ECO "C21"]
+[Opening "Centre game"]
+
+1. e4 e5 2. d4 exd4 *
+
+[ECO "C21"]
+[Opening "Centre game, Kieseritsky variation"]
+
+1. e4 e5 2. d4 exd4 3. Nf3 c5 4. Bc4 b5 *
+
+[ECO "C21"]
+[Opening "Halasz gambit"]
+
+1. e4 e5 2. d4 exd4 3. f4 *
+
+[ECO "C21"]
+[Opening "Danish gambit"]
+
+1. e4 e5 2. d4 exd4 3. c3 *
+
+[ECO "C21"]
+[Opening "Danish gambit"]
+[Variation "Collijn defence"]
+
+1. e4 e5 2. d4 exd4 3. c3 dxc3 4. Bc4 cxb2 5. Bxb2 Qe7 *
+
+[ECO "C21"]
+[Opening "Danish gambit"]
+[Variation "Schlechter defence"]
+
+1. e4 e5 2. d4 exd4 3. c3 dxc3 4. Bc4 cxb2 5. Bxb2 d5 *
+
+[ECO "C21"]
+[Opening "Danish gambit"]
+[Variation "Soerensen defence"]
+
+1. e4 e5 2. d4 exd4 3. c3 d5 *
+
+[ECO "C21"]
+[Opening "Centre game"]
+
+1. e4 e5 2. d4 exd4 3. Qxd4 *
+
+[ECO "C22"]
+[Opening "Centre game"]
+
+1. e4 e5 2. d4 exd4 3. Qxd4 Nc6 *
+
+[ECO "C22"]
+[Opening "Centre game"]
+[Variation "Paulsen attack"]
+
+1. e4 e5 2. d4 exd4 3. Qxd4 Nc6 4. Qe3 *
+
+[ECO "C22"]
+[Opening "Centre game"]
+[Variation "Charousek variation"]
+
+1. e4 e5 2. d4 exd4 3. Qxd4 Nc6 4. Qe3 Bb4+ 5. c3 Be7 *
+
+[ECO "C22"]
+[Opening "Centre game"]
+[Variation "l'Hermet variation"]
+
+1. e4 e5 2. d4 exd4 3. Qxd4 Nc6 4. Qe3 f5 *
+
+[ECO "C22"]
+[Opening "Centre game"]
+[Variation "Berger variation"]
+
+1. e4 e5 2. d4 exd4 3. Qxd4 Nc6 4. Qe3 Nf6 *
+
+[ECO "C22"]
+[Opening "Centre game"]
+[Variation "Kupreichik variation"]
+
+1. e4 e5 2. d4 exd4 3. Qxd4 Nc6 4. Qe3 Nf6 5. Nc3 Bb4 6. Bd2 O-O 7. O-O-O 
+Re8 8. Bc4 d6 9. Nh3 *
+
+[ECO "C22"]
+[Opening "Centre game"]
+[Variation "Hall variation"]
+
+1. e4 e5 2. d4 exd4 3. Qxd4 Nc6 4. Qc4 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+
+1. e4 e5 2. Bc4 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Philidor counter-attack"]
+
+1. e4 e5 2. Bc4 c6 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Lisitsyn variation"]
+
+1. e4 e5 2. Bc4 c6 3. d4 d5 4. exd5 cxd5 5. Bb5+ Bd7 6. Bxd7+ Nxd7 7. dxe5
+Nxe5 8. Ne2 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Calabrese counter-gambit"]
+
+1. e4 e5 2. Bc4 f5 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Calabrese counter-gambit, Jaenisch variation"]
+
+1. e4 e5 2. Bc4 f5 3. d3 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Classical variation"]
+
+1. e4 e5 2. Bc4 Bc5 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Lopez gambit"]
+
+1. e4 e5 2. Bc4 Bc5 3. Qe2 Nc6 4. c3 Nf6 5. f4 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Philidor variation"]
+
+1. e4 e5 2. Bc4 Bc5 3. c3 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Pratt variation"]
+
+1. e4 e5 2. Bc4 Bc5 3. c3 Nf6 4. d4 exd4 5. e5 d5 6. exf6 dxc4 7. Qh5 O-O *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Lewis counter-gambit"]
+
+1. e4 e5 2. Bc4 Bc5 3. c3 d5 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "del Rio variation"]
+
+1. e4 e5 2. Bc4 Bc5 3. c3 Qg5 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Lewis gambit"]
+
+1. e4 e5 2. Bc4 Bc5 3. d4 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Wing gambit"]
+
+1. e4 e5 2. Bc4 Bc5 3. b4 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "MacDonnell double gambit"]
+
+1. e4 e5 2. Bc4 Bc5 3. b4 Bxb4 4. f4 *
+
+[ECO "C23"]
+[Opening "Bishop's opening"]
+[Variation "Four pawns' gambit"]
+
+1. e4 e5 2. Bc4 Bc5 3. b4 Bxb4 4. f4 exf4 5. Nf3 Be7 6. d4 Bh4+ 7. g3 fxg3
+8. O-O gxh2+ 9. Kh1 *
+
+[ECO "C24"]
+[Opening "Bishop's opening"]
+[Variation "Berlin defence"]
+
+1. e4 e5 2. Bc4 Nf6 *
+
+[ECO "C24"]
+[Opening "Bishop's opening"]
+[Variation "Greco gambit"]
+
+1. e4 e5 2. Bc4 Nf6 3. f4 *
+
+[ECO "C24"]
+[Opening "Bishop's opening"]
+[Variation "Ponziani gambit"]
+
+1. e4 e5 2. Bc4 Nf6 3. d4 *
+
+[ECO "C24"]
+[Opening "Bishop's opening"]
+[Variation "Urusov gambit"]
+
+1. e4 e5 2. Bc4 Nf6 3. d4 exd4 4. Nf3 *
+
+[ECO "C24"]
+[Opening "Bishop's opening"]
+[Variation "Urusov gambit, Panov variation"]
+
+1. e4 e5 2. Bc4 Nf6 3. d4 exd4 4. Nf3 d5 5. exd5 Bb4+ 6. c3 Qe7+ *
+
+[ECO "C25"]
+[Opening "Vienna game"]
+
+1. e4 e5 2. Nc3 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Zhuravlev countergambit"]
+
+1. e4 e5 2. Nc3 Bb4 3. Qg4 Nf6 *
+
+[ECO "C25"]
+[Opening "Vienna game, Max Lange defence"]
+
+1. e4 e5 2. Nc3 Nc6 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Paulsen variation"]
+
+1. e4 e5 2. Nc3 Nc6 3. g3 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Fyfe gambit"]
+
+1. e4 e5 2. Nc3 Nc6 3. d4 *
+
+[ECO "C25"]
+[Opening "Vienna gambit"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Steinitz gambit"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 exf4 4. d4 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Steinitz gambit, Zukertort defence"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 exf4 4. d4 Qh4+ 5. Ke2 d5 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Steinitz gambit, Fraser-Minckwitz variation"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 exf4 4. d4 Qh4+ 5. Ke2 b6 *
+
+[ECO "C25"]
+[Opening "Vienna gambit"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 exf4 4. Nf3 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Hamppe-Allgaier gambit"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 exf4 4. Nf3 g5 5. h4 g4 6. Ng5 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Hamppe-Allgaier gambit, Alapin variation"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 exf4 4. Nf3 g5 5. h4 g4 6. Ng5 d6 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Hamppe-Muzio gambit"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 exf4 4. Nf3 g5 5. Bc4 g4 6. O-O *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Hamppe-Muzio, Dubois variation"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 exf4 4. Nf3 g5 5. Bc4 g4 6. O-O gxf3 7. Qxf3 Ne5
+8. Qxf4 Qf6 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Pierce gambit"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 exf4 4. Nf3 g5 5. d4 *
+
+[ECO "C25"]
+[Opening "Vienna"]
+[Variation "Pierce gambit, Rushmere attack"]
+
+1. e4 e5 2. Nc3 Nc6 3. f4 exf4 4. Nf3 g5 5. d4 g4 6. Bc4 gxf3 7. O-O d5 8.
+exd5 Bg4 9. dxc6 *
+
+[ECO "C26"]
+[Opening "Vienna"]
+[Variation "Falkbeer variation"]
+
+1. e4 e5 2. Nc3 Nf6 *
+
+[ECO "C26"]
+[Opening "Vienna"]
+[Variation "Mengarini variation"]
+
+1. e4 e5 2. Nc3 Nf6 3. a3 *
+
+[ECO "C26"]
+[Opening "Vienna"]
+[Variation "Paulsen-Mieses variation"]
+
+1. e4 e5 2. Nc3 Nf6 3. g3 *
+
+[ECO "C26"]
+[Opening "Vienna game"]
+
+1. e4 e5 2. Nc3 Nf6 3. Bc4 *
+
+[ECO "C27"]
+[Opening "Vienna game"]
+
+1. e4 e5 2. Nc3 Nf6 3. Bc4 Nxe4 *
+
+[ECO "C27"]
+[Opening "Vienna"]
+[Variation "`Frankenstein-Dracula' variation"]
+
+1. e4 e5 2. Nc3 Nf6 3. Bc4 Nxe4 4. Qh5 Nd6 5. Bb3 Nc6 6. Nb5 g6 7. Qf3 f5 
+8. Qd5 Qe7 9. Nxc7+ Kd8 10. Nxa8 b6 *
+
+[ECO "C27"]
+[Opening "Vienna"]
+[Variation "Adams' gambit"]
+
+1. e4 e5 2. Nc3 Nf6 3. Bc4 Nxe4 4. Qh5 Nd6 5. Bb3 Nc6 6. d4 *
+
+[ECO "C27"]
+[Opening "Vienna game"]
+
+1. e4 e5 2. Nc3 Nf6 3. Bc4 Nxe4 4. Qh5 Nd6 5. Bb3 Be7 *
+
+[ECO "C27"]
+[Opening "Vienna"]
+[Variation "Alekhine variation"]
+
+1. e4 e5 2. Nc3 Nf6 3. Bc4 Nxe4 4. Qh5 Nd6 5. Bb3 Be7 6. Nf3 Nc6 7. Nxe5 *
+
+[ECO "C27"]
+[Opening "Boden-Kieseritsky gambit"]
+
+1. e4 e5 2. Nc3 Nf6 3. Bc4 Nxe4 4. Nf3 *
+
+[ECO "C27"]
+[Opening "Boden-Kieseritsky gambit"]
+[Variation "Lichtenhein defence"]
+
+1. e4 e5 2. Nc3 Nf6 3. Bc4 Nxe4 4. Nf3 d5 *
+
+[ECO "C28"]
+[Opening "Vienna game"]
+
+1. e4 e5 2. Nc3 Nf6 3. Bc4 Nc6 *
+
+[ECO "C29"]
+[Opening "Vienna gambit"]
+
+1. e4 e5 2. Nc3 Nf6 3. f4 d5 *
+
+[ECO "C29"]
+[Opening "Vienna gambit"]
+[Variation "Kaufmann variation"]
+
+1. e4 e5 2. Nc3 Nf6 3. f4 d5 4. fxe5 Nxe4 5. Nf3 Bg4 6. Qe2 *
+
+[ECO "C29"]
+[Opening "Vienna gambit"]
+[Variation "Breyer variation"]
+
+1. e4 e5 2. Nc3 Nf6 3. f4 d5 4. fxe5 Nxe4 5. Nf3 Be7 *
+
+[ECO "C29"]
+[Opening "Vienna gambit"]
+[Variation "Paulsen attack"]
+
+1. e4 e5 2. Nc3 Nf6 3. f4 d5 4. fxe5 Nxe4 5. Qf3 *
+
+[ECO "C29"]
+[Opening "Vienna gambit"]
+[Variation "Bardeleben variation"]
+
+1. e4 e5 2. Nc3 Nf6 3. f4 d5 4. fxe5 Nxe4 5. Qf3 f5 *
+
+[ECO "C29"]
+[Opening "Vienna gambit"]
+[Variation "Heyde variation"]
+
+1. e4 e5 2. Nc3 Nf6 3. f4 d5 4. fxe5 Nxe4 5. Qf3 f5 6. d4 *
+
+[ECO "C29"]
+[Opening "Vienna gambit"]
+
+1. e4 e5 2. Nc3 Nf6 3. f4 d5 4. fxe5 Nxe4 5. d3 *
+
+[ECO "C29"]
+[Opening "Vienna gambit, Wurzburger trap"]
+
+1. e4 e5 2. Nc3 Nf6 3. f4 d5 4. fxe5 Nxe4 5. d3 Qh4+ 6. g3 Nxg3 7. Nf3 Qh5
+8. Nxd5 *
+
+[ECO "C29"]
+[Opening "Vienna gambit, Steinitz variation"]
+
+1. e4 e5 2. Nc3 Nf6 3. f4 d5 4. d3 *
+
+[ECO "C30"]
+[Opening "King's gambit"]
+
+1. e4 e5 2. f4 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "Keene's defence"]
+
+1. e4 e5 2. f4 Qh4+ 3. g3 Qe7 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "Mafia defence"]
+
+1. e4 e5 2. f4 c5 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "Norwalde variation"]
+
+1. e4 e5 2. f4 Qf6 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "Norwalde variation, Buecker gambit"]
+
+1. e4 e5 2. f4 Qf6 3. Nf3 Qxf4 4. Nc3 Bb4 5. Bc4 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "classical variation"]
+
+1. e4 e5 2. f4 Bc5 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "classical, Svenonius variation"]
+
+1. e4 e5 2. f4 Bc5 3. Nf3 d6 4. Nc3 Nf6 5. Bc4 Nc6 6. d3 Bg4 7. h3 Bxf3 8.
+Qxf3 exf4 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "classical, Hanham variation"]
+
+1. e4 e5 2. f4 Bc5 3. Nf3 d6 4. Nc3 Nd7 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "classical, 4.c3"]
+
+1. e4 e5 2. f4 Bc5 3. Nf3 d6 4. c3 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "classical, Marshall attack"]
+
+1. e4 e5 2. f4 Bc5 3. Nf3 d6 4. c3 Bg4 5. fxe5 dxe5 6. Qa4+ *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "classical counter-gambit"]
+
+1. e4 e5 2. f4 Bc5 3. Nf3 d6 4. c3 f5 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "classical, Reti variation"]
+
+1. e4 e5 2. f4 Bc5 3. Nf3 d6 4. c3 f5 5. fxe5 dxe5 6. d4 exd4 7. Bc4 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "classical, Soldatenkov variation"]
+
+1. e4 e5 2. f4 Bc5 3. Nf3 d6 4. fxe5 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "classical, Heath variation"]
+
+1. e4 e5 2. f4 Bc5 3. Nf3 d6 4. b4 *
+
+[ECO "C30"]
+[Opening "KGD"]
+[Variation "2...Nf6"]
+
+1. e4 e5 2. f4 Nf6 *
+
+[ECO "C31"]
+[Opening "KGD"]
+[Variation "Falkbeer counter-gambit"]
+
+1. e4 e5 2. f4 d5 *
+
+[ECO "C31"]
+[Opening "KGD"]
+[Variation "Falkbeer, Tartakower variation"]
+
+1. e4 e5 2. f4 d5 3. Nf3 *
+
+[ECO "C31"]
+[Opening "KGD"]
+[Variation "Falkbeer, Milner-Barry variation"]
+
+1. e4 e5 2. f4 d5 3. Nc3 *
+
+[ECO "C31"]
+[Opening "KGD"]
+[Variation "Falkbeer counter-gambit"]
+
+1. e4 e5 2. f4 d5 3. exd5 *
+
+[ECO "C31"]
+[Opening "KGD"]
+[Variation "Nimzovich counter-gambit"]
+
+1. e4 e5 2. f4 d5 3. exd5 c6 *
+
+[ECO "C31"]
+[Opening "KGD"]
+[Variation "Falkbeer, 3...e4"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 *
+
+[ECO "C31"]
+[Opening "KGD"]
+[Variation "Falkbeer, Rubinstein variation"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. Nc3 Nf6 5. Qe2 *
+
+[ECO "C31"]
+[Opening "KGD"]
+[Variation "Falkbeer, Nimzovich variation"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. Bb5+ *
+
+[ECO "C31"]
+[Opening "KGD"]
+[Variation "Falkbeer, 4.d3"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. d3 *
+
+[ECO "C31"]
+[Opening "KGD"]
+[Variation "Falkbeer, Morphy gambit"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. d3 Nf6 5. Nc3 Bb4 6. Bd2 e3 *
+
+[ECO "C32"]
+[Opening "KGD"]
+[Variation "Falkbeer, 5.de"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. d3 Nf6 5. dxe4 *
+
+[ECO "C32"]
+[Opening "KGD"]
+[Variation "Falkbeer, Alapin variation"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. d3 Nf6 5. dxe4 Nxe4 6. Nf3 Bc5 7. Qe2 Bf2+
+8. Kd1 Qxd5+ 9. Nfd2 *
+
+[ECO "C32"]
+[Opening "KGD"]
+[Variation "Falkbeer, main line, 7...Bf5"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. d3 Nf6 5. dxe4 Nxe4 6. Nf3 Bc5 7. Qe2 Bf5 *
+
+[ECO "C32"]
+[Opening "KGD"]
+[Variation "Falkbeer, Tarrasch variation"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. d3 Nf6 5. dxe4 Nxe4 6. Nf3 Bc5 7. Qe2 Bf5 
+8. g4 O-O *
+
+[ECO "C32"]
+[Opening "KGD"]
+[Variation "Falkbeer, Charousek gambit"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. d3 Nf6 5. dxe4 Nxe4 6. Qe2 *
+
+[ECO "C32"]
+[Opening "KGD"]
+[Variation "Falkbeer, Charousek variation"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. d3 Nf6 5. dxe4 Nxe4 6. Qe2 Qxd5 7. Nd2 f5 
+8. g4 *
+
+[ECO "C32"]
+[Opening "KGD"]
+[Variation "Falkbeer, Keres variation"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. d3 Nf6 5. Nd2 *
+
+[ECO "C32"]
+[Opening "KGD"]
+[Variation "Falkbeer, Reti variation"]
+
+1. e4 e5 2. f4 d5 3. exd5 e4 4. d3 Nf6 5. Qe2 *
+
+[ECO "C33"]
+[Opening "King's gambit accepted"]
+
+1. e4 e5 2. f4 exf4 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "Tumbleweed gambit"]
+
+1. e4 e5 2. f4 exf4 3. Kf2 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "Orsini gambit"]
+
+1. e4 e5 2. f4 exf4 3. b3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "Pawn's gambit (Stamma gambit)"]
+
+1. e4 e5 2. f4 exf4 3. h4 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "Schurig gambit"]
+
+1. e4 e5 2. f4 exf4 3. Bd3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "Carrera (Basman) gambit"]
+
+1. e4 e5 2. f4 exf4 3. Qe2 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "Villemson (Steinitz) gambit"]
+
+1. e4 e5 2. f4 exf4 3. d4 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "Keres (Mason-Steinitz) gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nc3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "Breyer gambit"]
+
+1. e4 e5 2. f4 exf4 3. Qf3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "Lesser bishop's (Petroff-Jaenisch-Tartakower) gambit"]
+
+1. e4 e5 2. f4 exf4 3. Be2 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Chigorin's attack"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 d5 5. Bxd5 g5 6. g3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Greco variation"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 Bc5 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, classical defence"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 g5 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Grimm attack"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 g5 5. Nc3 Bg7 6. d4 d6 7. e5 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, classical defence"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 g5 5. Nc3 Bg7 6. d4 Ne7 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, McDonnell attack"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 g5 5. Nc3 Bg7 6. d4 Ne7 7. g3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, McDonnell attack"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 g5 5. Nc3 Bg7 6. g3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Fraser variation"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 g5 5. Nc3 Bg7 6. g3 fxg3 7. Qf3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, classical defence, Cozio attack"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 g5 5. Qf3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Boden defence"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 Nc6 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Bryan counter-gambit"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 b5 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Bryan counter-gambit"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 b5 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Steinitz defence"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Ne7 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Maurian defence"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Nc6 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Ruy Lopez defence"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 c6 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Lopez-Gianutio counter-gambit"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 f5 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "Lopez-Gianutio counter-gambit, Hein variation"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 f5 4. Qe2 Qh4+ 5. Kd1 fxe4 6. Nc3 Kd8 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Bledow variation"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 d5 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Gifford variation"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 d5 4. Bxd5 Qh4+ 5. Kf1 g5 6. g3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Boren-Svenonius variation"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 d5 4. Bxd5 Qh4+ 5. Kf1 Bd6 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Anderssen variation"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 d5 4. Bxd5 c6 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Morphy variation"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 d5 4. Bxd5 Nf6 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Cozio (Morphy) defence"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Nf6 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Bogolyubov variation"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Nf6 4. Nc3 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Paulsen attack"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Nf6 4. Nc3 Bb4 5. e5 *
+
+[ECO "C33"]
+[Opening "KGA"]
+[Variation "bishop's gambit, Jaenisch variation"]
+
+1. e4 e5 2. f4 exf4 3. Bc4 Nf6 4. Nc3 c6 *
+
+[ECO "C34"]
+[Opening "King's knight's gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 *
+
+[ECO "C34"]
+[Opening "KGA"]
+[Variation "Bonsch-Osmolovsky variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 Ne7 *
+
+[ECO "C34"]
+[Opening "KGA"]
+[Variation "Gianutio counter-gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 f5 *
+
+[ECO "C34"]
+[Opening "KGA"]
+[Variation "Fischer defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 d6 *
+
+[ECO "C34"]
+[Opening "KGA"]
+[Variation "Becker defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 h6 *
+
+[ECO "C34"]
+[Opening "KGA"]
+[Variation "Schallop defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 Nf6 *
+
+[ECO "C35"]
+[Opening "KGA"]
+[Variation "Cunningham defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 Be7 *
+
+[ECO "C35"]
+[Opening "KGA"]
+[Variation "Cunningham, Bertin gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 Be7 4. Bc4 Bh4+ 5. g3 *
+
+[ECO "C35"]
+[Opening "KGA"]
+[Variation "Cunningham, three pawns gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 Be7 4. Bc4 Bh4+ 5. g3 fxg3 6. O-O gxh2+ 7. Kh1 *
+
+[ECO "C35"]
+[Opening "KGA"]
+[Variation "Cunningham, Euwe defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 Be7 4. Bc4 Nf6 *
+
+[ECO "C36"]
+[Opening "KGA"]
+[Variation "Abbazia defence (classical defence, modern defence[!])"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 d5 *
+
+[ECO "C36"]
+[Opening "KGA"]
+[Variation "Abbazia defence, modern variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 d5 4. exd5 Nf6 *
+
+[ECO "C36"]
+[Opening "KGA"]
+[Variation "Abbazia defence, Botvinnik variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 d5 4. exd5 Nf6 5. Bb5+ c6 6. dxc6 bxc6 7. Bc4 
+Nd5 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Quaade gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Nc3 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Rosentreter gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. d4 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Soerensen gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. d4 g4 5. Ne5 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "King's knight's gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Blachly gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 Nc6 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Lolli gambit (wild Muzio gambit)"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. Bxf7+ *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Lolli gambit, Young variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. Bxf7+ Kxf7 6. O-O gxf3 7. Qxf3 
+Qf6 8. d4 Qxd4+ 9. Be3 Qf6 10. Nc3 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Ghulam Kassim gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. d4 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "MacDonnell gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. Nc3 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Salvio gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. Ne5 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Silberschmidt gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. Ne5 Qh4+ 6. Kf1 Nh6 7. d4 f3 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Salvio gambit, Anderssen counter-attack"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. Ne5 Qh4+ 6. Kf1 Nh6 7. d4 d6 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Cochrane gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. Ne5 Qh4+ 6. Kf1 f3 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Herzfeld gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. Ne5 Qh4+ 6. Kf1 Nc6 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Muzio gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. O-O *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Muzio gambit, Paulsen variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. O-O gxf3 6. Qxf3 Qf6 7. e5 Qxe5
+8. d3 Bh6 9. Nc3 Ne7 10. Bd2 Nbc6 11. Rae1 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "double Muzio gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. O-O gxf3 6. Qxf3 Qf6 7. e5 Qxe5
+8. Bxf7+ *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Muzio gambit, From defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. O-O gxf3 6. Qxf3 Qe7 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Muzio gambit, Holloway defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. O-O gxf3 6. Qxf3 Nc6 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Muzio gambit, Kling and Horwitz counter-attack"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. O-O Qe7 *
+
+[ECO "C37"]
+[Opening "KGA"]
+[Variation "Muzio gambit, Brentano defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 g4 5. O-O d5 *
+
+[ECO "C38"]
+[Opening "King's knight's gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 Bg7 *
+
+[ECO "C38"]
+[Opening "KGA"]
+[Variation "Hanstein gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 Bg7 5. O-O *
+
+[ECO "C38"]
+[Opening "KGA"]
+[Variation "Philidor gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 Bg7 5. h4 *
+
+[ECO "C38"]
+[Opening "KGA"]
+[Variation "Greco gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 Bg7 5. h4 h6 6. d4 d6 7. Nc3 c6 8. 
+hxg5 hxg5 9. Rxh8 Bxh8 10. Ne5 *
+
+[ECO "C38"]
+[Opening "KGA"]
+[Variation "Philidor gambit, Schultz variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. Bc4 Bg7 5. h4 h6 6. d4 d6 7. Qd3 *
+
+[ECO "C39"]
+[Opening "King's knight's gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Allgaier gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ng5 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Allgaier, Horny defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ng5 h6 6. Nxf7 Kxf7 7. Qxg4 Nf6 
+8. Qxf4 Bd6 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Allgaier, Thorold variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ng5 h6 6. Nxf7 Kxf7 7. d4 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Allgaier, Cook variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ng5 h6 6. Nxf7 Kxf7 7. d4 d5 8. 
+Bxf4 dxe4 9. Bc4+ Kg7 10. Be5+ *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Allgaier, Blackburne gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ng5 h6 6. Nxf7 Kxf7 7. Nc3 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Allgaier, Walker attack"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ng5 h6 6. Nxf7 Kxf7 7. Bc4+ *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Allgaier, Urusov attack"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ng5 h6 6. Nxf7 Kxf7 7. Bc4+ d5 8.
+Bxd5+ Kg7 9. d4 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Allgaier, Schlechter defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ng5 Nf6 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Paulsen defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 Bg7 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, long whip (Stockwhip, classical) defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 h5 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, long whip defence, Jaenisch variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 h5 6. Bc4 Rh7 7. d4 Bh6 8. 
+Nc3 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Brentano (Campbell) defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 d5 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Brentano defence, Kaplanek variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 d5 6. d4 Nf6 7. exd5 Qxd5 8.
+Nc3 Bb4 9. Kf2 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Brentano defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 d5 6. d4 Nf6 7. Bxf4 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Brentano defence, Caro variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 d5 6. d4 Nf6 7. Bxf4 Nxe4 8.
+Nd2 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Salvio (Rosenthal) defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 Qe7 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Salvio defence, Cozio variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 Qe7 6. d4 f5 7. Bc4 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Polerio defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 Be7 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Neumann defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 Nc6 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Kolisch defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 d6 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Berlin defence"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 Nf6 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Berlin defence, Riviere variation"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 Nf6 6. Nxg4 d5 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Berlin defence, 6.Bc4"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 Nf6 6. Bc4 *
+
+[ECO "C39"]
+[Opening "KGA"]
+[Variation "Kieseritsky, Rice gambit"]
+
+1. e4 e5 2. f4 exf4 3. Nf3 g5 4. h4 g4 5. Ne5 Nf6 6. Bc4 d5 7. exd5 Bd6 8.
+O-O *
+
+[ECO "C40"]
+[Opening "King's knight opening"]
+
+1. e4 e5 2. Nf3 *
+
+[ECO "C40"]
+[Opening "Gunderam defence"]
+
+1. e4 e5 2. Nf3 Qe7 *
+
+[ECO "C40"]
+[Opening "Greco defence"]
+
+1. e4 e5 2. Nf3 Qf6 *
+
+[ECO "C40"]
+[Opening "Damiano's defence"]
+
+1. e4 e5 2. Nf3 f6 *
+
+[ECO "C40"]
+[Opening "QP counter-gambit (elephant gambit)"]
+
+1. e4 e5 2. Nf3 d5 *
+
+[ECO "C40"]
+[Opening "QP counter-gambit"]
+[Variation "Maroczy gambit"]
+
+1. e4 e5 2. Nf3 d5 3. exd5 Bd6 *
+
+[ECO "C40"]
+[Opening "Latvian counter-gambit"]
+
+1. e4 e5 2. Nf3 f5 *
+
+[ECO "C40"]
+[Opening "Latvian"]
+[Variation "Nimzovich variation"]
+
+1. e4 e5 2. Nf3 f5 3. Nxe5 Qf6 4. d4 d6 5. Nc4 fxe4 6. Ne3 *
+
+[ECO "C40"]
+[Opening "Latvian"]
+[Variation "Fraser defence"]
+
+1. e4 e5 2. Nf3 f5 3. Nxe5 Nc6 *
+
+[ECO "C40"]
+[Opening "Latvian gambit, 3.Bc4"]
+
+1. e4 e5 2. Nf3 f5 3. Bc4 *
+
+[ECO "C40"]
+[Opening "Latvian"]
+[Variation "Behting variation"]
+
+1. e4 e5 2. Nf3 f5 3. Bc4 fxe4 4. Nxe5 Qg5 5. Nf7 Qxg2 6. Rf1 d5 7. Nxh8 
+Nf6 *
+
+[ECO "C40"]
+[Opening "Latvian"]
+[Variation "Polerio variation"]
+
+1. e4 e5 2. Nf3 f5 3. Bc4 fxe4 4. Nxe5 d5 *
+
+[ECO "C40"]
+[Opening "Latvian"]
+[Variation "corkscrew counter-gambit"]
+
+1. e4 e5 2. Nf3 f5 3. Bc4 fxe4 4. Nxe5 Nf6 *
+
+[ECO "C41"]
+[Opening "Philidor's defence"]
+
+1. e4 e5 2. Nf3 d6 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Steinitz variation"]
+
+1. e4 e5 2. Nf3 d6 3. Bc4 Be7 4. c3 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Lopez counter-gambit"]
+
+1. e4 e5 2. Nf3 d6 3. Bc4 f5 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Lopez counter-gambit, Jaenisch variation"]
+
+1. e4 e5 2. Nf3 d6 3. Bc4 f5 4. d4 exd4 5. Ng5 Nh6 6. Nxh7 *
+
+[ECO "C41"]
+[Opening "Philidor's defence"]
+
+1. e4 e5 2. Nf3 d6 3. d4 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Philidor counter-gambit"]
+
+1. e4 e5 2. Nf3 d6 3. d4 f5 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Philidor counter-gambit, del Rio attack"]
+
+1. e4 e5 2. Nf3 d6 3. d4 f5 4. dxe5 fxe4 5. Ng5 d5 6. e6 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Philidor counter-gambit, Berger variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 f5 4. dxe5 fxe4 5. Ng5 d5 6. e6 Bc5 7. Nc3 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Philidor counter-gambit, Zukertort variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 f5 4. Nc3 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "exchange variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 exd4 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Boden variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 exd4 4. Qxd4 Bd7 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "exchange variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 exd4 4. Nxd4 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Paulsen attack"]
+
+1. e4 e5 2. Nf3 d6 3. d4 exd4 4. Nxd4 d5 5. exd5 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "exchange variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 exd4 4. Nxd4 Nf6 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Berger variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 exd4 4. Nxd4 Nf6 5. Nc3 Be7 6. Be2 O-O 7. O-O c5 
+8. Nf3 Nc6 9. Bg5 Be6 10. Re1 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Larsen variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 exd4 4. Nxd4 g6 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Nimzovich (Jaenisch) variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nf6 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Improved Hanham variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nf6 4. Nc3 Nbd7 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Nimzovich, Sozin variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nf6 4. Nc3 Nbd7 5. Bc4 Be7 6. O-O O-O 7. Qe2 c6 8.
+a4 exd4 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Nimzovich, Larobok variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nf6 4. Nc3 Nbd7 5. Bc4 Be7 6. Ng5 O-O 7. Bxf7+ *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Nimzovich variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nf6 4. dxe5 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Nimzovich, Sokolsky variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nf6 4. dxe5 Nxe4 5. Nbd2 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Nimzovich, Rellstab variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nf6 4. dxe5 Nxe4 5. Qd5 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Nimzovich, Locock variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nf6 4. Ng5 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Nimzovich, Klein variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nf6 4. Bc4 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Hanham variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nd7 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Hanham, Krause variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nd7 4. Bc4 c6 5. O-O *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Hanham, Steiner variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nd7 4. Bc4 c6 5. O-O Be7 6. dxe5 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Hanham, Kmoch variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nd7 4. Bc4 c6 5. Ng5 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Hanham, Berger variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nd7 4. Bc4 c6 5. Ng5 Nh6 6. f4 Be7 7. O-O O-O 8. 
+c3 d5 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Hanham, Schlechter variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nd7 4. Bc4 c6 5. Nc3 *
+
+[ECO "C41"]
+[Opening "Philidor"]
+[Variation "Hanham, Delmar variation"]
+
+1. e4 e5 2. Nf3 d6 3. d4 Nd7 4. Bc4 c6 5. c3 *
+
+[ECO "C42"]
+[Opening "Petrov's defence"]
+
+1. e4 e5 2. Nf3 Nf6 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "French attack"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d3 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "Kaufmann attack"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. c4 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "Nimzovich attack"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. Nc3 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "Cozio (Lasker) attack"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. Qe2 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack, Chigorin variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 d5 6. Bd3 Be7 7. O-O Nc6 
+8. Re1 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack, Berger variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 d5 6. Bd3 Be7 7. O-O Nc6 
+8. Re1 Bg4 9. c3 f5 10. Nbd2 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack, Krause variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 d5 6. Bd3 Be7 7. O-O Nc6 
+8. Re1 Bg4 9. c3 f5 10. c4 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack, Maroczy variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 d5 6. Bd3 Be7 7. O-O Nc6 
+8. Re1 Bg4 9. c3 f5 10. c4 Bh4 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack, Jaenisch variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 d5 6. Bd3 Be7 7. O-O Nc6 
+8. c4 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack, Mason variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 d5 6. Bd3 Be7 7. O-O O-O *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack, Marshall variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 d5 6. Bd3 Bd6 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack, Tarrasch variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 d5 6. Bd3 Bd6 7. O-O O-O 
+8. c4 Bg4 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack, Marshall trap"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 d5 6. Bd3 Bd6 7. O-O O-O 
+8. c4 Bg4 9. cxd5 f5 10. Re1 Bxh2+ *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "classical attack, close variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nf3 Nxe4 5. d4 Nf6 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "Cochrane gambit"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nxf7 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "Paulsen attack"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 d6 4. Nc4 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "Damiano variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nxe5 Nxe4 *
+
+[ECO "C42"]
+[Opening "Petrov three knights game"]
+
+1. e4 e5 2. Nf3 Nf6 3. Nc3 *
+
+[ECO "C42"]
+[Opening "Petrov"]
+[Variation "Italian variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. Bc4 *
+
+[ECO "C43"]
+[Opening "Petrov"]
+[Variation "modern (Steinitz) attack"]
+
+1. e4 e5 2. Nf3 Nf6 3. d4 *
+
+[ECO "C43"]
+[Opening "Petrov"]
+[Variation "modern attack, main line"]
+
+1. e4 e5 2. Nf3 Nf6 3. d4 exd4 4. e5 Ne4 5. Qxd4 *
+
+[ECO "C43"]
+[Opening "Petrov"]
+[Variation "modern attack, Steinitz variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. d4 exd4 4. e5 Ne4 5. Qe2 *
+
+[ECO "C43"]
+[Opening "Petrov"]
+[Variation "modern attack, Bardeleben variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. d4 exd4 4. e5 Ne4 5. Qe2 Nc5 6. Nxd4 Nc6 *
+
+[ECO "C43"]
+[Opening "Petrov"]
+[Variation "Urusov gambit"]
+
+1. e4 e5 2. Nf3 Nf6 3. d4 exd4 4. Bc4 *
+
+[ECO "C43"]
+[Opening "Petrov"]
+[Variation "modern attack, Symmetrical variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. d4 Nxe4 *
+
+[ECO "C43"]
+[Opening "Petrov"]
+[Variation "modern attack, Trifunovic variation"]
+
+1. e4 e5 2. Nf3 Nf6 3. d4 Nxe4 4. Bd3 d5 5. Nxe5 Bd6 6. O-O O-O 7. c4 Bxe5
+*
+
+[ECO "C44"]
+[Opening "King's pawn game"]
+
+1. e4 e5 2. Nf3 Nc6 *
+
+[ECO "C44"]
+[Opening "Irish (Chicago) gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nxe5 Nxe5 4. d4 *
+
+[ECO "C44"]
+[Opening "Konstantinopolsky opening"]
+
+1. e4 e5 2. Nf3 Nc6 3. g3 *
+
+[ECO "C44"]
+[Opening "Dresden opening"]
+
+1. e4 e5 2. Nf3 Nc6 3. c4 *
+
+[ECO "C44"]
+[Opening "Inverted Hungarian"]
+
+1. e4 e5 2. Nf3 Nc6 3. Be2 *
+
+[ECO "C44"]
+[Opening "Inverted Hanham"]
+
+1. e4 e5 2. Nf3 Nc6 3. Be2 Nf6 4. d3 d5 5. Nbd2 *
+
+[ECO "C44"]
+[Opening "Tayler opening"]
+
+1. e4 e5 2. Nf3 Nc6 3. Be2 Nf6 4. d4 *
+
+[ECO "C44"]
+[Opening "Ponziani opening"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 *
+
+[ECO "C44"]
+[Opening "Ponziani"]
+[Variation "Caro variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 d5 4. Qa4 Bd7 *
+
+[ECO "C44"]
+[Opening "Ponziani"]
+[Variation "Leonhardt variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 d5 4. Qa4 Nf6 *
+
+[ECO "C44"]
+[Opening "Ponziani"]
+[Variation "Steinitz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 d5 4. Qa4 f6 *
+
+[ECO "C44"]
+[Opening "Ponziani"]
+[Variation "Jaenisch counter-attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 Nf6 *
+
+[ECO "C44"]
+[Opening "Ponziani"]
+[Variation "Fraser defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 Nf6 4. d4 Nxe4 5. d5 Bc5 *
+
+[ECO "C44"]
+[Opening "Ponziani"]
+[Variation "Reti variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 Nge7 *
+
+[ECO "C44"]
+[Opening "Ponziani"]
+[Variation "Romanishin variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 Be7 *
+
+[ECO "C44"]
+[Opening "Ponziani counter-gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 f5 *
+
+[ECO "C44"]
+[Opening "Ponziani counter-gambit, Schmidt attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 f5 4. d4 d6 5. d5 *
+
+[ECO "C44"]
+[Opening "Ponziani counter-gambit, Cordel variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. c3 f5 4. d4 d6 5. d5 fxe4 6. Ng5 Nb8 7. Nxe4 Nf6 8.
+Bd3 Be7 *
+
+[ECO "C44"]
+[Opening "Scotch opening"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 *
+
+[ECO "C44"]
+[Opening "Scotch"]
+[Variation "Lolli variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 Nxd4 *
+
+[ECO "C44"]
+[Opening "Scotch"]
+[Variation "Cochrane variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 Nxd4 4. Nxe5 Ne6 5. Bc4 c6 6. O-O Nf6 7. Nxf7 *
+
+[ECO "C44"]
+[Opening "Scotch"]
+[Variation "Relfsson gambit ('MacLopez')"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bb5 *
+
+[ECO "C44"]
+[Opening "Scotch"]
+[Variation "Goering gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. c3 *
+
+[ECO "C44"]
+[Opening "Scotch"]
+[Variation "Sea-cadet mate"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. c3 dxc3 5. Nxc3 d6 6. Bc4 Bg4 7. O-O Ne5
+8. Nxe5 Bxd1 9. Bxf7+ Ke7 10. Nd5# *
+
+[ECO "C44"]
+[Opening "Scotch"]
+[Variation "Goering gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. c3 dxc3 5. Nxc3 Bb4 *
+
+[ECO "C44"]
+[Opening "Scotch"]
+[Variation "Goering gambit, Bardeleben variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. c3 dxc3 5. Nxc3 Bb4 6. Bc4 Nf6 *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+[Variation "Anderssen (Paulsen, Suhle) counter-attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 Bc5 5. O-O d6 6. c3 Bg4 *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 Bc5 5. Ng5 *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+[Variation "Cochrane-Shumov defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 Bc5 5. Ng5 Nh6 6. Nxf7 Nxf7 7. Bxf7+
+Kxf7 8. Qh5+ g6 9. Qxc5 d5 *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+[Variation "Vitzhum attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 Bc5 5. Ng5 Nh6 6. Qh5 *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 Bb4+ *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+[Variation "Hanneken variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 Bb4+ 5. c3 dxc3 6. O-O cxb2 7. Bxb2 
+Nf6 8. Ng5 O-O 9. e5 Nxe5 *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 Bb4+ 5. c3 dxc3 6. bxc3 *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+[Variation "Cochrane variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 Bb4+ 5. c3 dxc3 6. bxc3 Ba5 7. e5 *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+[Variation "Benima defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 Be7 *
+
+[ECO "C44"]
+[Opening "Scotch gambit"]
+[Variation "Dubois-Reti defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Bc4 Nf6 *
+
+[ECO "C45"]
+[Opening "Scotch game"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Ghulam Kassim variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Nxd4 5. Qxd4 d6 6. Bd3 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Pulling counter-attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Qh4 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Horwitz attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Qh4 5. Nb5 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Berger variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Qh4 5. Nb5 Bb4+ 6. Nd2 Qxe4+ 7. Be2
+Qxg2 8. Bf3 Qh3 9. Nxc7+ Kd8 10. Nxa8 Nf6 11. a3 *
+
+[ECO "C45"]
+[Opening "Scotch game"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Qh4 5. Nb5 Bb4+ 6. Bd2 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Rosenthal variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Qh4 5. Nb5 Bb4+ 6. Bd2 Qxe4+ 7. Be2
+Kd8 8. O-O Bxd2 9. Nxd2 Qg6 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Fraser attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Qh4 5. Nf3 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Steinitz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Qh4 5. Nc3 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Schmidt variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Nf6 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Mieses variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Nf6 5. Nxc6 bxc6 6. e5 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Tartakower variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Nf6 5. Nxc6 bxc6 6. Nd2 *
+
+[ECO "C45"]
+[Opening "Scotch game"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Bc5 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Blackburne attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Bc5 5. Be3 Qf6 6. c3 Nge7 7. Qd2 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Gottschall variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Bc5 5. Be3 Qf6 6. c3 Nge7 7. Qd2 d5
+8. Nb5 Bxe3 9. Qxe3 O-O 10. Nxc7 Rb8 11. Nxd5 Nxd5 12. exd5 Nb4 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Paulsen attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Bc5 5. Be3 Qf6 6. c3 Nge7 7. Bb5 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Paulsen, Gunsberg defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Bc5 5. Be3 Qf6 6. c3 Nge7 7. Bb5 Nd8
+*
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Meitner variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Bc5 5. Be3 Qf6 6. c3 Nge7 7. Nc2 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Blumenfeld attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Bc5 5. Be3 Qf6 6. Nb5 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Potter variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Bc5 5. Nb3 *
+
+[ECO "C45"]
+[Opening "Scotch"]
+[Variation "Romanishin variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Bc5 5. Nb3 Bb4+ *
+
+[ECO "C46"]
+[Opening "Three knights game"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 *
+
+[ECO "C46"]
+[Opening "Three knights"]
+[Variation "Schlechter variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Bb4 4. Nd5 Nf6 *
+
+[ECO "C46"]
+[Opening "Three knights"]
+[Variation "Winawer defence (Gothic defence)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 f5 *
+
+[ECO "C46"]
+[Opening "Three knights"]
+[Variation "Steinitz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 g6 *
+
+[ECO "C46"]
+[Opening "Three knights"]
+[Variation "Steinitz, Rosenthal variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 g6 4. d4 exd4 5. Nd5 *
+
+[ECO "C46"]
+[Opening "Four knights game"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 *
+
+[ECO "C46"]
+[Opening "Four knights"]
+[Variation "Schultze-Mueller gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Nxe5 *
+
+[ECO "C46"]
+[Opening "Four knights"]
+[Variation "Italian variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bc4 *
+
+[ECO "C46"]
+[Opening "Four knights"]
+[Variation "Gunsberg variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. a3 *
+
+[ECO "C47"]
+[Opening "Four knights"]
+[Variation "Scotch variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. d4 *
+
+[ECO "C47"]
+[Opening "Four knights"]
+[Variation "Scotch, Krause variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. d4 Bb4 5. Nxe5 *
+
+[ECO "C47"]
+[Opening "Four knights"]
+[Variation "Scotch, 4...exd4"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. d4 exd4 *
+
+[ECO "C47"]
+[Opening "Four knights"]
+[Variation "Belgrade gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. d4 exd4 5. Nd5 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Spanish variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Ranken variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 a6 5. Bxc6 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Spielmann variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 a6 5. Bxc6 dxc6 6. Nxe5 Nxe4 7. Nxe4
+Qd4 8. O-O Qxe5 9. Re1 Be6 10. d4 Qd5 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Spanish, classical defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bc5 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Bardeleben variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bc5 5. O-O O-O 6. Nxe5 Nxe5 7. d4 Bd6
+8. f4 Nc6 9. e5 Bb4 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Marshall variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bc5 5. O-O O-O 6. Nxe5 Nd4 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Rubinstein counter-gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Nd4 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Rubinstein counter-gambit, Bogolyubov variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Nd4 5. Nxe5 Qe7 6. f4 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Rubinstein counter-gambit, 5.Be2"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Nd4 5. Be2 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Rubinstein counter-gambit Maroczy variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Nd4 5. Be2 Nxf3+ 6. Bxf3 Bc5 7. O-O 
+O-O 8. d3 d6 9. Na4 Bb6 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Rubinstein counter-gambit, exchange variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Nd4 5. Nxd4 *
+
+[ECO "C48"]
+[Opening "Four knights"]
+[Variation "Rubinstein counter-gambit, Henneberger variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Nd4 5. O-O *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "double Ruy Lopez"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "Gunsberg counter-attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. Nd5 Nxd5 7. exd5 e4
+*
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "double Ruy Lopez"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "Alatortsev variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 Qe7 7. Ne2 d5 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 Bxc3 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "Janowski variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 Bxc3 7. bxc3 d6
+8. Re1 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "Svenonius variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 Bxc3 7. bxc3 d5
+*
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "symmetrical variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 d6 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "symmetrical, Metger unpin"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 d6 7. Bg5 Bxc3 
+8. bxc3 Qe7 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "symmetrical, Capablanca variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 d6 7. Bg5 Bxc3 
+8. bxc3 Qe7 9. Re1 Nd8 10. d4 Bg4 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "symmetrical, Pillsbury variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 d6 7. Bg5 Ne7 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "symmetrical, Blake variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 d6 7. Bg5 Ne7 8.
+Nh4 c6 9. Bc4 d5 10. Bb3 Qd6 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "symmetrical, Tarrasch variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 d6 7. Bg5 Be6 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "symmetrical, Maroczy system"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. d3 d6 7. Ne2 *
+
+[ECO "C49"]
+[Opening "Four knights"]
+[Variation "Nimzovich (Paulsen) variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Bb4 5. O-O O-O 6. Bxc6 *
+
+[ECO "C50"]
+[Opening "King's pawn game"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 *
+
+[ECO "C50"]
+[Opening "Blackburne shilling gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nd4 4. Nxe5 Qg5 5. Nxf7 Qxg2 6. Rf1 Qxe4+ 7. Be2
+Nf3# *
+
+[ECO "C50"]
+[Opening "Rousseau gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 f5 *
+
+[ECO "C50"]
+[Opening "Hungarian defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Be7 *
+
+[ECO "C50"]
+[Opening "Hungarian defence"]
+[Variation "Tartakower variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Be7 4. d4 exd4 5. c3 Nf6 6. e5 Ne4 *
+
+[ECO "C50"]
+[Opening "Giuoco Piano"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 *
+
+[ECO "C50"]
+[Opening "Giuoco Piano"]
+[Variation "four knights variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. Nc3 Nf6 *
+
+[ECO "C50"]
+[Opening "Giuoco Piano"]
+[Variation "Jerome gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. Bxf7+ *
+
+[ECO "C50"]
+[Opening "Giuoco Pianissimo"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. d3 *
+
+[ECO "C50"]
+[Opening "Giuoco Pianissimo"]
+[Variation "Dubois variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. d3 f5 5. Ng5 f4 *
+
+[ECO "C50"]
+[Opening "Giuoco Pianissimo"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. d3 Nf6 *
+
+[ECO "C50"]
+[Opening "Giuoco Pianissimo"]
+[Variation "Italian four knights variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. d3 Nf6 5. Nc3 *
+
+[ECO "C50"]
+[Opening "Giuoco Pianissimo"]
+[Variation "Canal variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. d3 Nf6 5. Nc3 d6 6. Bg5 *
+
+[ECO "C51"]
+[Opening "Evans gambit declined"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 *
+
+[ECO "C51"]
+[Opening "Evans gambit declined, Lange variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bb6 5. b5 Na5 6. Nxe5 Nh6 *
+
+[ECO "C51"]
+[Opening "Evans gambit declined, Pavlov variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bb6 5. b5 Na5 6. Nxe5 Nh6 7. d4 d6 8.
+Bxh6 dxe5 9. Bxg7 Rg8 10. Bxf7+ Kxf7 11. Bxe5 Qg5 12. Nd2 *
+
+[ECO "C51"]
+[Opening "Evans gambit declined, Hirschbach variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bb6 5. b5 Na5 6. Nxe5 Qg5 *
+
+[ECO "C51"]
+[Opening "Evans gambit declined, Vasquez variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bb6 5. b5 Na5 6. Nxe5 Qg5 7. Bxf7+ Ke7
+8. Qh5 *
+
+[ECO "C51"]
+[Opening "Evans gambit declined, Hicken variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bb6 5. b5 Na5 6. Nxe5 Qg5 7. Qf3 Qxe5
+8. Qxf7+ Kd8 9. Bb2 *
+
+[ECO "C51"]
+[Opening "Evans gambit declined, 5.a4"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bb6 5. a4 *
+
+[ECO "C51"]
+[Opening "Evans gambit declined, Showalter variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bb6 5. a4 a6 6. Nc3 *
+
+[ECO "C51"]
+[Opening "Evans gambit declined, Cordel variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bb6 5. Bb2 *
+
+[ECO "C51"]
+[Opening "Evans counter-gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 d5 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "normal variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bc5 6. d4 exd4 7. O-O d6 8.
+cxd4 Bb6 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "Ulvestad variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bc5 6. d4 exd4 7. O-O d6 8.
+cxd4 Bb6 9. d5 Na5 10. Bb2 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "Paulsen variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bc5 6. d4 exd4 7. O-O d6 8.
+cxd4 Bb6 9. d5 Na5 10. Bb2 Ne7 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "Morphy attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bc5 6. d4 exd4 7. O-O d6 8.
+cxd4 Bb6 9. Nc3 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "Goering attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bc5 6. d4 exd4 7. O-O d6 8.
+cxd4 Bb6 9. Nc3 Na5 10. Bg5 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "Steinitz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bc5 6. d4 exd4 7. O-O d6 8.
+cxd4 Bb6 9. Nc3 Na5 10. Bg5 f6 11. Be3 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bc5 6. d4 exd4 7. O-O d6 8.
+cxd4 Bb6 9. Nc3 Bg4 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "Fraser attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bc5 6. d4 exd4 7. O-O d6 8.
+cxd4 Bb6 9. Nc3 Bg4 10. Qa4 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "Fraser-Mortimer attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bc5 6. d4 exd4 7. O-O d6 8.
+cxd4 Bb6 9. Nc3 Bg4 10. Qa4 Bd7 11. Qb3 Na5 12. Bxf7+ Kf8 13. Qc2 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "Stone-Ware variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bd6 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "Mayet defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Bf8 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "5...Be7"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Be7 *
+
+[ECO "C51"]
+[Opening "Evans gambit"]
+[Variation "Cordel variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Be7 6. d4 Na5 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "compromised defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. d4 exd4 7. O-O dxc3
+*
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "compromised defence, Paulsen variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. d4 exd4 7. O-O dxc3
+8. Qb3 Qf6 9. e5 Qg6 10. Nxc3 Nge7 11. Ba3 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "compromised defence, Potter variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. d4 exd4 7. O-O dxc3
+8. Qb3 Qf6 9. e5 Qg6 10. Nxc3 Nge7 11. Rd1 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "Leonhardt variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. d4 b5 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. d4 d6 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "Tartakower attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. d4 d6 7. Qb3 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "Levenfish variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. d4 d6 7. Qb3 Qd7 8.
+dxe5 dxe5 9. O-O Bb6 10. Ba3 Na5 11. Nxe5 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "Sokolsky variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. d4 d6 7. Bg5 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. O-O *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "Richardson attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. O-O Nf6 7. d4 O-O 8.
+Nxe5 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. O-O d6 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "Waller attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. O-O d6 7. d4 exd4 8.
+Qb3 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "Lasker defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. O-O d6 7. d4 Bb6 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "Sanders-Alapin variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. O-O d6 7. d4 Bd7 *
+
+[ECO "C52"]
+[Opening "Evans gambit"]
+[Variation "Alapin-Steinitz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. O-O d6 7. d4 Bg4 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+[Variation "LaBourdonnais variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 d6 5. d4 exd4 6. cxd4 Bb6 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+[Variation "close variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Qe7 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+[Variation "centre-holding variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Qe7 5. d4 Bb6 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+[Variation "Tarrasch variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Qe7 5. d4 Bb6 6. O-O Nf6 7. a4 a6 8. 
+Re1 d6 9. h3 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+[Variation "Mestel variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Qe7 5. d4 Bb6 6. Bg5 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+[Variation "Eisinger variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Qe7 5. d4 Bb6 6. d5 Nb8 7. d6 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+[Variation "Bird's attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. b4 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+[Variation "Ghulam Kassim variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. e5 Ne4 7. Bd5 Nxf2 
+8. Kxf2 dxc3+ 9. Kg3 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. e5 d5 *
+
+[ECO "C53"]
+[Opening "Giuoco Piano"]
+[Variation "Anderssen variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. e5 d5 7. Bb5 Ne4 8.
+cxd4 Bb4+ *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+[Variation "Krause variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Bd2 
+Nxe4 8. Bxb4 Nxb4 9. Bxf7+ Kxf7 10. Qb3+ d5 11. Ne5+ Kf6 12. f3 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+[Variation "Cracow variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Kf1 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+[Variation "Greco's attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+[Variation "Greco variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 
+Nxe4 8. O-O Nxc3 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+[Variation "Bernstein variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 
+Nxe4 8. O-O Nxc3 9. bxc3 Bxc3 10. Qb3 d5 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+[Variation "Aitken variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 
+Nxe4 8. O-O Nxc3 9. bxc3 Bxc3 10. Ba3 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 
+Nxe4 8. O-O Bxc3 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+[Variation "Steinitz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 
+Nxe4 8. O-O Bxc3 9. bxc3 d5 10. Ba3 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+[Variation "Moeller (Therkatz) attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 
+Nxe4 8. O-O Bxc3 9. d5 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+[Variation "Therkatz-Herzog variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 
+Nxe4 8. O-O Bxc3 9. d5 Bf6 10. Re1 Ne7 11. Rxe4 d6 12. Bg5 Bxg5 13. Nxg5 
+O-O 14. Nxh7 *
+
+[ECO "C54"]
+[Opening "Giuoco Piano"]
+[Variation "Moeller, bayonet attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 
+Nxe4 8. O-O Bxc3 9. d5 Bf6 10. Re1 Ne7 11. Rxe4 d6 12. g4 *
+
+[ECO "C55"]
+[Opening "Two knights defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 *
+
+[ECO "C55"]
+[Opening "Giuoco piano"]
+[Variation "Rosentreter variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. O-O Bc5 5. d4 Bxd4 6. Nxd4 Nxd4 7. Bg5 h6
+8. Bh4 g5 9. f4 *
+
+[ECO "C55"]
+[Opening "Giuoco piano"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. O-O Bc5 5. d4 Bxd4 6. Nxd4 Nxd4 7. Bg5 d6
+*
+
+[ECO "C55"]
+[Opening "Giuoco piano"]
+[Variation "Holzhausen attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. O-O Bc5 5. d4 Bxd4 6. Nxd4 Nxd4 7. Bg5 d6
+8. f4 Qe7 9. fxe5 dxe5 10. Nc3 *
+
+[ECO "C55"]
+[Opening "Two knights defence (Modern bishop's opening)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d3 *
+
+[ECO "C55"]
+[Opening "Two knights defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 *
+
+[ECO "C55"]
+[Opening "Two knights defence, Keidanz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. e5 d5 6. Bb5 Ne4 7. Nxd4 Bc5 
+8. Nxc6 Bxf2+ 9. Kf1 Qh4 *
+
+[ECO "C55"]
+[Opening "Two knights defence, Perreux variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. Ng5 *
+
+[ECO "C55"]
+[Opening "Two knights defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O *
+
+[ECO "C55"]
+[Opening "two knights"]
+[Variation "Max Lange attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Bc5 6. e5 *
+
+[ECO "C55"]
+[Opening "two knights"]
+[Variation "Max Lange attack, Berger variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Bc5 6. e5 d5 7. exf6 dxc4
+8. Re1+ Be6 9. Ng5 Qd5 10. Nc3 Qf5 11. g4 Qg6 12. Nce4 Bb6 13. f4 O-O-O *
+
+[ECO "C55"]
+[Opening "two knights"]
+[Variation "Max Lange attack, Marshall variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Bc5 6. e5 d5 7. exf6 dxc4
+8. Re1+ Be6 9. Ng5 Qd5 10. Nc3 Qf5 11. Nce4 *
+
+[ECO "C55"]
+[Opening "two knights"]
+[Variation "Max Lange attack, Rubinstein variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Bc5 6. e5 d5 7. exf6 dxc4
+8. Re1+ Be6 9. Ng5 Qd5 10. Nc3 Qf5 11. Nce4 Bf8 *
+
+[ECO "C55"]
+[Opening "two knights"]
+[Variation "Max Lange attack, Loman defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Bc5 6. e5 d5 7. exf6 dxc4
+8. Re1+ Be6 9. Ng5 g6 *
+
+[ECO "C55"]
+[Opening "two knights"]
+[Variation "Max Lange attack, Schlechter variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Bc5 6. e5 d5 7. exf6 dxc4
+8. Re1+ Be6 9. fxg7 *
+
+[ECO "C55"]
+[Opening "two knights"]
+[Variation "Max Lange attack, Steinitz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Bc5 6. e5 Ng4 *
+
+[ECO "C55"]
+[Opening "two knights"]
+[Variation "Max Lange attack, Krause variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Bc5 6. e5 Ng4 7. c3 *
+
+[ECO "C56"]
+[Opening "Two knights defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Nxe4 *
+
+[ECO "C56"]
+[Opening "two knights defence"]
+[Variation "Yurdansky attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Nxe4 6. Re1 d5 7. Bxd5 
+Qxd5 8. Nc3 Qa5 9. Nxe4 Be6 10. Bg5 h6 11. Bh4 g5 12. Nf6+ Ke7 13. b4 *
+
+[ECO "C56"]
+[Opening "two knights defence"]
+[Variation "Canal variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. d4 exd4 5. O-O Nxe4 6. Re1 d5 7. Nc3 *
+
+[ECO "C57"]
+[Opening "Two knights defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 *
+
+[ECO "C57"]
+[Opening "two knights defence"]
+[Variation "Wilkes Barre (Traxler) variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 Bc5 *
+
+[ECO "C57"]
+[Opening "two knights defence"]
+[Variation "Ulvestad variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 b5 *
+
+[ECO "C57"]
+[Opening "two knights defence"]
+[Variation "Fritz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Nd4 *
+
+[ECO "C57"]
+[Opening "two knights defence"]
+[Variation "Fritz, Gruber variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Nd4 6. c3 b5 7. Bf1 Nxd5 
+8. Ne4 *
+
+[ECO "C57"]
+[Opening "two knights defence"]
+[Variation "Lolli attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Nxd5 6. d4 *
+
+[ECO "C57"]
+[Opening "two knights defence"]
+[Variation "Pincus variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Nxd5 6. d4 Bb4+ *
+
+[ECO "C57"]
+[Opening "two knights defence"]
+[Variation "Fegatello attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Nxd5 6. Nxf7 *
+
+[ECO "C57"]
+[Opening "two knights defence"]
+[Variation "Fegatello attack, Leonhardt variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Nxd5 6. Nxf7 Kxf7 7. Qf3+
+Ke6 8. Nc3 Nb4 9. Qe4 c6 10. a3 Na6 11. d4 Nc7 *
+
+[ECO "C57"]
+[Opening "two knights defence"]
+[Variation "Fegatello attack, Polerio defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Nxd5 6. Nxf7 Kxf7 7. Qf3+
+Ke6 8. Nc3 Ne7 *
+
+[ECO "C58"]
+[Opening "two knights defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 *
+
+[ECO "C58"]
+[Opening "two knights defence"]
+[Variation "Kieseritsky variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. d3 *
+
+[ECO "C58"]
+[Opening "two knights defence"]
+[Variation "Yankovich variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. d3 h6 7. Nf3 e4 8.
+Qe2 Nxc4 9. dxc4 Bc5 10. Nfd2 *
+
+[ECO "C58"]
+[Opening "two knights defence"]
+[Variation "Maroczy variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. d3 h6 7. Nf3 e4 8.
+Qe2 Nxc4 9. dxc4 Be7 *
+
+[ECO "C58"]
+[Opening "Two knights defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. Bb5+ *
+
+[ECO "C58"]
+[Opening "two knights defence"]
+[Variation "Bogolyubov variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. Bb5+ c6 7. dxc6 
+bxc6 8. Qf3 *
+
+[ECO "C58"]
+[Opening "two knights defence"]
+[Variation "Paoli variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. Bb5+ c6 7. dxc6 
+bxc6 8. Qf3 Qc7 9. Bd3 *
+
+[ECO "C58"]
+[Opening "two knights defence"]
+[Variation "Colman variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. Bb5+ c6 7. dxc6 
+bxc6 8. Qf3 Rb8 *
+
+[ECO "C58"]
+[Opening "two knights defence"]
+[Variation "Blackburne variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. Bb5+ c6 7. dxc6 
+bxc6 8. Qf3 cxb5 *
+
+[ECO "C58"]
+[Opening "Two knights defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. Bb5+ c6 7. dxc6 
+bxc6 8. Be2 *
+
+[ECO "C59"]
+[Opening "Two knights defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. Bb5+ c6 7. dxc6 
+bxc6 8. Be2 h6 *
+
+[ECO "C59"]
+[Opening "two knights defence"]
+[Variation "Knorre variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. Bb5+ c6 7. dxc6 
+bxc6 8. Be2 h6 9. Nf3 e4 10. Ne5 Bd6 11. d4 Qc7 12. Bd2 *
+
+[ECO "C59"]
+[Opening "two knights defence"]
+[Variation "Goering variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. Bb5+ c6 7. dxc6 
+bxc6 8. Be2 h6 9. Nf3 e4 10. Ne5 Qc7 *
+
+[ECO "C59"]
+[Opening "two knights defence"]
+[Variation "Steinitz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bc4 Nf6 4. Ng5 d5 5. exd5 Na5 6. Bb5+ c6 7. dxc6 
+bxc6 8. Be2 h6 9. Nh3 *
+
+[ECO "C60"]
+[Opening "Ruy Lopez (Spanish opening)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 *
+
+[ECO "C60"]
+[Opening "Ruy Lopez"]
+[Variation "Nuernberg variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 f6 *
+
+[ECO "C60"]
+[Opening "Ruy Lopez"]
+[Variation "Pollock defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Na5 *
+
+[ECO "C60"]
+[Opening "Ruy Lopez"]
+[Variation "Lucena defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Be7 *
+
+[ECO "C60"]
+[Opening "Ruy Lopez"]
+[Variation "Vinogradov variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Qe7 *
+
+[ECO "C60"]
+[Opening "Ruy Lopez"]
+[Variation "Brentano defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 g5 *
+
+[ECO "C60"]
+[Opening "Ruy Lopez"]
+[Variation "fianchetto (Smyslov/Barnes) defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 g6 *
+
+[ECO "C60"]
+[Opening "Ruy Lopez"]
+[Variation "Cozio defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nge7 *
+
+[ECO "C60"]
+[Opening "Ruy Lopez"]
+[Variation "Cozio defence, Paulsen variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nge7 4. Nc3 g6 *
+
+[ECO "C61"]
+[Opening "Ruy Lopez"]
+[Variation "Bird's defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nd4 *
+
+[ECO "C61"]
+[Opening "Ruy Lopez"]
+[Variation "Bird's defence, Paulsen variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nd4 4. Nxd4 exd4 5. O-O Ne7 *
+
+[ECO "C62"]
+[Opening "Ruy Lopez"]
+[Variation "old Steinitz defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 d6 *
+
+[ECO "C62"]
+[Opening "Ruy Lopez"]
+[Variation "old Steinitz defence, Nimzovich attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 d6 4. d4 Bd7 5. Nc3 Nf6 6. Bxc6 *
+
+[ECO "C62"]
+[Opening "Ruy Lopez"]
+[Variation "old Steinitz defence, semi-Duras variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 d6 4. d4 Bd7 5. c4 *
+
+[ECO "C63"]
+[Opening "Ruy Lopez"]
+[Variation "Schliemann defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 f5 *
+
+[ECO "C63"]
+[Opening "Ruy Lopez"]
+[Variation "Schliemann defence, Berger variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 f5 4. Nc3 *
+
+[ECO "C64"]
+[Opening "Ruy Lopez"]
+[Variation "classical (Cordel) defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Bc5 *
+
+[ECO "C64"]
+[Opening "Ruy Lopez"]
+[Variation "classical defence, Zaitsev variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Bc5 4. O-O Nd4 5. b4 *
+
+[ECO "C64"]
+[Opening "Ruy Lopez"]
+[Variation "classical defence, 4.c3"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Bc5 4. c3 *
+
+[ECO "C64"]
+[Opening "Ruy Lopez"]
+[Variation "classical defence, Benelux variation  "]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Bc5 4. c3 Nf6 5. O-O O-O 6. d4 Bb6 *
+
+[ECO "C64"]
+[Opening "Ruy Lopez"]
+[Variation "classical defence, Charousek variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Bc5 4. c3 Bb6 *
+
+[ECO "C64"]
+[Opening "Ruy Lopez"]
+[Variation "classical defence, Boden variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Bc5 4. c3 Qe7 *
+
+[ECO "C64"]
+[Opening "Ruy Lopez"]
+[Variation "Cordel gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Bc5 4. c3 f5 *
+
+[ECO "C65"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 *
+
+[ECO "C65"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Nyholm attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. d4 exd4 5. O-O *
+
+[ECO "C65"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Mortimer variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. d3 Ne7 *
+
+[ECO "C65"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Mortimer trap"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. d3 Ne7 5. Nxe5 c6 *
+
+[ECO "C65"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Anderssen variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. d3 d6 5. Bxc6+ *
+
+[ECO "C65"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Duras variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. d3 d6 5. c4 *
+
+[ECO "C65"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Kaufmann variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. d3 Bc5 5. Be3 *
+
+[ECO "C65"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, 4.O-O"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O *
+
+[ECO "C65"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Beverwijk variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Bc5 *
+
+[ECO "C66"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, 4.O-O, d6"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O d6 *
+
+[ECO "C66"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, hedgehog variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O d6 5. d4 Bd7 6. Nc3 Be7 *
+
+[ECO "C66"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Tarrasch trap"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O d6 5. d4 Bd7 6. Nc3 Be7 7. Re1 O-O *
+
+[ECO "C66"]
+[Opening "Ruy Lopez"]
+[Variation "closed Berlin defence, Bernstein variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O d6 5. d4 Bd7 6. Nc3 Be7 7. Bg5 *
+
+[ECO "C66"]
+[Opening "Ruy Lopez"]
+[Variation "closed Berlin defence, Showalter variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O d6 5. d4 Bd7 6. Nc3 Be7 7. Bxc6 *
+
+[ECO "C66"]
+[Opening "Ruy Lopez"]
+[Variation "closed Berlin defence, Wolf variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O d6 5. d4 Bd7 6. Nc3 exd4 *
+
+[ECO "C66"]
+[Opening "Ruy Lopez"]
+[Variation "closed Berlin defence, Chigorin variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O d6 5. d4 Nd7 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, open variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "open Berlin defence, l'Hermet variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Nd6 6. dxe5 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "open Berlin defence, Showalter variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Nd6 6. Ba4 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "open Berlin defence, 5...Be7"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Be7 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Rio de Janeiro variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Be7 6. Qe2 Nd6 7. Bxc6 
+bxc6 8. dxe5 Nb7 9. Nc3 O-O 10. Re1 Nc5 11. Nd4 Ne6 12. Be3 Nxd4 13. Bxd4 
+c5 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Zukertort variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Be7 6. Qe2 Nd6 7. Bxc6 
+bxc6 8. dxe5 Nb7 9. c4 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Pillsbury variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Be7 6. Qe2 Nd6 7. Bxc6 
+bxc6 8. dxe5 Nb7 9. b3 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Winawer attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Be7 6. Qe2 Nd6 7. Bxc6 
+bxc6 8. dxe5 Nb7 9. Nd4 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Cordel variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Be7 6. Qe2 Nd6 7. Bxc6 
+bxc6 8. dxe5 Nf5 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Trifunovic variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Be7 6. Qe2 d5 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Minckwitz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 Be7 6. dxe5 *
+
+[ECO "C67"]
+[Opening "Ruy Lopez"]
+[Variation "Berlin defence, Rosenthal variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. O-O Nxe4 5. d4 a6 *
+
+[ECO "C68"]
+[Opening "Ruy Lopez"]
+[Variation "exchange variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Bxc6 *
+
+[ECO "C68"]
+[Opening "Ruy Lopez"]
+[Variation "exchange, Alekhine variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Bxc6 dxc6 5. d4 exd4 6. Qxd4 Qxd4 7. Nxd4
+Bd7 *
+
+[ECO "C68"]
+[Opening "Ruy Lopez"]
+[Variation "exchange, Keres variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Bxc6 dxc6 5. Nc3 *
+
+[ECO "C68"]
+[Opening "Ruy Lopez"]
+[Variation "exchange, Romanovsky variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Bxc6 dxc6 5. Nc3 f6 6. d3 *
+
+[ECO "C69"]
+[Opening "Ruy Lopez"]
+[Variation "exchange variation, 5.O-O"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Bxc6 dxc6 5. O-O *
+
+[ECO "C69"]
+[Opening "Ruy Lopez"]
+[Variation "exchange variation, Alapin gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Bxc6 dxc6 5. O-O Bg4 6. h3 h5 *
+
+[ECO "C69"]
+[Opening "Ruy Lopez"]
+[Variation "exchange, Gligoric variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Bxc6 dxc6 5. O-O f6 *
+
+[ECO "C69"]
+[Opening "Ruy Lopez"]
+[Variation "exchange, Bronstein variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Bxc6 dxc6 5. O-O Qd6 *
+
+[ECO "C70"]
+[Opening "Ruy Lopez"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 *
+
+[ECO "C70"]
+[Opening "Ruy Lopez"]
+[Variation "fianchetto defence deferred"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 g6 *
+
+[ECO "C70"]
+[Opening "Ruy Lopez"]
+[Variation "Cozio defence deferred"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nge7 *
+
+[ECO "C70"]
+[Opening "Ruy Lopez"]
+[Variation "Bird's defence deferred"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nd4 *
+
+[ECO "C70"]
+[Opening "Ruy Lopez"]
+[Variation "Alapin's defence deferred"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bb4 *
+
+[ECO "C70"]
+[Opening "Ruy Lopez"]
+[Variation "Classical defence deferred"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Bc5 *
+
+[ECO "C70"]
+[Opening "Ruy Lopez"]
+[Variation "Caro variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 b5 *
+
+[ECO "C70"]
+[Opening "Ruy Lopez"]
+[Variation "Graz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 b5 5. Bb3 Bc5 *
+
+[ECO "C70"]
+[Opening "Ruy Lopez"]
+[Variation "Taimanov (chase/wing/accelerated counterthrust) variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 b5 5. Bb3 Na5 *
+
+[ECO "C70"]
+[Opening "Ruy Lopez"]
+[Variation "Schliemann defence deferred"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 f5 *
+
+[ECO "C71"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 *
+
+[ECO "C71"]
+[Opening "Ruy Lopez"]
+[Variation "Noah's ark trap"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. d4 b5 6. Bb3 Nxd4 7. Nxd4 exd4 
+8. Qxd4 c5 *
+
+[ECO "C71"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence, Three knights variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. Nc3 *
+
+[ECO "C71"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence, Duras (Keres) variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. c4 *
+
+[ECO "C72"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence, 5.O-O"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. O-O *
+
+[ECO "C73"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence, Richter variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. Bxc6+ bxc6 6. d4 *
+
+[ECO "C73"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence, Alapin variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. Bxc6+ bxc6 6. d4 f6 *
+
+[ECO "C74"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. c3 *
+
+[ECO "C74"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence, siesta variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. c3 f5 *
+
+[ECO "C74"]
+[Opening "Ruy Lopez"]
+[Variation "Siesta, Kopayev variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. c3 f5 6. exf5 Bxf5 7. O-O *
+
+[ECO "C75"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. c3 Bd7 *
+
+[ECO "C75"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence, Rubinstein variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. c3 Bd7 6. d4 Nge7 *
+
+[ECO "C76"]
+[Opening "Ruy Lopez"]
+[Variation "modern Steinitz defence, fianchetto (Bronstein) variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 d6 5. c3 Bd7 6. d4 g6 *
+
+[ECO "C77"]
+[Opening "Ruy Lopez"]
+[Variation "Morphy defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 *
+
+[ECO "C77"]
+[Opening "Ruy Lopez"]
+[Variation "four knights (Tarrasch) variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. Nc3 *
+
+[ECO "C77"]
+[Opening "Ruy Lopez"]
+[Variation "Treybal (Bayreuth) variation (exchange var. deferred)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. Bxc6 *
+
+[ECO "C77"]
+[Opening "Ruy Lopez"]
+[Variation "Wormald (Alapin) attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. Qe2 *
+
+[ECO "C77"]
+[Opening "Ruy Lopez"]
+[Variation "Wormald attack, Gruenfeld variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. Qe2 b5 6. Bb3 Be7 7. d4 d6 8. 
+c3 Bg4 *
+
+[ECO "C77"]
+[Opening "Ruy Lopez"]
+[Variation "Anderssen variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. d3 *
+
+[ECO "C77"]
+[Opening "Ruy Lopez"]
+[Variation "Morphy defence, Duras variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. d3 d6 6. c4 *
+
+[ECO "C78"]
+[Opening "Ruy Lopez"]
+[Variation "5.O-O"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O *
+
+[ECO "C78"]
+[Opening "Ruy Lopez"]
+[Variation "Wing attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O b5 6. Bb3 Be7 7. a4 *
+
+[ECO "C78"]
+[Opening "Ruy Lopez"]
+[Variation "...b5 & ...d6"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O b5 6. Bb3 d6 *
+
+[ECO "C78"]
+[Opening "Ruy Lopez"]
+[Variation "Rabinovich variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O b5 6. Bb3 d6 7. Ng5 d5 8. 
+exd5 Nd4 9. Re1 Bc5 10. Rxe5+ Kf8 *
+
+[ECO "C78"]
+[Opening "Ruy Lopez"]
+[Variation "Archangelsk (counterthrust) variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O b5 6. Bb3 Bb7 *
+
+[ECO "C78"]
+[Opening "Ruy Lopez"]
+[Variation "Moeller defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Bc5 *
+
+[ECO "C79"]
+[Opening "Ruy Lopez"]
+[Variation "Steinitz defence deferred (Russian defence)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O d6 *
+
+[ECO "C79"]
+[Opening "Ruy Lopez"]
+[Variation "Steinitz defence deferred, Lipnitsky variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O d6 6. Bxc6+ bxc6 7. d4 Bg4
+*
+
+[ECO "C79"]
+[Opening "Ruy Lopez"]
+[Variation "Steinitz defence deferred, Rubinstein variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O d6 6. Bxc6+ bxc6 7. d4 Nxe4
+*
+
+[ECO "C79"]
+[Opening "Ruy Lopez"]
+[Variation "Steinitz defence deferred, Boleslavsky variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O d6 6. Bxc6+ bxc6 7. d4 Nxe4
+8. Re1 f5 9. dxe5 d5 10. Nc3 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open (Tarrasch) defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Tartakower variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. Qe2 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Knorre variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. Nc3 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, 6.d4"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Riga variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 exd4 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, 6.d4 b5"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Friess attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Nxe5 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Richter variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. d5 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, 7.Bb3"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Schlechter defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+a4 Nxd4 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Berger variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+a4 Nxd4 9. Nxd4 exd4 10. Nc3 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Harksen gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+c4 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, 8.de"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Zukertort variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Ne7 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, 8...Be6"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Bernstein variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. Nbd2 *
+
+[ECO "C80"]
+[Opening "Ruy Lopez"]
+[Variation "open, Bernstein variation, Karpov gambit"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. Nbd2 Nc5 10. c3 d4 11. Ng5 *
+
+[ECO "C81"]
+[Opening "Ruy Lopez"]
+[Variation "open, Howell attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. Qe2 *
+
+[ECO "C81"]
+[Opening "Ruy Lopez"]
+[Variation "open, Howell attack, Ekstroem variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. Qe2 Be7 10. Rd1 O-O 11. c4 bxc4 12. Bxc4 Qd7 *
+
+[ECO "C81"]
+[Opening "Ruy Lopez"]
+[Variation "open, Howell attack, Adam variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. Qe2 Be7 10. c4 *
+
+[ECO "C82"]
+[Opening "Ruy Lopez"]
+[Variation "open, 9.c3"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 *
+
+[ECO "C82"]
+[Opening "Ruy Lopez"]
+[Variation "open, Berlin variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Nc5 *
+
+[ECO "C82"]
+[Opening "Ruy Lopez"]
+[Variation "open, Italian variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Bc5 *
+
+[ECO "C82"]
+[Opening "Ruy Lopez"]
+[Variation "open, St. Petersburg variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Bc5 10. Nbd2 *
+
+[ECO "C82"]
+[Opening "Ruy Lopez"]
+[Variation "open, Dilworth variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Bc5 10. Nbd2 O-O 11. Bc2 Nxf2 *
+
+[ECO "C82"]
+[Opening "Ruy Lopez"]
+[Variation "open, Motzko attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Bc5 10. Qd3 *
+
+[ECO "C82"]
+[Opening "Ruy Lopez"]
+[Variation "open, Motzko attack, Nenarokov variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Bc5 10. Qd3 Ne7 *
+
+[ECO "C83"]
+[Opening "Ruy Lopez"]
+[Variation "open, classical defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Be7 *
+
+[ECO "C83"]
+[Opening "Ruy Lopez"]
+[Variation "open, Malkin variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Be7 10. Nbd2 O-O 11. Qe2 *
+
+[ECO "C83"]
+[Opening "Ruy Lopez"]
+[Variation "open, 9...Be7, 10.Re1"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Be7 10. Re1 *
+
+[ECO "C83"]
+[Opening "Ruy Lopez"]
+[Variation "open, Tarrasch trap"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Be7 10. Re1 O-O 11. Nd4 Qd7 12. Nxe6 fxe6 13. Rxe4 *
+
+[ECO "C83"]
+[Opening "Ruy Lopez"]
+[Variation "open, Breslau variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Nxe4 6. d4 b5 7. Bb3 d5 8.
+dxe5 Be6 9. c3 Be7 10. Re1 O-O 11. Nd4 Nxe5 *
+
+[ECO "C84"]
+[Opening "Ruy Lopez"]
+[Variation "closed defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 *
+
+[ECO "C84"]
+[Opening "Ruy Lopez"]
+[Variation "closed, centre attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. d4 *
+
+[ECO "C84"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Basque gambit (North Spanish variation)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. d4 exd4 7. e5 Ne4 8.
+c3 *
+
+[ECO "C85"]
+[Opening "Ruy Lopez"]
+[Variation "Exchange variation doubly deferred (DERLD)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Bxc6 *
+
+[ECO "C86"]
+[Opening "Ruy Lopez"]
+[Variation "Worrall attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Qe2 *
+
+[ECO "C86"]
+[Opening "Ruy Lopez"]
+[Variation "Worrall attack, sharp line"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Qe2 b5 7. Bb3 O-O *
+
+[ECO "C86"]
+[Opening "Ruy Lopez"]
+[Variation "Worrall attack, solid line"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Qe2 b5 7. Bb3 d6 *
+
+[ECO "C87"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Averbach variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 d6 *
+
+[ECO "C88"]
+[Opening "Ruy Lopez"]
+[Variation "closed"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 *
+
+[ECO "C88"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Leonhardt variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8.
+c3 Na5 9. Bc2 c5 10. d4 Qc7 11. h3 Nc6 12. d5 Nb8 13. Nbd2 g5 *
+
+[ECO "C88"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Balla variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8.
+c3 Na5 9. Bc2 c5 10. d4 Qc7 11. a4 *
+
+[ECO "C88"]
+[Opening "Ruy Lopez"]
+[Variation "closed, 7...d6, 8.d4"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8.
+d4 *
+
+[ECO "C88"]
+[Opening "Ruy Lopez"]
+[Variation "Noah's ark trap"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8.
+d4 Nxd4 9. Nxd4 exd4 10. Qxd4 c5 *
+
+[ECO "C88"]
+[Opening "Ruy Lopez"]
+[Variation "Trajkovic counter-attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 Bb7 *
+
+[ECO "C88"]
+[Opening "Ruy Lopez"]
+[Variation "closed, 7...O-O"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O *
+
+[ECO "C88"]
+[Opening "Ruy Lopez"]
+[Variation "closed, anti-Marshall 8.a4"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+a4 *
+
+[ECO "C88"]
+[Opening "Ruy Lopez"]
+[Variation "closed, 8.c3"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 *
+
+[ECO "C89"]
+[Opening "Ruy Lopez"]
+[Variation "Marshall counter-attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d5 *
+
+[ECO "C89"]
+[Opening "Ruy Lopez"]
+[Variation "Marshall counter-attack, 11...c6"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d5 9. exd5 Nxd5 10. Nxe5 Nxe5 11. Rxe5 c6 *
+
+[ECO "C89"]
+[Opening "Ruy Lopez"]
+[Variation "Marshall, Kevitz variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d5 9. exd5 Nxd5 10. Nxe5 Nxe5 11. Rxe5 c6 12. Bxd5 cxd5 13. d4 Bd6 14. 
+Re3 *
+
+[ECO "C89"]
+[Opening "Ruy Lopez"]
+[Variation "Marshall, main line, 12.d2d4"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d5 9. exd5 Nxd5 10. Nxe5 Nxe5 11. Rxe5 c6 12. d4 *
+
+[ECO "C89"]
+[Opening "Ruy Lopez"]
+[Variation "Marshall, main line, 14...Qh3"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d5 9. exd5 Nxd5 10. Nxe5 Nxe5 11. Rxe5 c6 12. d4 Bd6 13. Re1 Qh4 14. g3
+Qh3 *
+
+[ECO "C89"]
+[Opening "Ruy Lopez"]
+[Variation "Marshall, main line, Spassky variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d5 9. exd5 Nxd5 10. Nxe5 Nxe5 11. Rxe5 c6 12. d4 Bd6 13. Re1 Qh4 14. g3
+Qh3 15. Be3 Bg4 16. Qd3 Rae8 17. Nd2 Re6 18. a4 Qh5 *
+
+[ECO "C89"]
+[Opening "Ruy Lopez"]
+[Variation "Marshall, Herman Steiner variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d5 9. exd5 e4 *
+
+[ECO "C90"]
+[Opening "Ruy Lopez"]
+[Variation "closed (with ...d6)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 *
+
+[ECO "C90"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Pilnik variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. d3 *
+
+[ECO "C90"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Lutikov variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. Bc2 *
+
+[ECO "C90"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Suetin variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. a3 *
+
+[ECO "C91"]
+[Opening "Ruy Lopez"]
+[Variation "closed, 9.d4"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. d4 *
+
+[ECO "C91"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Bogolyubov variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. d4 Bg4 *
+
+[ECO "C92"]
+[Opening "Ruy Lopez"]
+[Variation "closed, 9.h3"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 *
+
+[ECO "C92"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Keres (9...a5) variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 a5 *
+
+[ECO "C92"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Kholmov variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Be6 *
+
+[ECO "C92"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Ragozin-Petrosian (`Keres') variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Nd7 *
+
+[ECO "C92"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Flohr-Zaitsev system (Lenzerheide variation)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Bb7 *
+
+[ECO "C93"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Smyslov defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 h6 *
+
+[ECO "C94"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Breyer defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Nb8 *
+
+[ECO "C95"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Breyer, 10.d4"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Nb8 10. d4 *
+
+[ECO "C95"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Breyer, Borisenko variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Nb8 10. d4 Nbd7 *
+
+[ECO "C95"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Breyer, Gligoric variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Nb8 10. d4 Nbd7 11. Nbd2 Bb7 12. Bc2 c5 *
+
+[ECO "C95"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Breyer, Simagin variation"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Nb8 10. d4 Nbd7 11. Nh4 *
+
+[ECO "C96"]
+[Opening "Ruy Lopez"]
+[Variation "closed (8...Na5)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Na5 10. Bc2 *
+
+[ECO "C96"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Rossolimo defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Na5 10. Bc2 c6 11. d4 Qc7 *
+
+[ECO "C96"]
+[Opening "Ruy Lopez"]
+[Variation "closed (10...c5)"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Na5 10. Bc2 c5 *
+
+[ECO "C96"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Borisenko defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Na5 10. Bc2 c5 11. d4 Nc6 *
+
+[ECO "C96"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Keres (...Nd7) defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Na5 10. Bc2 c5 11. d4 Nd7 *
+
+[ECO "C97"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Chigorin defence"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Na5 10. Bc2 c5 11. d4 Qc7 *
+
+[ECO "C97"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Chigorin, Yugoslav system"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Na5 10. Bc2 c5 11. d4 Qc7 12. Nbd2 Bd7 13. Nf1 Rfe8 14. Ne3 g6
+*
+
+[ECO "C98"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Chigorin, 12...Nc6"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Na5 10. Bc2 c5 11. d4 Qc7 12. Nbd2 Nc6 *
+
+[ECO "C98"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Chigorin, Rauzer attack"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Na5 10. Bc2 c5 11. d4 Qc7 12. Nbd2 Nc6 13. dxc5 *
+
+[ECO "C99"]
+[Opening "Ruy Lopez"]
+[Variation "closed, Chigorin, 12...c5d4"]
+
+1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 O-O 8.
+c3 d6 9. h3 Na5 10. Bc2 c5 11. d4 Qc7 12. Nbd2 cxd4 13. cxd4 *
+
+[ECO "D00"]
+[Opening "Queen's pawn game"]
+
+1. d4 d5 *
+
+[ECO "D00"]
+[Opening "Queen's pawn, Mason variation"]
+
+1. d4 d5 2. Bf4 *
+
+[ECO "D00"]
+[Opening "Queen's pawn, Mason variation, Steinitz counter-gambit"]
+
+1. d4 d5 2. Bf4 c5 *
+
+[ECO "D00"]
+[Opening "Levitsky attack (Queen's bishop attack)"]
+
+1. d4 d5 2. Bg5 *
+
+[ECO "D00"]
+[Opening "Blackmar gambit"]
+
+1. d4 d5 2. e4 *
+
+[ECO "D00"]
+[Opening "Queen's pawn"]
+[Variation "stonewall attack"]
+
+1. d4 d5 2. e3 Nf6 3. Bd3 *
+
+[ECO "D00"]
+[Opening "Queen's pawn"]
+[Variation "Chigorin variation"]
+
+1. d4 d5 2. Nc3 *
+
+[ECO "D00"]
+[Opening "Queen's pawn"]
+[Variation "Anti-Veresov"]
+
+1. d4 d5 2. Nc3 Bg4 *
+
+[ECO "D00"]
+[Opening "Blackmar-Diemer gambit"]
+
+1. d4 d5 2. Nc3 Nf6 3. e4 *
+
+[ECO "D00"]
+[Opening "Blackmar-Diemer"]
+[Variation "Euwe defence"]
+
+1. d4 d5 2. Nc3 Nf6 3. e4 dxe4 4. f3 exf3 5. Nxf3 e6 *
+
+[ECO "D00"]
+[Opening "Blackmar-Diemer"]
+[Variation "Lemberg counter-gambit"]
+
+1. d4 d5 2. Nc3 Nf6 3. e4 e5 *
+
+[ECO "D01"]
+[Opening "Richter-Veresov attack"]
+
+1. d4 d5 2. Nc3 Nf6 3. Bg5 *
+
+[ECO "D01"]
+[Opening "Richter-Veresov attack, Veresov variation"]
+
+1. d4 d5 2. Nc3 Nf6 3. Bg5 Bf5 4. Bxf6 *
+
+[ECO "D01"]
+[Opening "Richter-Veresov attack, Richter variation"]
+
+1. d4 d5 2. Nc3 Nf6 3. Bg5 Bf5 4. f3 *
+
+[ECO "D02"]
+[Opening "Queen's pawn game"]
+
+1. d4 d5 2. Nf3 *
+
+[ECO "D02"]
+[Opening "Queen's pawn game, Chigorin variation"]
+
+1. d4 d5 2. Nf3 Nc6 *
+
+[ECO "D02"]
+[Opening "Queen's pawn game, Krause variation"]
+
+1. d4 d5 2. Nf3 c5 *
+
+[ECO "D02"]
+[Opening "Queen's pawn game"]
+
+1. d4 d5 2. Nf3 Nf6 *
+
+[ECO "D02"]
+[Opening "Queen's bishop game"]
+
+1. d4 d5 2. Nf3 Nf6 3. Bf4 *
+
+[ECO "D03"]
+[Opening "Torre attack (Tartakower variation)"]
+
+1. d4 d5 2. Nf3 Nf6 3. Bg5 *
+
+[ECO "D04"]
+[Opening "Queen's pawn game"]
+
+1. d4 d5 2. Nf3 Nf6 3. e3 *
+
+[ECO "D05"]
+[Opening "Queen's pawn game"]
+
+1. d4 d5 2. Nf3 Nf6 3. e3 e6 *
+
+[ECO "D05"]
+[Opening "Queen's pawn game, Zukertort variation"]
+
+1. d4 d5 2. Nf3 Nf6 3. e3 e6 4. Nbd2 c5 5. b3 *
+
+[ECO "D05"]
+[Opening "Queen's pawn game"]
+
+1. d4 d5 2. Nf3 Nf6 3. e3 e6 4. Bd3 *
+
+[ECO "D05"]
+[Opening "Queen's pawn game, Rubinstein (Colle-Zukertort) variation"]
+
+1. d4 d5 2. Nf3 Nf6 3. e3 e6 4. Bd3 c5 5. b3 *
+
+[ECO "D05"]
+[Opening "Colle system"]
+
+1. d4 d5 2. Nf3 Nf6 3. e3 e6 4. Bd3 c5 5. c3 *
+
+[ECO "D06"]
+[Opening "Queen's Gambit"]
+
+1. d4 d5 2. c4 *
+
+[ECO "D06"]
+[Opening "QGD"]
+[Variation "Grau (Sahovic) defence"]
+
+1. d4 d5 2. c4 Bf5 *
+
+[ECO "D06"]
+[Opening "QGD"]
+[Variation "Marshall defence"]
+
+1. d4 d5 2. c4 Nf6 *
+
+[ECO "D06"]
+[Opening "QGD"]
+[Variation "symmetrical (Austrian) defence"]
+
+1. d4 d5 2. c4 c5 *
+
+[ECO "D07"]
+[Opening "QGD"]
+[Variation "Chigorin defence"]
+
+1. d4 d5 2. c4 Nc6 *
+
+[ECO "D07"]
+[Opening "QGD"]
+[Variation "Chigorin defence, Janowski variation"]
+
+1. d4 d5 2. c4 Nc6 3. Nc3 dxc4 4. Nf3 *
+
+[ECO "D08"]
+[Opening "QGD"]
+[Variation "Albin counter-gambit"]
+
+1. d4 d5 2. c4 e5 *
+
+[ECO "D08"]
+[Opening "QGD"]
+[Variation "Albin counter-gambit, Lasker trap"]
+
+1. d4 d5 2. c4 e5 3. dxe5 d4 4. e3 Bb4+ 5. Bd2 dxe3 *
+
+[ECO "D08"]
+[Opening "QGD"]
+[Variation "Albin counter-gambit"]
+
+1. d4 d5 2. c4 e5 3. dxe5 d4 4. Nf3 *
+
+[ECO "D08"]
+[Opening "QGD"]
+[Variation "Albin counter-gambit, Alapin variation"]
+
+1. d4 d5 2. c4 e5 3. dxe5 d4 4. Nf3 Nc6 5. Nbd2 *
+
+[ECO "D08"]
+[Opening "QGD"]
+[Variation "Albin counter-gambit, Krenosz variation"]
+
+1. d4 d5 2. c4 e5 3. dxe5 d4 4. Nf3 Nc6 5. Nbd2 Bg4 6. h3 Bxf3 7. Nxf3 Bb4+
+8. Bd2 Qe7 *
+
+[ECO "D08"]
+[Opening "QGD"]
+[Variation "Albin counter-gambit, Janowski variation"]
+
+1. d4 d5 2. c4 e5 3. dxe5 d4 4. Nf3 Nc6 5. Nbd2 f6 *
+
+[ECO "D08"]
+[Opening "QGD"]
+[Variation "Albin counter-gambit, Balogh variation"]
+
+1. d4 d5 2. c4 e5 3. dxe5 d4 4. Nf3 Nc6 5. Nbd2 Qe7 *
+
+[ECO "D09"]
+[Opening "QGD"]
+[Variation "Albin counter-gambit, 5.g3"]
+
+1. d4 d5 2. c4 e5 3. dxe5 d4 4. Nf3 Nc6 5. g3 *
+
+[ECO "D10"]
+[Opening "QGD Slav defence"]
+
+1. d4 d5 2. c4 c6 *
+
+[ECO "D10"]
+[Opening "QGD Slav defence, Alekhine variation"]
+
+1. d4 d5 2. c4 c6 3. Nc3 dxc4 4. e4 *
+
+[ECO "D10"]
+[Opening "QGD Slav"]
+[Variation "Winawer counter-gambit"]
+
+1. d4 d5 2. c4 c6 3. Nc3 e5 *
+
+[ECO "D10"]
+[Opening "QGD Slav defence"]
+[Variation "exchange variation"]
+
+1. d4 d5 2. c4 c6 3. cxd5 *
+
+[ECO "D11"]
+[Opening "QGD Slav"]
+[Variation "3.Nf3"]
+
+1. d4 d5 2. c4 c6 3. Nf3 *
+
+[ECO "D11"]
+[Opening "QGD Slav"]
+[Variation "Breyer variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nbd2 *
+
+[ECO "D11"]
+[Opening "QGD Slav"]
+[Variation "4.e3"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. e3 *
+
+[ECO "D12"]
+[Opening "QGD Slav"]
+[Variation "4.e3 Bf5"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. e3 Bf5 *
+
+[ECO "D12"]
+[Opening "QGD Slav"]
+[Variation "Landau variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. e3 Bf5 5. cxd5 cxd5 6. Qb3 Qc8 7. Bd2 e6 8.
+Na3 *
+
+[ECO "D12"]
+[Opening "QGD Slav"]
+[Variation "exchange variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. e3 Bf5 5. cxd5 cxd5 6. Nc3 *
+
+[ECO "D12"]
+[Opening "QGD Slav"]
+[Variation "Amsterdam variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. e3 Bf5 5. cxd5 cxd5 6. Nc3 e6 7. Ne5 Nfd7 *
+
+[ECO "D13"]
+[Opening "QGD Slav"]
+[Variation "exchange variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. cxd5 cxd5 *
+
+[ECO "D14"]
+[Opening "QGD Slav"]
+[Variation "exchange variation, 6.Bf4 Bf5"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. cxd5 cxd5 5. Nc3 Nc6 6. Bf4 Bf5 *
+
+[ECO "D14"]
+[Opening "QGD Slav"]
+[Variation "exchange, Trifunovic variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. cxd5 cxd5 5. Nc3 Nc6 6. Bf4 Bf5 7. e3 e6 8.
+Qb3 Bb4 *
+
+[ECO "D15"]
+[Opening "QGD Slav"]
+[Variation "4.Nc3"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 *
+
+[ECO "D15"]
+[Opening "QGD Slav"]
+[Variation "Suechting variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 Qb6 *
+
+[ECO "D15"]
+[Opening "QGD Slav"]
+[Variation "Schlechter variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 g6 *
+
+[ECO "D15"]
+[Opening "QGD Slav accepted"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 *
+
+[ECO "D15"]
+[Opening "QGD Slav"]
+[Variation "5.e3 (Alekhine variation)"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. e3 *
+
+[ECO "D15"]
+[Opening "QGD Slav"]
+[Variation "Slav gambit"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. e4 *
+
+[ECO "D15"]
+[Opening "QGD Slav"]
+[Variation "Tolush-Geller gambit"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. e4 b5 6. e5 *
+
+[ECO "D16"]
+[Opening "QGD Slav accepted"]
+[Variation "Alapin variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 *
+
+[ECO "D16"]
+[Opening "QGD Slav"]
+[Variation "Smyslov variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Na6 6. e4 Bg4 *
+
+[ECO "D16"]
+[Opening "QGD Slav"]
+[Variation "Soultanbeieff variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 e6 *
+
+[ECO "D16"]
+[Opening "QGD Slav"]
+[Variation "Steiner variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Bg4 *
+
+[ECO "D17"]
+[Opening "QGD Slav"]
+[Variation "Czech defence"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Bf5 *
+
+[ECO "D17"]
+[Opening "QGD Slav"]
+[Variation "Krause attack"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Bf5 6. Ne5 *
+
+[ECO "D17"]
+[Opening "QGD Slav"]
+[Variation "Carlsbad variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Bf5 6. Ne5 Nbd7 7. Nxc4 Qc7
+8. g3 e5 *
+
+[ECO "D17"]
+[Opening "QGD Slav"]
+[Variation "Wiesbaden variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Bf5 6. Ne5 e6 *
+
+[ECO "D18"]
+[Opening "QGD Slav"]
+[Variation "Dutch variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Bf5 6. e3 *
+
+[ECO "D18"]
+[Opening "QGD Slav"]
+[Variation "Dutch, Lasker variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Bf5 6. e3 Na6 *
+
+[ECO "D19"]
+[Opening "QGD Slav"]
+[Variation "Dutch variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Bf5 6. e3 e6 7. Bxc4 Bb4 8.
+O-O *
+
+[ECO "D19"]
+[Opening "QGD Slav"]
+[Variation "Dutch variation, main line"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Bf5 6. e3 e6 7. Bxc4 Bb4 8.
+O-O O-O 9. Qe2 *
+
+[ECO "D19"]
+[Opening "QGD Slav"]
+[Variation "Dutch, Saemisch variation"]
+
+1. d4 d5 2. c4 c6 3. Nf3 Nf6 4. Nc3 dxc4 5. a4 Bf5 6. e3 e6 7. Bxc4 Bb4 8.
+O-O O-O 9. Qe2 Ne4 10. g4 *
+
+[ECO "D20"]
+[Opening "Queen's gambit accepted"]
+
+1. d4 d5 2. c4 dxc4 *
+
+[ECO "D20"]
+[Opening "QGA"]
+[Variation "3.e4"]
+
+1. d4 d5 2. c4 dxc4 3. e4 *
+
+[ECO "D20"]
+[Opening "QGA"]
+[Variation "Linares variation"]
+
+1. d4 d5 2. c4 dxc4 3. e4 c5 4. d5 Nf6 5. Nc3 b5 *
+
+[ECO "D20"]
+[Opening "QGA"]
+[Variation "Schwartz defence"]
+
+1. d4 d5 2. c4 dxc4 3. e4 f5 *
+
+[ECO "D21"]
+[Opening "QGA"]
+[Variation "3.Nf3"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 *
+
+[ECO "D21"]
+[Opening "QGA"]
+[Variation "Ericson variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 b5 *
+
+[ECO "D21"]
+[Opening "QGA"]
+[Variation "Alekhine defense, Borisenko-Furman variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 a6 4. e4 *
+
+[ECO "D22"]
+[Opening "QGA"]
+[Variation "Alekhine defence"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 a6 *
+
+[ECO "D22"]
+[Opening "QGA"]
+[Variation "Alekhine defence, Alatortsev variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 a6 4. e3 Bg4 5. Bxc4 e6 6. d5 *
+
+[ECO "D22"]
+[Opening "QGA"]
+[Variation "Haberditz variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 a6 4. e3 b5 *
+
+[ECO "D23"]
+[Opening "Queen's gambit accepted"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 *
+
+[ECO "D23"]
+[Opening "QGA"]
+[Variation "Mannheim variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. Qa4+ *
+
+[ECO "D24"]
+[Opening "QGA, 4.Nc3"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. Nc3 *
+
+[ECO "D24"]
+[Opening "QGA, Bogolyubov variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. Nc3 a6 5. e4 *
+
+[ECO "D25"]
+[Opening "QGA, 4.e3"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 *
+
+[ECO "D25"]
+[Opening "QGA, Smyslov variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 g6 *
+
+[ECO "D25"]
+[Opening "QGA, Janowsky-Larsen variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 Bg4 *
+
+[ECO "D25"]
+[Opening "QGA, Flohr variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 Be6 *
+
+[ECO "D26"]
+[Opening "QGA"]
+[Variation "4...e6"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 *
+
+[ECO "D26"]
+[Opening "QGA"]
+[Variation "classical variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 *
+
+[ECO "D26"]
+[Opening "QGA"]
+[Variation "classical, Furman variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. Qe2 a6 7. dxc5 Bxc5 
+8. O-O Nc6 9. e4 b5 10. e5 *
+
+[ECO "D26"]
+[Opening "QGA"]
+[Variation "classical variation, 6.O-O"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. O-O *
+
+[ECO "D26"]
+[Opening "QGA"]
+[Variation "classical, Steinitz variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. O-O cxd4 *
+
+[ECO "D27"]
+[Opening "QGA"]
+[Variation "classical, 6...a6"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. O-O a6 *
+
+[ECO "D27"]
+[Opening "QGA"]
+[Variation "classical, Rubinstein variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. O-O a6 7. a4 *
+
+[ECO "D27"]
+[Opening "QGA"]
+[Variation "classical, Geller variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. O-O a6 7. e4 *
+
+[ECO "D28"]
+[Opening "QGA"]
+[Variation "classical, 7.Qe2"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. O-O a6 7. Qe2 *
+
+[ECO "D28"]
+[Opening "QGA"]
+[Variation "classical, 7...b5"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. O-O a6 7. Qe2 b5 *
+
+[ECO "D28"]
+[Opening "QGA"]
+[Variation "classical, Flohr variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. O-O a6 7. Qe2 b5 8. 
+Bb3 Nc6 9. Rd1 c4 10. Bc2 Nb4 11. Nc3 Nxc2 12. Qxc2 Bb7 13. d5 Qc7 *
+
+[ECO "D29"]
+[Opening "QGA"]
+[Variation "classical, 8...Bb7"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. O-O a6 7. Qe2 b5 8. 
+Bb3 Bb7 *
+
+[ECO "D29"]
+[Opening "QGA"]
+[Variation "classical, Smyslov variation"]
+
+1. d4 d5 2. c4 dxc4 3. Nf3 Nf6 4. e3 e6 5. Bxc4 c5 6. O-O a6 7. Qe2 b5 8. 
+Bb3 Bb7 9. Rd1 Nbd7 10. Nc3 Bd6 *
+
+[ECO "D30"]
+[Opening "Queen's gambit declined"]
+
+1. d4 d5 2. c4 e6 *
+
+[ECO "D30"]
+[Opening "QGD Slav"]
+
+1. d4 d5 2. c4 e6 3. Nf3 Nf6 4. e3 c6 5. Nbd2 *
+
+[ECO "D30"]
+[Opening "QGD"]
+[Variation "Stonewall variation"]
+
+1. d4 d5 2. c4 e6 3. Nf3 Nf6 4. e3 c6 5. Nbd2 Ne4 6. Bd3 f5 *
+
+[ECO "D30"]
+[Opening "QGD Slav"]
+
+1. d4 d5 2. c4 e6 3. Nf3 Nf6 4. e3 c6 5. Nbd2 Nbd7 *
+
+[ECO "D30"]
+[Opening "QGD Slav"]
+[Variation "Semmering variation"]
+
+1. d4 d5 2. c4 e6 3. Nf3 Nf6 4. e3 c6 5. Nbd2 Nbd7 6. Bd3 c5 *
+
+[ECO "D30"]
+[Opening "QGD"]
+[Variation "Spielmann variation"]
+
+1. d4 d5 2. c4 e6 3. Nf3 Nf6 4. e3 c6 5. Nbd2 g6 *
+
+[ECO "D30"]
+[Opening "QGD"]
+
+1. d4 d5 2. c4 e6 3. Nf3 Nf6 4. Bg5 *
+
+[ECO "D30"]
+[Opening "QGD"]
+[Variation "Capablanca variation"]
+
+1. d4 d5 2. c4 e6 3. Nf3 Nf6 4. Bg5 Nbd7 5. e3 c6 6. Nbd2 *
+
+[ECO "D30"]
+[Opening "QGD"]
+[Variation "Vienna variation"]
+
+1. d4 d5 2. c4 e6 3. Nf3 Nf6 4. Bg5 Bb4+ *
+
+[ECO "D30"]
+[Opening "QGD"]
+[Variation "Capablanca-Duras variation"]
+
+1. d4 d5 2. c4 e6 3. Nf3 Nf6 4. Bg5 h6 *
+
+[ECO "D30"]
+[Opening "QGD"]
+[Variation "Hastings variation"]
+
+1. d4 d5 2. c4 e6 3. Nf3 Nf6 4. Bg5 h6 5. Bxf6 Qxf6 6. Nc3 c6 7. Qb3 *
+
+[ECO "D31"]
+[Opening "QGD"]
+[Variation "3.Nc3"]
+
+1. d4 d5 2. c4 e6 3. Nc3 *
+
+[ECO "D31"]
+[Opening "QGD"]
+[Variation "Janowski variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 a6 *
+
+[ECO "D31"]
+[Opening "QGD"]
+[Variation "Alapin variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 b6 *
+
+[ECO "D31"]
+[Opening "QGD"]
+[Variation "Charousek (Petrosian) variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Be7 *
+
+[ECO "D31"]
+[Opening "QGD"]
+[Variation "semi-Slav"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c6 *
+
+[ECO "D31"]
+[Opening "QGD"]
+[Variation "semi-Slav, Noteboom variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c6 4. Nf3 dxc4 *
+
+[ECO "D31"]
+[Opening "QGD"]
+[Variation "semi-Slav, Koomen variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c6 4. Nf3 dxc4 5. a4 Bb4 6. e3 b5 7. Bd2 Qe7 *
+
+[ECO "D31"]
+[Opening "QGD"]
+[Variation "semi-Slav, Junge variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c6 4. Nf3 dxc4 5. a4 Bb4 6. e3 b5 7. Bd2 Qb6 *
+
+[ECO "D31"]
+[Opening "QGD"]
+[Variation "semi-Slav, Abrahams variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c6 4. Nf3 dxc4 5. a4 Bb4 6. e3 b5 7. Bd2 a5 *
+
+[ECO "D31"]
+[Opening "QGD"]
+[Variation "semi-Slav, Marshall gambit"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c6 4. e4 *
+
+[ECO "D32"]
+[Opening "QGD"]
+[Variation "Tarrasch defence"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 *
+
+[ECO "D32"]
+[Opening "QGD"]
+[Variation "Tarrasch, von Hennig-Schara gambit"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 cxd4 *
+
+[ECO "D32"]
+[Opening "QGD"]
+[Variation "Tarrasch defence, 4.cd ed"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 *
+
+[ECO "D32"]
+[Opening "QGD"]
+[Variation "Tarrasch defence, Tarrasch gambit"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. dxc5 d4 6. Na4 b5 *
+
+[ECO "D32"]
+[Opening "QGD"]
+[Variation "Tarrasch defence, Marshall gambit"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. e4 *
+
+[ECO "D32"]
+[Opening "QGD"]
+[Variation "Tarrasch defence"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 *
+
+[ECO "D33"]
+[Opening "QGD"]
+[Variation "Tarrasch, Schlechter-Rubinstein system"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 *
+
+[ECO "D33"]
+[Opening "QGD"]
+[Variation "Tarrasch, Folkestone (Swedish) variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 c4 *
+
+[ECO "D33"]
+[Opening "QGD"]
+[Variation "Tarrasch, Schlechter-Rubinstein system, Rey Ardid variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 c4 7. e4 *
+
+[ECO "D33"]
+[Opening "QGD"]
+[Variation "Tarrasch, Prague variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 Nf6 *
+
+[ECO "D33"]
+[Opening "QGD"]
+[Variation "Tarrasch, Wagner variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 Nf6 7. Bg2 Bg4 *
+
+[ECO "D34"]
+[Opening "QGD"]
+[Variation "Tarrasch, Prague variation, 7...Be7"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 Nf6 7. Bg2 Be7 *
+
+[ECO "D34"]
+[Opening "QGD"]
+[Variation "Tarrasch, Prague variation, Normal position"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 Nf6 7. Bg2 Be7 8.
+O-O O-O *
+
+[ECO "D34"]
+[Opening "QGD"]
+[Variation "Tarrasch, Reti variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 Nf6 7. Bg2 Be7 8.
+O-O O-O 9. dxc5 Bxc5 10. Na4 *
+
+[ECO "D34"]
+[Opening "QGD"]
+[Variation "Tarrasch, Prague variation, 9.Bg5"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 Nf6 7. Bg2 Be7 8.
+O-O O-O 9. Bg5 *
+
+[ECO "D34"]
+[Opening "QGD"]
+[Variation "Tarrasch, Bogolyubov variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 Nf6 7. Bg2 Be7 8.
+O-O O-O 9. Bg5 Be6 10. Rc1 c4 *
+
+[ECO "D34"]
+[Opening "QGD"]
+[Variation "Tarrasch, Stoltz variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 c5 4. cxd5 exd5 5. Nf3 Nc6 6. g3 Nf6 7. Bg2 Be7 8.
+O-O O-O 9. Bg5 Be6 10. Rc1 b6 *
+
+[ECO "D35"]
+[Opening "QGD"]
+[Variation "3...Nf6"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 *
+
+[ECO "D35"]
+[Opening "QGD"]
+[Variation "Harrwitz attack"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bf4 *
+
+[ECO "D35"]
+[Opening "QGD"]
+[Variation "exchange variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. cxd5 *
+
+[ECO "D35"]
+[Opening "QGD"]
+[Variation "exchange, Saemisch variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. cxd5 exd5 5. Nf3 Nbd7 6. Bf4 *
+
+[ECO "D35"]
+[Opening "QGD"]
+[Variation "exchange, positional line"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. cxd5 exd5 5. Bg5 *
+
+[ECO "D35"]
+[Opening "QGD"]
+[Variation "exchange, chameleon variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. cxd5 exd5 5. Bg5 Be7 6. e3 O-O 7. Bd3 Nbd7
+8. Qc2 Re8 9. Nge2 Nf8 10. O-O-O *
+
+[ECO "D35"]
+[Opening "QGD"]
+[Variation "exchange, positional line, 5...c6"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. cxd5 exd5 5. Bg5 c6 *
+
+[ECO "D36"]
+[Opening "QGD"]
+[Variation "exchange, positional line, 6.Qc2"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. cxd5 exd5 5. Bg5 c6 6. Qc2 *
+
+[ECO "D37"]
+[Opening "QGD"]
+[Variation "4.Nf3"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 *
+
+[ECO "D37"]
+[Opening "QGD"]
+[Variation "classical variation (5.Bf4)"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 Be7 5. Bf4 *
+
+[ECO "D38"]
+[Opening "QGD"]
+[Variation "Ragozin variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 Bb4 *
+
+[ECO "D39"]
+[Opening "QGD"]
+[Variation "Ragozin, Vienna variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 Bb4 5. Bg5 dxc4 *
+
+[ECO "D40"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch defence"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c5 *
+
+[ECO "D40"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch, symmetrical variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c5 5. e3 Nc6 6. Bd3 Bd6 7. O-O O-O *
+
+[ECO "D40"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch, Levenfish variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c5 5. e3 Nc6 6. Bd3 Bd6 7. O-O O-O 8. 
+Qe2 Qe7 9. dxc5 Bxc5 10. e4 *
+
+[ECO "D40"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch defence, Pillsbury variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c5 5. Bg5 *
+
+[ECO "D41"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch, 5.cd"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c5 5. cxd5 *
+
+[ECO "D41"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch, Kmoch variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c5 5. cxd5 Nxd5 6. e4 Nxc3 7. bxc3 cxd4
+8. cxd4 Bb4+ 9. Bd2 Bxd2+ 10. Qxd2 O-O 11. Bb5 *
+
+[ECO "D41"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch, San Sebastian variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c5 5. cxd5 Nxd5 6. e4 Nxc3 7. bxc3 cxd4
+8. cxd4 Bb4+ 9. Bd2 Qa5 *
+
+[ECO "D41"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch with e3"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c5 5. cxd5 Nxd5 6. e3 *
+
+[ECO "D42"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch, 7.Bd3"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c5 5. cxd5 Nxd5 6. e3 Nc6 7. Bd3 *
+
+[ECO "D43"]
+[Opening "QGD semi-Slav"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 *
+
+[ECO "D43"]
+[Opening "QGD semi-Slav"]
+[Variation "Hastings variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. Bg5 h6 6. Bxf6 Qxf6 7. Qb3 *
+
+[ECO "D44"]
+[Opening "QGD semi-Slav"]
+[Variation "5.Bg5 dc"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. Bg5 dxc4 *
+
+[ECO "D44"]
+[Opening "QGD semi-Slav"]
+[Variation "Botvinnik system (anti-Meran)"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. Bg5 dxc4 6. e4 *
+
+[ECO "D44"]
+[Opening "QGD semi-Slav"]
+[Variation "Ekstrom variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. Bg5 dxc4 6. e4 b5 7. e5 h6 8. Bh4
+g5 9. exf6 gxh4 10. Ne5 *
+
+[ECO "D44"]
+[Opening "QGD semi-Slav"]
+[Variation "anti-Meran gambit"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. Bg5 dxc4 6. e4 b5 7. e5 h6 8. Bh4
+g5 9. Nxg5 *
+
+[ECO "D44"]
+[Opening "QGD semi-Slav"]
+[Variation "anti-Meran, Lilienthal variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. Bg5 dxc4 6. e4 b5 7. e5 h6 8. Bh4
+g5 9. Nxg5 hxg5 10. Bxg5 Nbd7 11. g3 *
+
+[ECO "D44"]
+[Opening "QGD semi-Slav"]
+[Variation "anti-Meran, Szabo variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. Bg5 dxc4 6. e4 b5 7. e5 h6 8. Bh4
+g5 9. Nxg5 hxg5 10. Bxg5 Nbd7 11. Qf3 *
+
+[ECO "D44"]
+[Opening "QGD semi-Slav"]
+[Variation "anti-Meran, Alatortsev system"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. Bg5 dxc4 6. e4 b5 7. e5 h6 8. Bh4
+g5 9. Nxg5 Nd5 *
+
+[ECO "D45"]
+[Opening "QGD semi-Slav"]
+[Variation "5.e3"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 *
+
+[ECO "D45"]
+[Opening "QGD semi-Slav"]
+[Variation "stonewall defence"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Ne4 6. Bd3 f5 *
+
+[ECO "D45"]
+[Opening "QGD semi-Slav"]
+[Variation "accelerated Meran (Alekhine variation)"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 a6 *
+
+[ECO "D45"]
+[Opening "QGD semi-Slav"]
+[Variation "5...Nd7"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 *
+
+[ECO "D45"]
+[Opening "QGD semi-Slav"]
+[Variation "Stoltz variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Qc2 *
+
+[ECO "D45"]
+[Opening "QGD semi-Slav"]
+[Variation "Rubinstein (anti-Meran) system"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Ne5 *
+
+[ECO "D46"]
+[Opening "QGD semi-Slav"]
+[Variation "6.Bd3"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 *
+
+[ECO "D46"]
+[Opening "QGD semi-Slav"]
+[Variation "Bogolyubov variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 Be7 *
+
+[ECO "D46"]
+[Opening "QGD semi-Slav"]
+[Variation "Romih variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 Bb4 *
+
+[ECO "D46"]
+[Opening "QGD semi-Slav"]
+[Variation "Chigorin defence"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 Bd6 *
+
+[ECO "D47"]
+[Opening "QGD semi-Slav"]
+[Variation "7.Bc4"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 *
+
+[ECO "D47"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 *
+
+[ECO "D47"]
+[Opening "QGD semi-Slav"]
+[Variation "neo-Meran (Lundin variation)"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 b4 *
+
+[ECO "D47"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, Wade variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 Bb7 *
+
+[ECO "D48"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, 8...a6"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 *
+
+[ECO "D48"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, Pirc variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 9. e4 b4 *
+
+[ECO "D48"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 9. e4 c5 *
+
+[ECO "D48"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, Reynolds' variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 9. e4 c5 10. d5 *
+
+[ECO "D48"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, old main line"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 9. e4 c5 10. e5 *
+
+[ECO "D49"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, Blumenfeld variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 9. e4 c5 10. e5 cxd4 11. Nxb5 *
+
+[ECO "D49"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, Rabinovich variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 9. e4 c5 10. e5 cxd4 11. Nxb5 Ng4 *
+
+[ECO "D49"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, Sozin variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 9. e4 c5 10. e5 cxd4 11. Nxb5 Nxe5 *
+
+[ECO "D49"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, Stahlberg variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 9. e4 c5 10. e5 cxd4 11. Nxb5 Nxe5 12. Nxe5 axb5 13. Qf3 *
+
+[ECO "D49"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, Sozin variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 9. e4 c5 10. e5 cxd4 11. Nxb5 Nxe5 12. Nxe5 axb5 13. O-O *
+
+[ECO "D49"]
+[Opening "QGD semi-Slav"]
+[Variation "Meran, Rellstab attack"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Nf3 c6 5. e3 Nbd7 6. Bd3 dxc4 7. Bxc4 b5 8.
+Bd3 a6 9. e4 c5 10. e5 cxd4 11. Nxb5 Nxe5 12. Nxe5 axb5 13. O-O Qd5 14. Qe2
+Ba6 15. Bg5 *
+
+[ECO "D50"]
+[Opening "QGD"]
+[Variation "4.Bg5"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 *
+
+[ECO "D50"]
+[Opening "QGD"]
+[Variation "Been-Koomen variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 c5 *
+
+[ECO "D50"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch, Krause variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 c5 5. Nf3 cxd4 6. Nxd4 e5 7. Ndb5 a6 8.
+Qa4 *
+
+[ECO "D50"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch, Primitive Pillsbury variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 c5 5. Nf3 cxd4 6. Qxd4 *
+
+[ECO "D50"]
+[Opening "QGD"]
+[Variation "Semi-Tarrasch"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 c5 5. cxd5 *
+
+[ECO "D50"]
+[Opening "QGD"]
+[Variation "Canal (Venice) variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 c5 5. cxd5 Qb6 *
+
+[ECO "D51"]
+[Opening "QGD"]
+[Variation "4.Bg5 Nbd7"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 *
+
+[ECO "D51"]
+[Opening "QGD"]
+[Variation "Rochlin variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. Nf3 c6 6. Rc1 Qa5 7. Bd2 *
+
+[ECO "D51"]
+[Opening "QGD"]
+[Variation "Alekhine variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. Nf3 c6 6. e4 *
+
+[ECO "D51"]
+[Opening "QGD"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 *
+
+[ECO "D51"]
+[Opening "QGD"]
+[Variation "Manhattan variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 Bb4 *
+
+[ECO "D51"]
+[Opening "QGD"]
+[Variation "5...c6"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 c6 *
+
+[ECO "D51"]
+[Opening "QGD"]
+[Variation "Capablanca anti-Cambridge Springs variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 c6 6. a3 *
+
+[ECO "D52"]
+[Opening "QGD"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 c6 6. Nf3 *
+
+[ECO "D52"]
+[Opening "QGD"]
+[Variation "Cambridge Springs defence"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 c6 6. Nf3 Qa5 *
+
+[ECO "D52"]
+[Opening "QGD"]
+[Variation "Cambridge Springs defence, Bogoljubow variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 c6 6. Nf3 Qa5 7. Nd2 Bb4 8.
+Qc2 *
+
+[ECO "D52"]
+[Opening "QGD"]
+[Variation "Cambridge Springs defence, Argentine variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 c6 6. Nf3 Qa5 7. Nd2 Bb4 8.
+Qc2 O-O 9. Bh4 *
+
+[ECO "D52"]
+[Opening "QGD"]
+[Variation "Cambridge Springs defence, Rubinstein variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 c6 6. Nf3 Qa5 7. Nd2 dxc4 *
+
+[ECO "D52"]
+[Opening "QGD"]
+[Variation "Cambridge Springs defence, Capablanca variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 c6 6. Nf3 Qa5 7. Bxf6 *
+
+[ECO "D52"]
+[Opening "QGD"]
+[Variation "Cambridge Springs defence, 7.cd"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 c6 6. Nf3 Qa5 7. cxd5 *
+
+[ECO "D52"]
+[Opening "QGD"]
+[Variation "Cambridge Springs defence, Yugoslav variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Nbd7 5. e3 c6 6. Nf3 Qa5 7. cxd5 Nxd5 *
+
+[ECO "D53"]
+[Opening "QGD"]
+[Variation "4.Bg5 Be7"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 *
+
+[ECO "D53"]
+[Opening "QGD"]
+[Variation "Lasker variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 Ne4 *
+
+[ECO "D53"]
+[Opening "QGD"]
+[Variation "4.Bg5 Be7, 5.e3 O-O"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O *
+
+[ECO "D54"]
+[Opening "QGD"]
+[Variation "Anti-neo-orthodox variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Rc1 *
+
+[ECO "D55"]
+[Opening "QGD"]
+[Variation "6.Nf3"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 *
+
+[ECO "D55"]
+[Opening "QGD"]
+[Variation "Pillsbury attack"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 b6 7. Bd3 Bb7 8. 
+cxd5 exd5 9. Ne5 *
+
+[ECO "D55"]
+[Opening "QGD"]
+[Variation "Neo-orthodox variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 *
+
+[ECO "D55"]
+[Opening "QGD"]
+[Variation "Neo-orthodox variation, 7.Bxf6"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bxf6 *
+
+[ECO "D55"]
+[Opening "QGD"]
+[Variation "Petrosian variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bxf6 Bxf6 8.
+Rc1 c6 9. Bd3 Nd7 10. O-O dxc4 11. Bxc4 *
+
+[ECO "D55"]
+[Opening "QGD"]
+[Variation "Neo-orthodox variation, 7.Bh4"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bh4 *
+
+[ECO "D56"]
+[Opening "QGD"]
+[Variation "Lasker defence"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bh4 Ne4 *
+
+[ECO "D56"]
+[Opening "QGD"]
+[Variation "Lasker defence, Teichmann variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bh4 Ne4 8. 
+Bxe7 Qxe7 9. Qc2 *
+
+[ECO "D56"]
+[Opening "QGD"]
+[Variation "Lasker defence, Russian variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bh4 Ne4 8. 
+Bxe7 Qxe7 9. Qc2 Nf6 10. Bd3 dxc4 11. Bxc4 c5 12. O-O Nc6 13. Rfd1 Bd7 *
+
+[ECO "D57"]
+[Opening "QGD"]
+[Variation "Lasker defence, main line"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bh4 Ne4 8. 
+Bxe7 Qxe7 9. cxd5 Nxc3 10. bxc3 *
+
+[ECO "D57"]
+[Opening "QGD"]
+[Variation "Lasker defence, Bernstein variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bh4 Ne4 8. 
+Bxe7 Qxe7 9. cxd5 Nxc3 10. bxc3 exd5 11. Qb3 Qd6 *
+
+[ECO "D58"]
+[Opening "QGD"]
+[Variation "Tartakower (Makagonov-Bondarevsky) system"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bh4 b6 *
+
+[ECO "D59"]
+[Opening "QGD"]
+[Variation "Tartakower (Makagonov-Bondarevsky) system, 8.cd Nxd5"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bh4 b6 8. 
+cxd5 Nxd5 *
+
+[ECO "D59"]
+[Opening "QGD"]
+[Variation "Tartakower variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6 7. Bh4 b6 8. 
+cxd5 Nxd5 9. Bxe7 Qxe7 10. Nxd5 exd5 11. Rc1 Be6 *
+
+[ECO "D60"]
+[Opening "QGD"]
+[Variation "Orthodox defence"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 *
+
+[ECO "D60"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Botvinnik variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Bd3 *
+
+[ECO "D60"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Rauzer variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Qb3 *
+
+[ECO "D61"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Rubinstein variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Qc2 *
+
+[ECO "D62"]
+[Opening "QGD"]
+[Variation "Orthodox defence, 7.Qc2 c5, 8.cd (Rubinstein)"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Qc2 c5 8.
+cxd5 *
+
+[ECO "D63"]
+[Opening "QGD"]
+[Variation "Orthodox defence, 7.Rc1"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 *
+
+[ECO "D63"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Pillsbury attack"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 b6 8.
+cxd5 exd5 9. Bd3 *
+
+[ECO "D63"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Capablanca variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 b6 8.
+cxd5 exd5 9. Bb5 *
+
+[ECO "D63"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Swiss (Henneberger) variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 a6 *
+
+[ECO "D63"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Swiss, Karlsbad variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 a6 8.
+cxd5 *
+
+[ECO "D63"]
+[Opening "QGD"]
+[Variation "Orthodox defence"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 *
+
+[ECO "D64"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Rubinstein attack (with Rc1)"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Qc2 *
+
+[ECO "D64"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Rubinstein attack, Wolf variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Qc2 Ne4 *
+
+[ECO "D64"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Rubinstein attack, Karlsbad variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Qc2 a6 *
+
+[ECO "D64"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Rubinstein attack, Gruenfeld variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Qc2 a6 9. a3 *
+
+[ECO "D65"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Rubinstein attack, main line"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Qc2 a6 9. cxd5 *
+
+[ECO "D66"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Bd3 line"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 *
+
+[ECO "D66"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Bd3 line, fianchetto variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 dxc4 9. Bxc4 b5 *
+
+[ECO "D67"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Bd3 line, Capablanca freeing manoevre"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 dxc4 9. Bxc4 Nd5 *
+
+[ECO "D67"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Bd3 line, Janowski variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 dxc4 9. Bxc4 Nd5 10. h4 *
+
+[ECO "D67"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Bd3 line"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 dxc4 9. Bxc4 Nd5 10. Bxe7 Qxe7 *
+
+[ECO "D67"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Bd3 line, Alekhine variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 dxc4 9. Bxc4 Nd5 10. Bxe7 Qxe7 11. Ne4 *
+
+[ECO "D67"]
+[Opening "QGD"]
+[Variation "Orthodox defence, Bd3 line, 11.O-O"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 dxc4 9. Bxc4 Nd5 10. Bxe7 Qxe7 11. O-O *
+
+[ECO "D68"]
+[Opening "QGD"]
+[Variation "Orthodox defence, classical variation"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 dxc4 9. Bxc4 Nd5 10. Bxe7 Qxe7 11. O-O Nxc3 12. Rxc3 e5 *
+
+[ECO "D68"]
+[Opening "QGD"]
+[Variation "Orthodox defence, classical, 13.d1b1 (Maroczy)"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 dxc4 9. Bxc4 Nd5 10. Bxe7 Qxe7 11. O-O Nxc3 12. Rxc3 e5 13. Qb1 *
+
+[ECO "D68"]
+[Opening "QGD"]
+[Variation "Orthodox defence, classical, 13.d1c2 (Vidmar)"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 dxc4 9. Bxc4 Nd5 10. Bxe7 Qxe7 11. O-O Nxc3 12. Rxc3 e5 13. Qc2 *
+
+[ECO "D69"]
+[Opening "QGD"]
+[Variation "Orthodox defence, classical, 13.de"]
+
+1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 Nbd7 7. Rc1 c6 8.
+Bd3 dxc4 9. Bxc4 Nd5 10. Bxe7 Qxe7 11. O-O Nxc3 12. Rxc3 e5 13. dxe5 Nxe5 
+14. Nxe5 Qxe5 *
+
+[ECO "D70"]
+[Opening "Neo-Gruenfeld defence"]
+
+1. d4 Nf6 2. c4 g6 3. f3 d5 *
+
+[ECO "D70"]
+[Opening "Neo-Gruenfeld (Kemeri) defence"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 *
+
+[ECO "D71"]
+[Opening "Neo-Gruenfeld, 5.cd"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 4. Bg2 Bg7 5. cxd5 Nxd5 *
+
+[ECO "D72"]
+[Opening "Neo-Gruenfeld, 5.cd, main line"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 4. Bg2 Bg7 5. cxd5 Nxd5 6. e4 Nb6 7. Ne2 *
+
+[ECO "D73"]
+[Opening "Neo-Gruenfeld, 5.Nf3"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 4. Bg2 Bg7 5. Nf3 *
+
+[ECO "D74"]
+[Opening "Neo-Gruenfeld, 6.cd Nxd5, 7.O-O"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 4. Bg2 Bg7 5. Nf3 O-O 6. cxd5 Nxd5 7. O-O *
+
+[ECO "D75"]
+[Opening "Neo-Gruenfeld, 6.cd Nxd5, 7.O-O c5, 8.Nc3"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 4. Bg2 Bg7 5. Nf3 O-O 6. cxd5 Nxd5 7. O-O c5 8.
+Nc3 *
+
+[ECO "D75"]
+[Opening "Neo-Gruenfeld, 6.cd Nxd5, 7.O-O c5, 8.dc"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 4. Bg2 Bg7 5. Nf3 O-O 6. cxd5 Nxd5 7. O-O c5 8.
+dxc5 *
+
+[ECO "D76"]
+[Opening "Neo-Gruenfeld, 6.cd Nxd5, 7.O-O Nb6"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 4. Bg2 Bg7 5. Nf3 O-O 6. cxd5 Nxd5 7. O-O Nb6 *
+
+[ECO "D77"]
+[Opening "Neo-Gruenfeld, 6.O-O"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 4. Bg2 Bg7 5. Nf3 O-O 6. O-O *
+
+[ECO "D78"]
+[Opening "Neo-Gruenfeld, 6.O-O c6"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 4. Bg2 Bg7 5. Nf3 O-O 6. O-O c6 *
+
+[ECO "D79"]
+[Opening "Neo-Gruenfeld, 6.O-O, main line"]
+
+1. d4 Nf6 2. c4 g6 3. g3 d5 4. Bg2 Bg7 5. Nf3 O-O 6. O-O c6 7. cxd5 cxd5 *
+
+[ECO "D80"]
+[Opening "Gruenfeld defence"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 *
+
+[ECO "D80"]
+[Opening "Gruenfeld"]
+[Variation "Spike gambit"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. g4 *
+
+[ECO "D80"]
+[Opening "Gruenfeld"]
+[Variation "Stockholm variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Bg5 *
+
+[ECO "D80"]
+[Opening "Gruenfeld"]
+[Variation "Lundin variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Bg5 Ne4 5. Nxe4 dxe4 6. Qd2 c5 *
+
+[ECO "D81"]
+[Opening "Gruenfeld"]
+[Variation "Russian variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Qb3 *
+
+[ECO "D82"]
+[Opening "Gruenfeld"]
+[Variation "4.Bf4"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Bf4 *
+
+[ECO "D83"]
+[Opening "Gruenfeld"]
+[Variation "Gruenfeld gambit"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Bf4 Bg7 5. e3 O-O *
+
+[ECO "D83"]
+[Opening "Gruenfeld"]
+[Variation "Gruenfeld gambit, Capablanca variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Bf4 Bg7 5. e3 O-O 6. Rc1 *
+
+[ECO "D83"]
+[Opening "Gruenfeld"]
+[Variation "Gruenfeld gambit, Botvinnik variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Bf4 Bg7 5. e3 O-O 6. Rc1 c5 7. dxc5 Be6 *
+
+[ECO "D84"]
+[Opening "Gruenfeld"]
+[Variation "Gruenfeld gambit accepted"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Bf4 Bg7 5. e3 O-O 6. cxd5 Nxd5 7. Nxd5 Qxd5
+8. Bxc7 *
+
+[ECO "D85"]
+[Opening "Gruenfeld"]
+[Variation "exchange variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 *
+
+[ECO "D85"]
+[Opening "Gruenfeld"]
+[Variation "modern exchange variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 5. e4 Nxc3 6. bxc3 Bg7 7. Nf3 *
+
+[ECO "D86"]
+[Opening "Gruenfeld"]
+[Variation "exchange, classical variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 5. e4 Nxc3 6. bxc3 Bg7 7. Bc4 *
+
+[ECO "D86"]
+[Opening "Gruenfeld"]
+[Variation "exchange, Larsen variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 5. e4 Nxc3 6. bxc3 Bg7 7. Bc4 O-O
+8. Ne2 Qd7 9. O-O b6 *
+
+[ECO "D86"]
+[Opening "Gruenfeld"]
+[Variation "exchange, Simagin's lesser variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 5. e4 Nxc3 6. bxc3 Bg7 7. Bc4 O-O
+8. Ne2 b6 *
+
+[ECO "D86"]
+[Opening "Gruenfeld"]
+[Variation "exchange, Simagin's improved variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 5. e4 Nxc3 6. bxc3 Bg7 7. Bc4 O-O
+8. Ne2 Nc6 *
+
+[ECO "D87"]
+[Opening "Gruenfeld"]
+[Variation "exchange, Spassky variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 5. e4 Nxc3 6. bxc3 Bg7 7. Bc4 O-O
+8. Ne2 c5 *
+
+[ECO "D87"]
+[Opening "Gruenfeld"]
+[Variation "exchange, Seville variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 5. e4 Nxc3 6. bxc3 Bg7 7. Bc4 O-O
+8. Ne2 c5 9. O-O Nc6 10. Be3 Bg4 11. f3 Na5 12. Bxf7+ *
+
+[ECO "D88"]
+[Opening "Gruenfeld"]
+[Variation "Spassky variation, main line, 10...cd, 11.cd"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 5. e4 Nxc3 6. bxc3 Bg7 7. Bc4 O-O
+8. Ne2 c5 9. O-O Nc6 10. Be3 cxd4 11. cxd4 *
+
+[ECO "D89"]
+[Opening "Gruenfeld"]
+[Variation "Spassky variation, main line, 13.Bd3"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 5. e4 Nxc3 6. bxc3 Bg7 7. Bc4 O-O
+8. Ne2 c5 9. O-O Nc6 10. Be3 cxd4 11. cxd4 Bg4 12. f3 Na5 13. Bd3 Be6 *
+
+[ECO "D89"]
+[Opening "Gruenfeld"]
+[Variation "exchange, Sokolsky variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. cxd5 Nxd5 5. e4 Nxc3 6. bxc3 Bg7 7. Bc4 O-O
+8. Ne2 c5 9. O-O Nc6 10. Be3 cxd4 11. cxd4 Bg4 12. f3 Na5 13. Bd3 Be6 14. 
+d5 *
+
+[ECO "D90"]
+[Opening "Gruenfeld"]
+[Variation "Three knights variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 *
+
+[ECO "D90"]
+[Opening "Gruenfeld"]
+[Variation "Schlechter variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 c6 *
+
+[ECO "D90"]
+[Opening "Gruenfeld"]
+[Variation "Three knights variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 *
+
+[ECO "D90"]
+[Opening "Gruenfeld"]
+[Variation "Flohr variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qa4+ *
+
+[ECO "D91"]
+[Opening "Gruenfeld"]
+[Variation "5.Bg5"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Bg5 *
+
+[ECO "D92"]
+[Opening "Gruenfeld"]
+[Variation "5.Bf4"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Bf4 *
+
+[ECO "D93"]
+[Opening "Gruenfeld with Bf4    e3"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Bf4 O-O 6. e3 *
+
+[ECO "D94"]
+[Opening "Gruenfeld"]
+[Variation "5.e3"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. e3 *
+
+[ECO "D94"]
+[Opening "Gruenfeld"]
+[Variation "Makogonov variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. e3 O-O 6. b4 *
+
+[ECO "D94"]
+[Opening "Gruenfeld"]
+[Variation "Opovcensky variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. e3 O-O 6. Bd2 *
+
+[ECO "D94"]
+[Opening "Gruenfeld with e3    Bd3"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. e3 O-O 6. Bd3 *
+
+[ECO "D94"]
+[Opening "Gruenfeld"]
+[Variation "Smyslov defence"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. e3 O-O 6. Bd3 c6 7. O-O Bg4 *
+
+[ECO "D94"]
+[Opening "Gruenfeld"]
+[Variation "Flohr defence"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. e3 O-O 6. Bd3 c6 7. O-O Bf5 *
+
+[ECO "D95"]
+[Opening "Gruenfeld with e3 & Qb3"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. e3 O-O 6. Qb3 *
+
+[ECO "D95"]
+[Opening "Gruenfeld"]
+[Variation "Botvinnik variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. e3 O-O 6. Qb3 e6 *
+
+[ECO "D95"]
+[Opening "Gruenfeld"]
+[Variation "Pachman variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. e3 O-O 6. Qb3 dxc4 7. Bxc4 Nbd7
+8. Ng5 *
+
+[ECO "D96"]
+[Opening "Gruenfeld"]
+[Variation "Russian variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 *
+
+[ECO "D97"]
+[Opening "Gruenfeld"]
+[Variation "Russian variation with e4"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 dxc4 6. Qxc4 O-O 7. e4 *
+
+[ECO "D97"]
+[Opening "Gruenfeld"]
+[Variation "Russian, Alekhine (Hungarian) variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 dxc4 6. Qxc4 O-O 7. e4 a6 *
+
+[ECO "D97"]
+[Opening "Gruenfeld"]
+[Variation "Russian, Szabo (Boleslavsky) variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 dxc4 6. Qxc4 O-O 7. e4 c6 *
+
+[ECO "D97"]
+[Opening "Gruenfeld"]
+[Variation "Russian, Levenfish variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 dxc4 6. Qxc4 O-O 7. e4 b6 *
+
+[ECO "D97"]
+[Opening "Gruenfeld"]
+[Variation "Russian, Byrne (Simagin) variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 dxc4 6. Qxc4 O-O 7. e4 Nc6 *
+
+[ECO "D97"]
+[Opening "Gruenfeld"]
+[Variation "Russian, Prins variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 dxc4 6. Qxc4 O-O 7. e4 Na6 *
+
+[ECO "D98"]
+[Opening "Gruenfeld"]
+[Variation "Russian, Smyslov variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 dxc4 6. Qxc4 O-O 7. e4 Bg4 *
+
+[ECO "D98"]
+[Opening "Gruenfeld"]
+[Variation "Russian, Keres variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 dxc4 6. Qxc4 O-O 7. e4 Bg4 
+8. Be3 Nfd7 9. Be2 Nb6 10. Qd3 Nc6 11. O-O-O *
+
+[ECO "D99"]
+[Opening "Gruenfeld defence"]
+[Variation "Smyslov, main line"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 dxc4 6. Qxc4 O-O 7. e4 Bg4 
+8. Be3 Nfd7 9. Qb3 *
+
+[ECO "D99"]
+[Opening "Gruenfeld defence"]
+[Variation "Smyslov, Yugoslav variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 d5 4. Nf3 Bg7 5. Qb3 dxc4 6. Qxc4 O-O 7. e4 Bg4 
+8. Be3 Nfd7 9. Qb3 c5 *
+
+[ECO "E00"]
+[Opening "Queen's pawn game"]
+
+1. d4 Nf6 2. c4 e6 *
+
+[ECO "E00"]
+[Opening "Neo-Indian (Seirawan) attack"]
+
+1. d4 Nf6 2. c4 e6 3. Bg5 *
+
+[ECO "E00"]
+[Opening "Catalan opening"]
+
+1. d4 Nf6 2. c4 e6 3. g3 *
+
+[ECO "E01"]
+[Opening "Catalan"]
+[Variation "closed"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 *
+
+[ECO "E02"]
+[Opening "Catalan"]
+[Variation "open, 5.Qa4"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 dxc4 5. Qa4+ *
+
+[ECO "E03"]
+[Opening "Catalan"]
+[Variation "open, Alekhine variation"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 dxc4 5. Qa4+ Nbd7 6. Qxc4 a6 7. Qc2 *
+
+[ECO "E03"]
+[Opening "Catalan"]
+[Variation "open, 5.Qa4 Nbd7, 6.Qxc4"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 dxc4 5. Qa4+ Nbd7 6. Qxc4 *
+
+[ECO "E04"]
+[Opening "Catalan"]
+[Variation "open, 5.Nf3"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 dxc4 5. Nf3 *
+
+[ECO "E05"]
+[Opening "Catalan"]
+[Variation "open, classical line"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 dxc4 5. Nf3 Be7 *
+
+[ECO "E06"]
+[Opening "Catalan"]
+[Variation "closed, 5.Nf3"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 Be7 5. Nf3 *
+
+[ECO "E07"]
+[Opening "Catalan"]
+[Variation "closed, 6...Nbd7"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 Be7 5. Nf3 O-O 6. O-O Nbd7 *
+
+[ECO "E07"]
+[Opening "Catalan"]
+[Variation "closed, Botvinnik variation"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 Be7 5. Nf3 O-O 6. O-O Nbd7 7. Nc3 c6 8.
+Qd3 *
+
+[ECO "E08"]
+[Opening "Catalan"]
+[Variation "closed, 7.Qc2"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 Be7 5. Nf3 O-O 6. O-O Nbd7 7. Qc2 *
+
+[ECO "E08"]
+[Opening "Catalan"]
+[Variation "closed, Zagoryansky variation"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 Be7 5. Nf3 O-O 6. O-O Nbd7 7. Qc2 c6 8.
+Rd1 b6 9. a4 *
+
+[ECO "E08"]
+[Opening "Catalan"]
+[Variation "closed, Qc2 & b3"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 Be7 5. Nf3 O-O 6. O-O Nbd7 7. Qc2 c6 8.
+b3 *
+
+[ECO "E08"]
+[Opening "Catalan"]
+[Variation "closed, Spassky gambit"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 Be7 5. Nf3 O-O 6. O-O Nbd7 7. Qc2 c6 8.
+b3 b6 9. Rd1 Bb7 10. Nc3 b5 *
+
+[ECO "E09"]
+[Opening "Catalan"]
+[Variation "closed, main line"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 Be7 5. Nf3 O-O 6. O-O Nbd7 7. Qc2 c6 8.
+Nbd2 *
+
+[ECO "E09"]
+[Opening "Catalan"]
+[Variation "closed, Sokolsky variation"]
+
+1. d4 Nf6 2. c4 e6 3. g3 d5 4. Bg2 Be7 5. Nf3 O-O 6. O-O Nbd7 7. Qc2 c6 8.
+Nbd2 b6 9. b3 a5 10. Bb2 Ba6 *
+
+[ECO "E10"]
+[Opening "Queen's pawn game"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 *
+
+[ECO "E10"]
+[Opening "Blumenfeld counter-gambit"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 c5 4. d5 b5 *
+
+[ECO "E10"]
+[Opening "Blumenfeld counter-gambit accepted"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 c5 4. d5 b5 5. dxe6 fxe6 6. cxb5 d5 *
+
+[ECO "E10"]
+[Opening "Blumenfeld counter-gambit, Dus-Chotimursky variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 c5 4. d5 b5 5. Bg5 *
+
+[ECO "E10"]
+[Opening "Blumenfeld counter-gambit, Spielmann variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 c5 4. d5 b5 5. Bg5 exd5 6. cxd5 h6 *
+
+[ECO "E10"]
+[Opening "Dzindzikhashvili defence"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 a6 *
+
+[ECO "E10"]
+[Opening "Doery defence"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 Ne4 *
+
+[ECO "E11"]
+[Opening "Bogo-Indian defence"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 Bb4+ *
+
+[ECO "E11"]
+[Opening "Bogo-Indian defence, Gruenfeld variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 Bb4+ 4. Nbd2 *
+
+[ECO "E11"]
+[Opening "Bogo-Indian defence, Nimzovich variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 Bb4+ 4. Bd2 Qe7 *
+
+[ECO "E11"]
+[Opening "Bogo-Indian defence, Monticelli trap"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 Bb4+ 4. Bd2 Bxd2+ 5. Qxd2 b6 6. g3 Bb7 7. Bg2 O-O
+8. Nc3 Ne4 9. Qc2 Nxc3 10. Ng5 *
+
+[ECO "E12"]
+[Opening "Queen's Indian defence"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 *
+
+[ECO "E12"]
+[Opening "Queen's Indian"]
+[Variation "Miles variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Bf4 *
+
+[ECO "E12"]
+[Opening "Queen's Indian"]
+[Variation "Petrosian system"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. a3 *
+
+[ECO "E12"]
+[Opening "Queen's Indian"]
+[Variation "4.Nc3"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Nc3 *
+
+[ECO "E12"]
+[Opening "Queen's Indian"]
+[Variation "4.Nc3, Botvinnik variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Nc3 Bb7 5. Bg5 h6 6. Bh4 g5 7. Bg3 Nh5 *
+
+[ECO "E13"]
+[Opening "Queen's Indian"]
+[Variation "4.Nc3, main line"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Nc3 Bb7 5. Bg5 h6 6. Bh4 Bb4 *
+
+[ECO "E14"]
+[Opening "Queen's Indian"]
+[Variation "4.e3"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. e3 *
+
+[ECO "E14"]
+[Opening "Queen's Indian"]
+[Variation "Averbakh variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. e3 Bb7 5. Bd3 c5 6. O-O Be7 7. b3 O-O 8. 
+Bb2 cxd4 9. Nxd4 *
+
+[ECO "E15"]
+[Opening "Queen's Indian"]
+[Variation "4.g3"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 *
+
+[ECO "E15"]
+[Opening "Queen's Indian"]
+[Variation "Nimzovich variation (exaggerated fianchetto)"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Ba6 *
+
+[ECO "E15"]
+[Opening "Queen's Indian"]
+[Variation "4.g3 Bb7"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 *
+
+[ECO "E15"]
+[Opening "Queen's Indian"]
+[Variation "Rubinstein variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 c5 6. d5 exd5 7. Nh4 *
+
+[ECO "E15"]
+[Opening "Queen's Indian"]
+[Variation "Buerger variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 c5 6. d5 exd5 7. Ng5 *
+
+[ECO "E16"]
+[Opening "Queen's Indian"]
+[Variation "Capablanca variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 Bb4+ *
+
+[ECO "E16"]
+[Opening "Queen's Indian"]
+[Variation "Yates variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 Bb4+ 6. Bd2 a5 *
+
+[ECO "E16"]
+[Opening "Queen's Indian"]
+[Variation "Riumin variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 Bb4+ 6. Bd2 Be7 *
+
+[ECO "E17"]
+[Opening "Queen's Indian"]
+[Variation "5.Bg2 Be7"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 Be7 *
+
+[ECO "E17"]
+[Opening "Queen's Indian"]
+[Variation "anti-Queen's Indian system"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 Be7 6. Nc3 *
+
+[ECO "E17"]
+[Opening "Queen's Indian"]
+[Variation "Opovcensky variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 Be7 6. Nc3 Ne4 7. Bd2 *
+
+[ECO "E17"]
+[Opening "Queen's Indian"]
+[Variation "old main line, 6.O-O"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 Be7 6. O-O *
+
+[ECO "E17"]
+[Opening "Queen's Indian"]
+[Variation "Euwe variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 Be7 6. O-O O-O 7. b3 *
+
+[ECO "E18"]
+[Opening "Queen's Indian"]
+[Variation "old main line, 7.Nc3"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 Be7 6. O-O O-O 7. Nc3 *
+
+[ECO "E19"]
+[Opening "Queen's Indian"]
+[Variation "old main line, 9.Qxc3"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. g3 Bb7 5. Bg2 Be7 6. O-O O-O 7. Nc3 Ne4 8.
+Qc2 Nxc3 9. Qxc3 *
+
+[ECO "E20"]
+[Opening "Nimzo-Indian defence"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 *
+
+[ECO "E20"]
+[Opening "Nimzo-Indian"]
+[Variation "Kmoch variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. f3 *
+
+[ECO "E20"]
+[Opening "Nimzo-Indian"]
+[Variation "Mikenas attack"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qd3 *
+
+[ECO "E20"]
+[Opening "Nimzo-Indian"]
+[Variation "Romanishin-Kasparov (Steiner) system"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. g3 *
+
+[ECO "E21"]
+[Opening "Nimzo-Indian"]
+[Variation "three knights variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Nf3 *
+
+[ECO "E21"]
+[Opening "Nimzo-Indian"]
+[Variation "three knights, Korchnoi variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Nf3 c5 5. d5 *
+
+[ECO "E21"]
+[Opening "Nimzo-Indian"]
+[Variation "three knights, Euwe variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Nf3 c5 5. d5 Ne4 *
+
+[ECO "E22"]
+[Opening "Nimzo-Indian"]
+[Variation "Spielmann variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qb3 *
+
+[ECO "E23"]
+[Opening "Nimzo-Indian"]
+[Variation "Spielmann, 4...c5, 5.dc Nc6"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qb3 c5 5. dxc5 Nc6 *
+
+[ECO "E23"]
+[Opening "Nimzo-Indian"]
+[Variation "Spielmann, Karlsbad variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qb3 c5 5. dxc5 Nc6 6. Nf3 Ne4 7. Bd2 Nxd2
+*
+
+[ECO "E23"]
+[Opening "Nimzo-Indian"]
+[Variation "Spielmann, San Remo variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qb3 c5 5. dxc5 Nc6 6. Nf3 Ne4 7. Bd2 Nxc5
+*
+
+[ECO "E23"]
+[Opening "Nimzo-Indian"]
+[Variation "Spielmann, Staahlberg variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qb3 c5 5. dxc5 Nc6 6. Nf3 Ne4 7. Bd2 Nxc5
+8. Qc2 f5 9. g3 *
+
+[ECO "E24"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 *
+
+[ECO "E24"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch, Botvinnik variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 c5 6. f3 d5 7. e3 O-O 8.
+cxd5 Nxd5 *
+
+[ECO "E25"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 c5 6. f3 d5 7. cxd5 *
+
+[ECO "E25"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch, Keres variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 c5 6. f3 d5 7. cxd5 Nxd5
+8. dxc5 *
+
+[ECO "E25"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch, Romanovsky variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 c5 6. f3 d5 7. cxd5 Nxd5
+8. dxc5 f5 *
+
+[ECO "E26"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 c5 6. e3 *
+
+[ECO "E26"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch, O'Kelly variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 c5 6. e3 b6 *
+
+[ECO "E27"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 O-O *
+
+[ECO "E28"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 O-O 6. e3 *
+
+[ECO "E29"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch, main line"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 O-O 6. e3 c5 7. Bd3 Nc6 *
+
+[ECO "E29"]
+[Opening "Nimzo-Indian"]
+[Variation "Saemisch, Capablanca variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 O-O 6. e3 c5 7. Bd3 Nc6 
+8. Ne2 b6 9. e4 Ne8 *
+
+[ECO "E30"]
+[Opening "Nimzo-Indian"]
+[Variation "Leningrad variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Bg5 *
+
+[ECO "E30"]
+[Opening "Nimzo-Indian"]
+[Variation "Leningrad, ...b5 gambit"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Bg5 h6 5. Bh4 c5 6. d5 b5 *
+
+[ECO "E31"]
+[Opening "Nimzo-Indian"]
+[Variation "Leningrad, main line"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Bg5 h6 5. Bh4 c5 6. d5 d6 *
+
+[ECO "E32"]
+[Opening "Nimzo-Indian"]
+[Variation "classical variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 *
+
+[ECO "E32"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, Adorjan gambit"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 O-O 5. a3 Bxc3+ 6. Qxc3 b5 *
+
+[ECO "E33"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, 4...Nc6"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 Nc6 *
+
+[ECO "E33"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, Milner-Barry (Zurich) variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 Nc6 5. Nf3 d6 *
+
+[ECO "E34"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, Noa variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 *
+
+[ECO "E35"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, Noa variation, 5.cd ed"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 *
+
+[ECO "E36"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, Noa variation, 5.a3"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. a3 *
+
+[ECO "E36"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, Botvinnik variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. a3 Bxc3+ 6. Qxc3 Nc6 *
+
+[ECO "E36"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, Noa variation, main line"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. a3 Bxc3+ 6. Qxc3 Ne4 *
+
+[ECO "E37"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, Noa variation, main line, 7.Qc2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. a3 Bxc3+ 6. Qxc3 Ne4 7. Qc2 *
+
+[ECO "E37"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, San Remo variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. a3 Bxc3+ 6. Qxc3 Ne4 7. Qc2 Nc6
+8. e3 e5 *
+
+[ECO "E38"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, 4...c5"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 c5 *
+
+[ECO "E39"]
+[Opening "Nimzo-Indian"]
+[Variation "classical, Pirc variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 c5 5. dxc5 O-O *
+
+[ECO "E40"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 *
+
+[ECO "E40"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Taimanov variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 Nc6 *
+
+[ECO "E41"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3 c5"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 *
+
+[ECO "E41"]
+[Opening "Nimzo-Indian"]
+[Variation "e3, Huebner variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 Nc6 6. Nf3 Bxc3+ 7. bxc3 d6 *
+
+[ECO "E42"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3 c5, 5.Ne2 (Rubinstein)"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Ne2 *
+
+[ECO "E43"]
+[Opening "Nimzo-Indian"]
+[Variation "Fischer variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 b6 *
+
+[ECO "E44"]
+[Opening "Nimzo-Indian"]
+[Variation "Fischer variation, 5.Ne2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 b6 5. Ne2 *
+
+[ECO "E45"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Bronstein (Byrne) variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 b6 5. Ne2 Ba6 *
+
+[ECO "E46"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3 O-O"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O *
+
+[ECO "E46"]
+[Opening "Nimzo-Indian"]
+[Variation "Reshevsky variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Ne2 *
+
+[ECO "E46"]
+[Opening "Nimzo-Indian"]
+[Variation "Simagin variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Ne2 d5 6. a3 Bd6 *
+
+[ECO "E47"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3 O-O, 5.Bd3"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 *
+
+[ECO "E48"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3 O-O, 5.Bd3 d5"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 d5 *
+
+[ECO "E49"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Botvinnik system"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 d5 6. a3 Bxc3+ 7. bxc3 *
+
+[ECO "E50"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3 e8g8, 5.Nf3, without ...d5"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 *
+
+[ECO "E51"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3 e8g8, 5.Nf3 d7d5"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 *
+
+[ECO "E51"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Ragozin variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 Nc6 7. O-O dxc4 *
+
+[ECO "E52"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, main line with ...b6"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 b6 *
+
+[ECO "E53"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, main line with ...c5"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 c5 *
+
+[ECO "E53"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Keres variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 c5 7. O-O b6 *
+
+[ECO "E53"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Gligoric system with 7...Nbd7"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 c5 7. O-O Nbd7 *
+
+[ECO "E54"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Gligoric system with 7...dc"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 c5 7. O-O dxc4 8.
+Bxc4 *
+
+[ECO "E54"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Gligoric system, Smyslov variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 c5 7. O-O dxc4 8.
+Bxc4 Qe7 *
+
+[ECO "E55"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Gligoric system, Bronstein variation"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 c5 7. O-O dxc4 8.
+Bxc4 Nbd7 *
+
+[ECO "E56"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, main line with 7...Nc6"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 c5 7. O-O Nc6 *
+
+[ECO "E57"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, main line with 8...dc and 9...cd"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 c5 7. O-O Nc6 8. 
+a3 dxc4 9. Bxc4 cxd4 *
+
+[ECO "E58"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, main line with 8...Bxc3"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 c5 7. O-O Nc6 8. 
+a3 Bxc3 9. bxc3 *
+
+[ECO "E59"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, main line"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Nf3 d5 6. Bd3 c5 7. O-O Nc6 8. 
+a3 Bxc3 9. bxc3 dxc4 10. Bxc4 *
+
+[ECO "E60"]
+[Opening "King's Indian defence"]
+
+1. d4 Nf6 2. c4 g6 *
+
+[ECO "E60"]
+[Opening "King's Indian, 3.Nf3"]
+
+1. d4 Nf6 2. c4 g6 3. Nf3 *
+
+[ECO "E60"]
+[Opening "Queen's pawn"]
+[Variation "Mengarini attack"]
+
+1. d4 Nf6 2. c4 g6 3. Qc2 *
+
+[ECO "E60"]
+[Opening "King's Indian"]
+[Variation "Anti-Gruenfeld"]
+
+1. d4 Nf6 2. c4 g6 3. d5 *
+
+[ECO "E60"]
+[Opening "King's Indian"]
+[Variation "Danube gambit"]
+
+1. d4 Nf6 2. c4 g6 3. d5 b5 *
+
+[ECO "E60"]
+[Opening "King's Indian"]
+[Variation "3.g3"]
+
+1. d4 Nf6 2. c4 g6 3. g3 *
+
+[ECO "E60"]
+[Opening "King's Indian"]
+[Variation "3.g3, counterthrust variation"]
+
+1. d4 Nf6 2. c4 g6 3. g3 Bg7 4. Bg2 d5 *
+
+[ECO "E61"]
+[Opening "King's Indian defence, 3.Nc3"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 *
+
+[ECO "E61"]
+[Opening "King's Indian"]
+[Variation "Smyslov system"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. Bg5 *
+
+[ECO "E62"]
+[Opening "King's Indian"]
+[Variation "fianchetto variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 *
+
+[ECO "E62"]
+[Opening "King's Indian"]
+[Variation "fianchetto, Larsen system"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 c6 7. O-O Bf5 *
+
+[ECO "E62"]
+[Opening "King's Indian"]
+[Variation "fianchetto, Kavalek (Bronstein) variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 c6 7. O-O Qa5 *
+
+[ECO "E62"]
+[Opening "King's Indian"]
+[Variation "fianchetto with ...Nc6"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 Nc6 *
+
+[ECO "E62"]
+[Opening "King's Indian"]
+[Variation "fianchetto, Uhlmann (Szabo) variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 Nc6 7. O-O e5 *
+
+[ECO "E62"]
+[Opening "King's Indian"]
+[Variation "fianchetto, lesser Simagin (Spassky) variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 Nc6 7. O-O Bf5 *
+
+[ECO "E62"]
+[Opening "King's Indian"]
+[Variation "fianchetto, Simagin variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 Nc6 7. O-O Bg4 *
+
+[ECO "E63"]
+[Opening "King's Indian"]
+[Variation "fianchetto, Panno variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 Nc6 7. O-O a6 *
+
+[ECO "E64"]
+[Opening "King's Indian"]
+[Variation "fianchetto, Yugoslav system"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 c5 *
+
+[ECO "E65"]
+[Opening "King's Indian"]
+[Variation "fianchetto, Yugoslav, 7.O-O"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 c5 7. O-O *
+
+[ECO "E66"]
+[Opening "King's Indian"]
+[Variation "fianchetto, Yugoslav Panno"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 c5 7. O-O Nc6 8. 
+d5 *
+
+[ECO "E67"]
+[Opening "King's Indian"]
+[Variation "fianchetto with ...Nd7"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 Nbd7 *
+
+[ECO "E67"]
+[Opening "King's Indian"]
+[Variation "fianchetto, classical variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 Nbd7 7. O-O e5 *
+
+[ECO "E68"]
+[Opening "King's Indian"]
+[Variation "fianchetto, classical variation, 8.e4"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 Nbd7 7. O-O e5 8.
+e4 *
+
+[ECO "E69"]
+[Opening "King's Indian"]
+[Variation "fianchetto, classical main line"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. Nf3 d6 5. g3 O-O 6. Bg2 Nbd7 7. O-O e5 8.
+e4 c6 9. h3 *
+
+[ECO "E70"]
+[Opening "King's Indian"]
+[Variation "4.e4"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 *
+
+[ECO "E70"]
+[Opening "King's Indian"]
+[Variation "Kramer system"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nge2 *
+
+[ECO "E70"]
+[Opening "King's Indian"]
+[Variation "accelerated Averbakh system"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Bg5 *
+
+[ECO "E71"]
+[Opening "King's Indian"]
+[Variation "Makagonov system (5.h3)"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. h3 *
+
+[ECO "E72"]
+[Opening "King's Indian with e4 & g3"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. g3 *
+
+[ECO "E72"]
+[Opening "King's Indian"]
+[Variation "Pomar system"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. g3 O-O 6. Bg2 e5 7. Nge2 *
+
+[ECO "E73"]
+[Opening "King's Indian"]
+[Variation "5.Be2"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Be2 *
+
+[ECO "E73"]
+[Opening "King's Indian"]
+[Variation "Semi-Averbakh system"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Be2 O-O 6. Be3 *
+
+[ECO "E73"]
+[Opening "King's Indian"]
+[Variation "Averbakh system"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Be2 O-O 6. Bg5 *
+
+[ECO "E74"]
+[Opening "King's Indian"]
+[Variation "Averbakh, 6...c5"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Be2 O-O 6. Bg5 c5 *
+
+[ECO "E75"]
+[Opening "King's Indian"]
+[Variation "Averbakh, main line"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Be2 O-O 6. Bg5 c5 7. d5 e6 *
+
+[ECO "E76"]
+[Opening "King's Indian"]
+[Variation "Four pawns attack"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f4 *
+
+[ECO "E76"]
+[Opening "King's Indian"]
+[Variation "Four pawns attack, dynamic line"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f4 O-O 6. Nf3 c5 7. d5 *
+
+[ECO "E77"]
+[Opening "King's Indian"]
+[Variation "Four pawns attack, 6.Be2"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f4 O-O 6. Be2 *
+
+[ECO "E77"]
+[Opening "King's Indian"]
+[Variation "Six pawns attack"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f4 O-O 6. Be2 c5 7. d5 e6 8. dxe6
+fxe6 9. g4 Nc6 10. h4 *
+
+[ECO "E77"]
+[Opening "King's Indian"]
+[Variation "Four pawns attack"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f4 O-O 6. Be2 c5 7. d5 e6 8. Nf3
+*
+
+[ECO "E77"]
+[Opening "King's Indian"]
+[Variation "Four pawns attack, Florentine gambit"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f4 O-O 6. Be2 c5 7. d5 e6 8. Nf3
+exd5 9. e5 *
+
+[ECO "E78"]
+[Opening "King's Indian"]
+[Variation "Four pawns attack, with Be2 and Nf3"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f4 O-O 6. Be2 c5 7. Nf3 *
+
+[ECO "E79"]
+[Opening "King's Indian"]
+[Variation "Four pawns attack, main line"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f4 O-O 6. Be2 c5 7. Nf3 cxd4 8. 
+Nxd4 Nc6 9. Be3 *
+
+[ECO "E80"]
+[Opening "King's Indian"]
+[Variation "Saemisch variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 *
+
+[ECO "E81"]
+[Opening "King's Indian"]
+[Variation "Saemisch, 5...O-O"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O *
+
+[ECO "E81"]
+[Opening "King's Indian"]
+[Variation "Saemisch, Byrne variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 c6 7. Bd3 a6 *
+
+[ECO "E82"]
+[Opening "King's Indian"]
+[Variation "Saemisch, double fianchetto variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 b6 *
+
+[ECO "E83"]
+[Opening "King's Indian"]
+[Variation "Saemisch, 6...Nc6"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 Nc6 *
+
+[ECO "E83"]
+[Opening "King's Indian"]
+[Variation "Saemisch, Ruban variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 Nc6 7. Nge2 Rb8 *
+
+[ECO "E83"]
+[Opening "King's Indian"]
+[Variation "Saemisch, Panno formation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 Nc6 7. Nge2 a6 *
+
+[ECO "E84"]
+[Opening "King's Indian"]
+[Variation "Saemisch, Panno main line"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 Nc6 7. Nge2 a6 8. 
+Qd2 Rb8 *
+
+[ECO "E85"]
+[Opening "King's Indian"]
+[Variation "Saemisch, orthodox variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 e5 *
+
+[ECO "E86"]
+[Opening "King's Indian"]
+[Variation "Saemisch, orthodox, 7.Nge2 c6"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 e5 7. Nge2 c6 *
+
+[ECO "E87"]
+[Opening "King's Indian"]
+[Variation "Saemisch, orthodox, 7.d5"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 e5 7. d5 *
+
+[ECO "E87"]
+[Opening "King's Indian"]
+[Variation "Saemisch, orthodox, Bronstein variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 e5 7. d5 Nh5 8. Qd2
+Qh4+ 9. g3 Nxg3 10. Qf2 Nxf1 11. Qxh4 Nxe3 12. Ke2 Nxc4 *
+
+[ECO "E88"]
+[Opening "King's Indian"]
+[Variation "Saemisch, orthodox, 7.d5 c6"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 e5 7. d5 c6 *
+
+[ECO "E89"]
+[Opening "King's Indian"]
+[Variation "Saemisch, orthodox main line"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. f3 O-O 6. Be3 e5 7. d5 c6 8. Nge2
+cxd5 *
+
+[ECO "E90"]
+[Opening "King's Indian"]
+[Variation "5.Nf3"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 *
+
+[ECO "E90"]
+[Opening "King's Indian"]
+[Variation "Larsen variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be3 *
+
+[ECO "E90"]
+[Opening "King's Indian"]
+[Variation "Zinnowitz variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Bg5 *
+
+[ECO "E91"]
+[Opening "King's Indian"]
+[Variation "6.Be2"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 *
+
+[ECO "E91"]
+[Opening "King's Indian"]
+[Variation "Kazakh variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 Na6 *
+
+[ECO "E92"]
+[Opening "King's Indian"]
+[Variation "classical variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 *
+
+[ECO "E92"]
+[Opening "King's Indian"]
+[Variation "Andersson variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. dxe5 *
+
+[ECO "E92"]
+[Opening "King's Indian"]
+[Variation "Gligoric-Taimanov system"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. Be3 *
+
+[ECO "E92"]
+[Opening "King's Indian"]
+[Variation "Petrosian system"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. d5 *
+
+[ECO "E92"]
+[Opening "King's Indian"]
+[Variation "Petrosian system, Stein variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. d5 a5 *
+
+[ECO "E93"]
+[Opening "King's Indian"]
+[Variation "Petrosian system, main line"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. d5 Nbd7 *
+
+[ECO "E93"]
+[Opening "King's Indian"]
+[Variation "Petrosian system, Keres variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. d5 Nbd7 8. 
+Bg5 h6 9. Bh4 g5 10. Bg3 Nh5 11. h4 *
+
+[ECO "E94"]
+[Opening "King's Indian"]
+[Variation "orthodox variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. O-O *
+
+[ECO "E94"]
+[Opening "King's Indian"]
+[Variation "orthodox, Donner variation"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. O-O c6 *
+
+[ECO "E94"]
+[Opening "King's Indian"]
+[Variation "orthodox, 7...Nbd7"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. O-O Nbd7 *
+
+[ECO "E95"]
+[Opening "King's Indian"]
+[Variation "orthodox, 7...Nbd7, 8.Re1"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. O-O Nbd7 8.
+Re1 *
+
+[ECO "E96"]
+[Opening "King's Indian"]
+[Variation "orthodox, 7...Nbd7, main line"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. O-O Nbd7 8.
+Re1 c6 9. Bf1 a5 *
+
+[ECO "E97"]
+[Opening "King's Indian"]
+[Variation "orthodox, Aronin-Taimanov variation (Yugoslav attack / Mar del Plata variation)"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. O-O Nc6 *
+
+[ECO "E97"]
+[Opening "King's Indian"]
+[Variation "orthodox, Aronin-Taimanov, bayonet attack"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. O-O Nc6 8. 
+d5 Ne7 9. b4 *
+
+[ECO "E98"]
+[Opening "King's Indian"]
+[Variation "orthodox, Aronin-Taimanov, 9.Ne1"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. O-O Nc6 8. 
+d5 Ne7 9. Ne1 *
+
+[ECO "E99"]
+[Opening "King's Indian"]
+[Variation "orthodox, Aronin-Taimanov, main line"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. O-O Nc6 8. 
+d5 Ne7 9. Ne1 Nd7 10. f3 f5 *
+
+[ECO "E99"]
+[Opening "King's Indian"]
+[Variation "orthodox, Aronin-Taimanov, Benko attack"]
+
+1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 4. e4 d6 5. Nf3 O-O 6. Be2 e5 7. O-O Nc6 8. 
+d5 Ne7 9. Ne1 Nd7 10. f3 f5 11. g4 *
+
diff --git a/end.c b/end.c
new file mode 100644 (file)
index 0000000..9af0c29
--- /dev/null
+++ b/end.c
@@ -0,0 +1,652 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "end.h"
+#include "lines.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "lex.h"
+#include "apply.h"
+#include "grammar.h"
+
+/**
+ * Code to handle specifications describing the state of the board
+ * in terms of numbers of pieces and material balance between opponents.
+ *
+ * Games are then matched against these specifications.
+ */
+
+/* Define a type to represent classes of occurrance. */
+typedef enum {
+    EXACTLY, NUM_OR_MORE, NUM_OR_LESS,
+    SAME_AS_OPPONENT, NOT_SAME_AS_OPPONENT,
+    LESS_THAN_OPPONENT, MORE_THAN_OPPONENT,
+    LESS_EQ_THAN_OPPONENT, MORE_EQ_THAN_OPPONENT
+} Occurs;
+
+/* Define a structure to hold details on the occurrances of
+ * each of the pieces.
+ */
+
+typedef struct ending_details{
+    /* There is not a proper distinction between black and white
+     * but we still need information on the two sets of pieces
+     * specified in the input file.
+     */
+    int num_pieces[2][NUM_PIECE_VALUES];
+    Occurs occurs[2][NUM_PIECE_VALUES];
+    /* Numbers of general minor pieces. */
+    int num_minor_pieces[2];
+    Occurs minor_occurs[2];
+    /* How long a given relationship must last to be recognised.
+     * This value is in half moves.
+     */
+    unsigned move_depth;
+    /* How long a match relationship has been matched.
+     * This is always reset to zero on failure and incremented on
+     * success. A full match is only returned when match_depth == move_depth.
+     */
+    unsigned match_depth[2];
+    struct ending_details *next;
+} Ending_details;
+
+/* Keep a list of endings to be found. */
+static Ending_details *endings_to_match = NULL;
+
+        /* What kind of piece is the character, c, likely to represent?
+         * NB: This is NOT the same as is_piece() in decode.c
+         */
+/* Define pseudo-letter for minor pieces, used later. */
+#define MINOR_PIECE 'L'
+
+static Piece
+is_English_piece(char c)
+{   Piece piece = EMPTY;
+
+    switch(c){
+        case 'K': case 'k':
+            piece = KING;
+            break;
+        case 'Q': case 'q':
+            piece = QUEEN;
+            break;
+        case 'R': case 'r':
+            piece = ROOK;
+            break;
+        case 'N': case 'n':
+            piece = KNIGHT;
+            break;
+        case 'B': case 'b':
+            piece = BISHOP;
+            break;
+        case 'P': case 'p':
+            piece = PAWN;
+            break;
+    }
+    return piece;
+}
+
+        /* Initialise the count of required pieces prior to reading
+         * in the data.
+         */
+static Ending_details *
+new_ending_details(void)
+{   Ending_details *details = (Ending_details *) MallocOrDie(sizeof(Ending_details));
+    int c;
+    Piece piece;
+
+    for(piece = PAWN; piece <= KING; piece++){
+        for(c = 0; c < 2; c++){
+           details->num_pieces[c][piece] = 0;
+           details->occurs[c][piece] = EXACTLY;
+        }
+    }
+    /* Fill out some miscellaneous colour based information. */
+    for(c = 0; c < 2; c++){
+        /* Only the KING is a requirement for each side. */
+        details->num_pieces[c][KING] = 1;
+        details->match_depth[c] = 0;
+        /* How many general minor pieces to match. */
+        details->num_minor_pieces[c] = 0;
+        details->minor_occurs[c] = EXACTLY;
+    }
+    /* Assume that the match must always have a depth of at least two for
+     * two half-move stability.
+     */
+    details->move_depth = 2;
+    details->next = NULL;
+    return details;
+}
+
+static const char *
+extract_combination(const char *p,Occurs *p_occurs, int *p_number, const char *line)
+{   Boolean Ok = TRUE;
+    Occurs occurs = EXACTLY;
+    int number = 1;
+
+    if(isdigit((int) *p)){
+        /* Only single digits are allowed. */
+        number = *p-'0';
+        p++;
+        if(isdigit((int) *p)){
+            fprintf(GlobalState.logfile,"Number > 9 is too big in %s.\n",
+                        line);
+            while(isdigit((int) *p)){
+                p++;
+            }
+            Ok = FALSE;
+        }
+    }
+    if(Ok){
+        /* Look for trailing annotations. */
+        switch(*p){
+          case '*':
+            number = 0;
+            occurs = NUM_OR_MORE;
+            p++;
+            break;
+          case '+':
+            occurs = NUM_OR_MORE;
+            p++;
+            break;
+          case '-':
+            occurs = NUM_OR_LESS;
+            p++;
+            break;
+          case '?':
+            number = 1;
+            occurs = NUM_OR_LESS;
+            p++;
+            break;
+          case '=':
+          case '#':
+          case '<':
+          case '>':
+            switch(*p){
+              case '=':
+                p++;
+                occurs = SAME_AS_OPPONENT;
+                break;
+              case '#':
+                p++;
+                occurs = NOT_SAME_AS_OPPONENT;
+                break;
+              case '<':
+                p++;
+                if(*p == '='){
+                      occurs = LESS_EQ_THAN_OPPONENT;
+                      p++;
+                }
+                else{
+                      occurs = LESS_THAN_OPPONENT;
+                }
+                break;
+              case '>':
+                p++;
+                if(*p == '='){
+                      occurs = MORE_EQ_THAN_OPPONENT;
+                      p++;
+                }
+                else{
+                      occurs = MORE_THAN_OPPONENT;
+                }
+                break;
+            }
+            break;
+        }
+    }
+
+    if(Ok){
+        *p_occurs = occurs;
+        *p_number = number;
+        return p;
+    }
+    else{
+        return NULL;
+    }
+}
+
+        /* Extract a single piece set of information from line.
+         * Return where we have got to as the result.
+         * colour == WHITE means we are looking at the first set of
+         * pieces, so some of the notation is illegal (i.e. the relative ops).
+         *
+         * The basic syntax for a piece description is:
+         *        piece [number] [occurs]
+         * For instance:
+         *        P2+ Pawn occurs at least twice or more.
+         *        R= Rook occurs same number of times as opponent. (colour == BLACK)
+         *        P1>= Exactly one pawn more than the opponent. (colour == BLACK)
+         */
+static const char *
+extract_piece_information(const char *line,Ending_details *details,Colour colour)
+{   const char *p = line;
+    Boolean Ok = TRUE;
+
+    while(Ok && (*p != '\0') && !isspace((int) *p)){
+        Piece piece = is_English_piece(*p);
+        /* By default a piece should occur exactly once. */
+        Occurs occurs = EXACTLY;
+        int number = 1;
+
+        if(piece != EMPTY){
+
+            /* Skip over the piece. */
+            p++;
+            p = extract_combination(p,&occurs,&number,line);
+            if(p != NULL){
+                if((piece == KING) && (number != 1)){
+                    fprintf(GlobalState.logfile,"A king must occur exactly once.\n");
+                    number = 1;
+                }
+                else if((piece == PAWN) && (number > 8)){
+                    fprintf(GlobalState.logfile,
+                                "No more than 8 pawns are allowed.\n");
+                    number = 8;
+                }
+                details->num_pieces[colour][piece] = number;
+                details->occurs[colour][piece] = occurs;
+            }
+            else{
+                Ok = FALSE;
+            }
+        }
+        else if(isalpha((int) *p) && (toupper((int) *p) == MINOR_PIECE)){
+            p++;
+            p = extract_combination(p,&occurs,&number,line);
+            if(p != NULL){
+                details->num_minor_pieces[colour] = number;
+                details->minor_occurs[colour] = occurs;
+            }
+            else{
+                Ok = FALSE;
+            }
+        }
+        else{
+            fprintf(GlobalState.logfile,"Unknown symbol at %s\n", p);
+            Ok = FALSE;
+        }
+    }
+    if(Ok){
+        /* Make a sanity check on the use of minor pieces. */
+        if((details->num_minor_pieces[colour] > 0) ||
+                (details->minor_occurs[colour] != EXACTLY)){
+            /* Warn about use of BISHOP and KNIGHT letters. */
+            if((details->num_pieces[colour][BISHOP] > 0) ||
+                    (details->occurs[colour][BISHOP] != EXACTLY) ||
+                    (details->num_pieces[colour][KNIGHT] > 0) ||
+                    (details->occurs[colour][KNIGHT] != EXACTLY)){
+                fprintf(GlobalState.logfile,
+                    "Warning: the mixture of minor pieces in %s is not guaranteed to work.\n",
+                        line);
+                fprintf(GlobalState.logfile,
+                        "In a single set it is advisable to stick to either L or B and/or N.\n");
+            }
+        }
+      return p;
+    }
+    else{
+      return NULL;
+    }
+}
+
+static Boolean
+decompose_line(const char *line,Ending_details *details)
+{   const char *p = line;
+    Boolean Ok = TRUE;
+
+    /* Skip initial space. */
+    while(isspace((int) *p)){
+        p++;
+    }
+
+    /* Look for a move depth. */
+    if(isdigit((int) *p)){
+        unsigned depth;
+
+        depth = *p-'0';
+        p++;
+        while(isdigit((int) *p)){
+            depth = (depth*10)+(*p-'0');
+            p++;
+        }
+        while(isspace((int) *p)){
+            p++;
+        }
+        details->move_depth = depth;
+    }
+
+    /* Extract two pairs of piece information. */
+    p = extract_piece_information(p,details,WHITE);
+    if(p != NULL){
+        while((*p != '\0') && isspace((int) *p)){
+            p++;
+        }
+        if(*p != '\0'){
+            p = extract_piece_information(p,details,BLACK);
+        }
+        else{
+            /* No explicit requirements for the other colour. */
+            Piece piece;
+
+            for(piece = PAWN; piece <= KING; piece++){
+               details->num_pieces[BLACK][piece] = 0;
+               details->occurs[BLACK][piece] = NUM_OR_MORE;
+            }
+            details->num_pieces[BLACK][KING] = 1;
+            details->occurs[BLACK][KING] = EXACTLY;
+        }
+    }
+    if(p != NULL){
+        /* Allow trailing text as a comment. */
+    }
+    else{
+        Ok = FALSE;
+    }
+    return Ok;
+}
+
+        /* A new game to be looked for. Indicate that we have not
+         * started matching any yet.
+         */
+static void
+reset_match_depths(Ending_details *endings)
+{
+    for(; endings != NULL; endings = endings->next){
+        endings->match_depth[WHITE] = 0;
+        endings->match_depth[BLACK] = 0;
+    }
+}
+
+        /* Try to find a match for the given number of piece details. */
+static Boolean
+piece_match(int num_available,int num_to_find, int num_opponents, Occurs occurs)
+{   Boolean match = FALSE;
+
+    switch(occurs){
+        case EXACTLY:
+            match = num_available == num_to_find;
+            break;
+        case NUM_OR_MORE:
+            match = num_available >= num_to_find;
+            break;
+        case NUM_OR_LESS:
+            match = num_available <= num_to_find;
+            break;
+        case SAME_AS_OPPONENT:
+            match = num_available == num_opponents;
+            break;
+        case NOT_SAME_AS_OPPONENT:
+            match = num_available != num_opponents;
+            break;
+        case LESS_THAN_OPPONENT:
+            match = (num_available+num_to_find) <= num_opponents;
+            break;
+        case MORE_THAN_OPPONENT:
+            match = (num_available-num_to_find) >= num_opponents;
+            break;
+        case LESS_EQ_THAN_OPPONENT:
+            /* This means exactly num_to_find less than the
+             * opponent.
+             */
+            match = (num_available+num_to_find) == num_opponents;
+            break;
+        case MORE_EQ_THAN_OPPONENT:
+            /* This means exactly num_to_find greater than the
+             * opponent.
+             */
+            match = (num_available-num_to_find) == num_opponents;
+            break;
+        default:
+            fprintf(GlobalState.logfile,
+                "Inconsistent state %d in piece_match.\n",occurs);
+            match = FALSE;
+    }
+    return match;
+}
+
+    /* Try to find a match against one player's pieces in the piece_set_colour
+     * set of details_to_find.
+     */
+static Boolean
+piece_set_match(Ending_details *details_to_find,
+                int num_pieces[2][NUM_PIECE_VALUES],
+                Colour game_colour, Colour piece_set_colour)
+{   Boolean match = TRUE;
+    Piece piece;
+    /* Determine whether we failed on a match for minor pieces or not. */
+    Boolean minor_failure = FALSE;
+
+    /* No need to check KING. */
+    for(piece = PAWN; (piece < KING) && match; piece++){
+        int num_available = num_pieces[game_colour][piece];
+        int num_opponents = num_pieces[OPPOSITE_COLOUR(game_colour)][piece];
+        int num_to_find = details_to_find->num_pieces[piece_set_colour][piece];
+        Occurs occurs = details_to_find->occurs[piece_set_colour][piece];
+
+        match = piece_match(num_available,num_to_find,num_opponents,occurs);
+        if(!match){
+            if((piece == KNIGHT) || (piece == BISHOP)){
+                minor_failure = TRUE;
+                /* Carry on trying to match. */
+                match = TRUE;
+            }
+            else{
+                minor_failure = FALSE;
+            }
+        }
+    }
+    if(match){
+        /* Ensure that the minor pieces match if there is a minor pieces
+         * requirement.
+         */
+        int num_to_find = details_to_find->num_minor_pieces[piece_set_colour];
+        Occurs occurs = details_to_find->minor_occurs[piece_set_colour];
+
+        if((num_to_find > 0) || (occurs != EXACTLY)){
+            int num_available =
+                        num_pieces[game_colour][BISHOP]+
+                        num_pieces[game_colour][KNIGHT];
+            int num_opponents = num_pieces[OPPOSITE_COLOUR(game_colour)][BISHOP]+
+                                num_pieces[OPPOSITE_COLOUR(game_colour)][KNIGHT];
+
+            match = piece_match(num_available,num_to_find,num_opponents,occurs);
+        }
+        else if(minor_failure){
+            /* We actually failed with proper matching of individual minor
+             * pieces, and no minor match fixup is possible.
+             */
+            match = FALSE;
+        }
+        else{
+            /* Match stands. */
+        }
+    }
+    return match;
+}
+        /* Look for an ending match between current_details and
+         * details_to_find. Only return TRUE if we have both a match
+         * and match_depth >= move_depth in details_to_find.
+         */
+static Boolean
+ending_match(Ending_details *details_to_find, int num_pieces[2][NUM_PIECE_VALUES],
+        Colour game_colour)
+{   Boolean match = TRUE;
+    Colour piece_set_colour = WHITE;
+
+    match = piece_set_match(details_to_find,num_pieces,game_colour,
+                                piece_set_colour);
+    if(match){
+        game_colour = OPPOSITE_COLOUR(game_colour);
+        piece_set_colour = OPPOSITE_COLOUR(piece_set_colour);
+        match = piece_set_match(details_to_find,num_pieces,game_colour,
+                                piece_set_colour);
+        /* Reset colour to its original value. */
+        game_colour = OPPOSITE_COLOUR(game_colour);
+    }
+
+    if(match){
+        details_to_find->match_depth[game_colour]++;
+        if(details_to_find->match_depth[game_colour] < details_to_find->move_depth){
+            /* Not a full match yet. */
+            match = FALSE;
+        }
+    }
+    else{
+        /* Reset the match counter. */
+        details_to_find->match_depth[game_colour] = 0;
+    }
+    return match;
+}
+
+static Boolean
+look_for_ending(Move *moves,Ending_details *details_to_find)
+{   Boolean game_ok = TRUE;
+    Boolean game_matches = FALSE;
+    Boolean match_comment_added = FALSE;
+    Move *next_move = moves;
+    Colour colour = WHITE;
+    /* The initial game position has the full set of piece details. */
+    int num_pieces[2][NUM_PIECE_VALUES] = {
+            /* Dummies for OFF and EMPTY at the start. */
+            /*   P N B R Q K */
+            {0,0,8,2,2,2,1,1},
+            {0,0,8,2,2,2,1,1}
+    };
+    unsigned move_number = 1;
+
+    /* Ensure that all previous match indications are cleared. */
+    reset_match_depths(endings_to_match);
+    /* Keep going while the game is ok, and we have some more
+     * moves and we haven't exceeded the search depth without finding
+     * a match.
+     */
+    while(game_ok && (next_move != NULL) && !game_matches){
+        /* Try before applying each move.
+         * Note, that we wish to try both ways around because we might
+         * have WT,BT WF,BT ... If we don't try BLACK on WHITE success
+         * then we might miss a match.
+         */
+        game_matches = ending_match(details_to_find,num_pieces,WHITE) |
+                            ending_match(details_to_find,num_pieces,BLACK);
+        if(!game_matches){
+            if(*(next_move->move) != '\0'){
+               /* Remove any captured pieces. */
+               if(next_move->captured_piece != EMPTY){
+                   num_pieces[OPPOSITE_COLOUR(colour)][next_move->captured_piece]--;
+               }
+               if(next_move->promoted_piece != EMPTY){
+                   num_pieces[OPPOSITE_COLOUR(colour)][next_move->promoted_piece]++;
+                   /* Remove the promoting pawn. */
+                   num_pieces[OPPOSITE_COLOUR(colour)][PAWN]--;
+               }
+
+               colour = OPPOSITE_COLOUR(colour);
+               next_move = next_move->next;
+               if(colour == WHITE){
+                   move_number++;
+               }
+            }
+            else{
+                /* An empty move. */
+                fprintf(GlobalState.logfile,
+                            "Internal error: Empty move in look_for_ending.\n");
+                game_ok = FALSE;
+            }
+        }
+       else {
+           /* Match.
+              See whether a matching comment is required.
+            */
+           if(GlobalState.add_position_match_comments && !match_comment_added) {
+               if(next_move != NULL) {
+                   CommentList *comment = create_match_comment(next_move);
+                   append_comments_to_move(next_move, comment);
+               }
+           }
+       }
+    }
+    if(!game_ok){
+        game_matches = FALSE;
+    }
+    return game_matches;
+}
+
+Boolean
+check_for_ending(Move *moves)
+{   /* Match if there are no endings to match. */
+    Boolean matches = (endings_to_match == NULL)? TRUE : FALSE;
+    Ending_details *details;
+
+    for(details = endings_to_match; !matches && (details != NULL);
+                        details = details->next){
+        matches = look_for_ending(moves,details);
+    }
+    return matches;
+}
+
+Boolean
+process_ending_line(const char *line)
+{   Boolean Ok = TRUE;
+
+    if(non_blank_line(line)){
+        Ending_details *details = new_ending_details();
+
+        if(decompose_line(line,details)){
+            /* Add it on to the list. */
+            details->next = endings_to_match;
+            endings_to_match = details;
+        }
+        else{
+            Ok = FALSE;
+        }
+    }
+    return Ok;
+}
+
+Boolean
+build_endings(const char *infile)
+{   FILE *fp = fopen(infile,"r");
+    Boolean Ok = TRUE;
+
+    if(fp == NULL){
+        fprintf(GlobalState.logfile,"Cannot open %s for reading.\n",infile);
+        exit(1);
+    }
+    else{
+        char *line;
+        while((line = read_line(fp)) != NULL){
+            Ok &= process_ending_line(line);
+            (void) free(line);
+        }
+        (void) fclose(fp);
+    }
+    return Ok;
+}
diff --git a/end.h b/end.h
new file mode 100644 (file)
index 0000000..3751653
--- /dev/null
+++ b/end.h
@@ -0,0 +1,24 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+Boolean check_for_ending(Move *moves);
+Boolean build_endings(const char *infile);
+Boolean process_ending_line(const char *line);
diff --git a/fenmatcher.c b/fenmatcher.c
new file mode 100644 (file)
index 0000000..2258e17
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "apply.h"
+#include "fenmatcher.h"
+
+/* Character on an encoded board representing an empty square. */
+#define EMPTY_SQUARE '_'
+/* Pattern meta characters. */
+#define NON_EMPTY_SQUARE '!'
+#define ANY_SQUARE_STATE '?'
+#define ZERO_OR_MORE_OF_ANYTHING '*'
+#define ANY_WHITE_PIECE 'A'
+#define ANY_BLACK_PIECE 'a'
+
+/* Symbols for closures. */
+#define CCL_START '['
+#define CCL_END ']'
+#define NCCL '^'
+
+/**
+ * Based on original pattern matching code by Rob Pike.
+ * Taken from:
+ *     http://www.cs.princeton.edu/courses/archive/spr09/cos333/beautiful.html
+ * and ideas from Kernighan and Plauger's "Software Tools".
+ */
+
+static Boolean matchhere(const char *regexp, const char *text);
+static Boolean matchstar(const char *regexp, const char *text);
+static Boolean matchccl(const char *regexp, const char *text);
+static Boolean matchnccl(const char *regexp, const char *text);
+static Boolean matchone(char regchar, char textchar);
+static char *convert_board_to_text(const Board *board);
+
+/* The list of FEN-based patterns to match. */
+static StringList *fen_patterns = NULL;
+
+void
+add_fen_pattern(const char *fen_pattern)
+{
+    /* Check the pattern a reasonable syntax. */
+    /* Count the number of rank dividers. */
+    int dividors = 0;
+    /* Count the number of symbols in each rank - must be
+     * at least one.
+     */
+    int rankSymbols = 0;
+    Boolean ok = TRUE;
+    const char *p = fen_pattern;
+    Boolean in_closure = FALSE;
+    while(*p != '\0' && ok) {
+        if(*p == '/') {
+           dividors++;
+           if(rankSymbols == 0) {
+               /* Nothing on the previous rank. */
+               ok = FALSE;
+           }
+           rankSymbols = 0;
+       }
+       else if(*p == CCL_START) {
+           if(!in_closure) {
+               in_closure = TRUE;
+           }
+           else {
+               ok = FALSE;
+               fprintf(GlobalState.logfile,
+                       "Nested closures not allowed: %s\n",
+                       fen_pattern);
+           }
+       }
+       else if(*p == CCL_END) {
+           if(in_closure) {
+               in_closure = FALSE;
+           }
+           else {
+               ok = FALSE;
+               fprintf(GlobalState.logfile,
+                       "Missing %c to match %c: %s\n",
+                       CCL_START, CCL_END,
+                       fen_pattern);
+           }
+       }
+       else if(*p == NCCL) {
+           if(!in_closure) {
+               ok = FALSE;
+               fprintf(GlobalState.logfile,
+                       "%c not allowed outside %c...%c: %s\n",
+                       NCCL,
+                       CCL_START, CCL_END,
+                       fen_pattern);
+           }
+       }
+       else {
+           rankSymbols++;
+       }
+       p++;
+    }
+    if(dividors != 7) {
+        ok = FALSE;
+    }
+    else if(rankSymbols == 0) {
+        ok = FALSE;
+    }
+    if(ok) {
+       const char *pattern = copy_string(fen_pattern);
+       fen_patterns = save_string_list_item(fen_patterns, pattern);
+    }
+    else {
+        fprintf(GlobalState.logfile, "FEN Pattern: %s badly formed.\n",
+               fen_pattern);
+    }
+}
+
+    /*
+     * Try to match the board against one of the FEN patterns.
+     * Return the matching pattern, if there is one, otherwise NULL.
+     */
+const char *
+matchBoard(const Board *board)
+{
+    Boolean match = FALSE;
+    const char *pattern = NULL;
+    if(fen_patterns != NULL) {
+       const char *text = convert_board_to_text(board);
+
+       StringList *item = fen_patterns;
+
+       while(item != NULL && !match) {
+           if(0) printf("Try %s against %s\n", item->str, text);
+           pattern = item->str;
+           if(matchhere(pattern, text)) {
+               if(0) fprintf(stdout, "%s matches\n%s\n", pattern, text);
+               match = TRUE;
+           }
+           else {
+               item = item->next;
+           }
+       }
+       (void) free((void *) text);
+       if(match) {
+           return pattern;
+       }
+       else {
+           return (const char *) NULL;
+       }
+    }
+    else {
+        return (const char *) NULL;
+    }
+}
+
+/**
+ * matchhere: search for regexp at beginning of text
+ */
+static Boolean
+matchhere(const char *regexp, const char *text)
+{
+    if (regexp[0] == '\0' && text[0] == '\0') {
+       return TRUE;
+    }
+    if (regexp[0] == ZERO_OR_MORE_OF_ANYTHING) {
+       return matchstar(regexp+1, text);
+    }
+    if (*text !='\0') {
+        switch(*regexp) {
+           case ANY_SQUARE_STATE:
+               return matchhere(regexp+1, text+1);
+               break;
+           case NON_EMPTY_SQUARE:
+           case ANY_WHITE_PIECE:
+           case ANY_BLACK_PIECE:
+               if(matchone(*regexp, *text)) {
+                   return matchhere(regexp+1, text+1);
+               }
+               break;
+           case CCL_START:
+               /* Closure */
+               if(regexp[1] == NCCL) {
+                   return matchnccl(regexp + 2, text);
+               }
+               else {
+                   return matchccl(regexp + 1, text);
+               }
+               break;
+           case '1': case '2': case '3': case '4':
+           case '5': case '6': case '7': case '8':
+               {
+                   /* The number of empty squares required. */
+                   int empty = regexp[0] - '0';
+                   Boolean matches = TRUE;
+                   /* The number matched. */
+                   int match_count = 0;
+                   while(matches && match_count < empty) {
+                       if(text[match_count] == EMPTY_SQUARE) {
+                           match_count++;
+                       }
+                       else {
+                           matches = FALSE;
+                       }
+                   }
+                   if(matches) {
+                       return matchhere(regexp+1, text + match_count);
+                   }
+               }
+               break;
+           default:
+               if(*regexp == *text) {
+                   return matchhere(regexp+1, text+1);
+               }
+               break;
+       }
+    }
+    /* No match. */
+    return FALSE;
+}
+
+/**
+ * matchstar: leftmost longest search on a single rank.
+ */
+static Boolean
+matchstar(const char *regexp, const char *text)
+{
+    const char *t;
+
+    /* Find the end of this rank. */
+    for (t = text; *t != '\0' && *t != '/'; t++) {
+           ;
+    }
+    /* Try from the longest match to the shortest until success. */
+    do {
+       /* * matches zero or more */
+       if (matchhere(regexp, t)) {
+           return TRUE;
+       }
+    } while (t-- > text);
+    return FALSE;
+}
+
+    /*
+     * Return TRUE if regchar matches textchar, FALSE otherwise.
+     */
+static Boolean
+matchone(char regchar, char textchar)
+{
+    if(regchar == textchar) {
+        return TRUE;
+    }
+    else {
+        switch(regchar) {
+           case NON_EMPTY_SQUARE:
+               return textchar != EMPTY_SQUARE;
+           case ANY_WHITE_PIECE:
+               /* Match any white piece. */
+               switch(textchar) {
+                   case 'K':
+                   case 'Q':
+                   case 'R':
+                   case 'N':
+                   case 'B':
+                   case 'P':
+                       return TRUE;
+                   default:
+                       return FALSE;
+               }
+           case ANY_BLACK_PIECE:
+               /* Match any black piece. */
+               switch(textchar) {
+                   case 'k':
+                   case 'q':
+                   case 'r':
+                   case 'n':
+                   case 'b':
+                   case 'p':
+                       return TRUE;
+                   default:
+                       return FALSE;
+               }
+           case ANY_SQUARE_STATE:
+               return TRUE;
+           default:
+               return FALSE;
+       }
+    }
+}
+
+    /*
+     * Match any of the character closure.
+     */
+static Boolean
+matchccl(const char *regexp, const char *text)
+{
+    while(*regexp != CCL_END &&
+         !matchone(*regexp,*text) && *regexp != '\0') {
+       regexp++;
+    }
+    if(matchone(*regexp, *text)) {
+        do {
+           regexp++;
+       }
+       while(*regexp != CCL_END && *regexp != '\0');
+       return matchhere(regexp + 1, text + 1);
+    }
+    else {
+       return FALSE;
+    }
+}
+
+    /*
+     * Match any of the characters not in the closure.
+     */
+static Boolean
+matchnccl(const char *regexp, const char *text)
+{
+    while(*regexp != CCL_END &&
+         !matchone(*regexp,*text) && *regexp != '\0') {
+       regexp++;
+    }
+    if(*regexp == CCL_END) {
+       return matchhere(regexp + 1, text + 1);
+    }
+    else {
+       return FALSE;
+    }
+}
+
+
+    /* Build a basic EPD string from the given board. */
+static char *
+convert_board_to_text(const Board *board)
+{   Rank rank;
+    int ix = 0;
+    /* Allow space for a full board and '/' separators in between. */
+    char *text = (char *) MallocOrDie(8 * 8 + 8);
+    for(rank = LASTRANK; rank >= FIRSTRANK; rank--){
+        Col col;
+        for(col = FIRSTCOL; col <= LASTCOL; col++){
+            int coloured_piece = board->board[RankConvert(rank)]
+                                             [ColConvert(col)];
+            if(coloured_piece != EMPTY){
+                text[ix] = coloured_piece_to_SAN_letter(coloured_piece);
+            }
+            else{
+                text[ix] = EMPTY_SQUARE;
+            }
+           ix++;
+        }
+        if(rank != FIRSTRANK){
+            text[ix] = '/';
+           ix++;
+        }
+    }
+    text[ix]  = '\0';
+    return text;
+}
diff --git a/fenmatcher.h b/fenmatcher.h
new file mode 100644 (file)
index 0000000..d1c28d9
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+void add_fen_pattern(const char *fen_pattern);
+const char *matchBoard(const Board *board);
diff --git a/grammar.c b/grammar.c
new file mode 100644 (file)
index 0000000..0d708de
--- /dev/null
+++ b/grammar.c
@@ -0,0 +1,1004 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "lex.h"
+#include "moves.h"
+#include "map.h"
+#include "lists.h"
+#include "apply.h"
+#include "output.h"
+#include "eco.h"
+#include "end.h"
+#include "grammar.h"
+#include "hashing.h"
+
+static TokenType current_symbol = NO_TOKEN;
+
+/* Keep track of which RAV level we are at.
+ * This is used to check whether a TERMINATING_RESULT is the final one
+ * and whether NULL_MOVEs are allowed.
+ */
+static unsigned RAV_level = 0;
+
+/* Retain details of the header of a game.
+ * This comprises the Tags and any comment prefixing the
+ * moves of the game.
+ */
+static struct{
+    /* The tag values. */
+    char **Tags;
+    unsigned header_tags_length;
+    CommentList *prefix_comment;
+} GameHeader;
+
+static void ParseOptGameList(SourceFileType file_type);
+static Boolean ParseGame(Move **returned_move_list);
+Boolean ParseOptTagList(void);
+Boolean ParseTag(void);
+static Move *ParseMoveList(void);
+static Move *ParseMoveAndVariants(void);
+static Move *ParseMove(void);
+static Move *ParseMoveUnit(void);
+static CommentList *ParseOptCommentList(void);
+Boolean ParseOptMoveNumber(void);
+static StringList *ParseOptNAGList(void);
+static Variation *ParseOptVariantList(void);
+static Variation *ParseVariant(void);
+static char *ParseResult(void);
+
+static void setup_for_new_game(void);
+void free_tags(void);
+static void check_result(char **Tags,const char *terminating_result);
+static void free_comment_list(CommentList *comment_list);
+static void DealWithEcoLine(Move *move_list);
+static void DealWithGame(Move *move_list);
+static Boolean finished_processing(void);
+
+    /* Initialise the game header structure to contain
+     * space for the default number of tags.
+     * The space will have to be increased if new tags are
+     * identified in the program source.
+     */
+void
+init_game_header(void)
+{
+    unsigned i;
+    GameHeader.header_tags_length = ORIGINAL_NUMBER_OF_TAGS;
+    GameHeader.Tags = (char **) MallocOrDie(GameHeader.header_tags_length*
+                    sizeof(*GameHeader.Tags));
+    for(i = 0; i < GameHeader.header_tags_length; i++){
+        GameHeader.Tags[i] = (char *) NULL;
+    }
+}
+
+void
+increase_game_header_tags_length(unsigned new_length)
+{   unsigned i;
+
+    if(new_length <= GameHeader.header_tags_length){
+        fprintf(GlobalState.logfile,
+                "Internal error: inappropriate length %d ",new_length);
+        fprintf(GlobalState.logfile,
+                " passed to increase_game_header_tags().\n");
+        exit(1);
+    }
+    GameHeader.Tags = (char **) ReallocOrDie((void *) GameHeader.Tags,
+                                      new_length*sizeof(*GameHeader.Tags));
+    for(i = GameHeader.header_tags_length; i < new_length; i++){
+        GameHeader.Tags[i] = NULL;
+    }
+    GameHeader.header_tags_length = new_length;
+}
+
+        /* Try to open the given file. Error and exit on failure. */
+FILE *
+must_open_file(const char *filename,const char *mode)
+{   FILE *fp;
+
+    fp = fopen(filename,mode);
+    if(fp == NULL){
+        fprintf(GlobalState.logfile,"Unable to open the file: \"%s\"\n",
+                filename);
+        exit(1);
+    }
+    return fp;
+}
+
+        /* Print out on outfp the current details and
+         * terminate with a newline.
+         */
+void
+report_details(FILE *outfp)
+{
+      if(GameHeader.Tags[WHITE_TAG] != NULL){
+          fprintf(outfp,"%s - ",GameHeader.Tags[WHITE_TAG]);
+      }
+      if(GameHeader.Tags[BLACK_TAG] != NULL){
+          fprintf(outfp,"%s ",GameHeader.Tags[BLACK_TAG]);
+      }
+
+      if(GameHeader.Tags[EVENT_TAG] != NULL){
+          fprintf(outfp,"%s ",GameHeader.Tags[EVENT_TAG]);
+      }
+      if(GameHeader.Tags[SITE_TAG] != NULL){
+          fprintf(outfp,"%s ",GameHeader.Tags[SITE_TAG]);
+      }
+
+      if(GameHeader.Tags[DATE_TAG] != NULL){
+          fprintf(outfp,"%s ",GameHeader.Tags[DATE_TAG]);
+      }
+      putc('\n',outfp);
+      fflush(outfp);
+}
+
+        /* Check that terminating_result is consistent with
+         * Tags[RESULT_TAG].  If the latter is missing, fill it
+         * in from terminating_result.
+         */
+static void
+check_result(char **Tags,const char *terminating_result)
+{   char *result_tag = Tags[RESULT_TAG];
+
+    if(terminating_result != NULL){
+        if((result_tag == NULL) || (*result_tag == '\0') ||
+                    (strcmp(result_tag,"?") == 0)){
+            /* Use a copy of terminating result. */
+            result_tag = copy_string(terminating_result);
+            Tags[RESULT_TAG] = result_tag;
+        }
+        else if((result_tag != NULL) &&
+                    (strcmp(terminating_result,"*") != 0) &&
+                    (strcmp(result_tag,terminating_result) != 0)){
+            print_error_context(GlobalState.logfile);
+            fprintf(GlobalState.logfile,
+                        "Inconsistent result strings in the following game.\n");
+            report_details(GlobalState.logfile);
+        }
+        else{
+            /* Ok. */
+        }
+    }
+}
+
+        /* Select which file to write to based upon the game state.
+         * This will depend upon:
+         *        Whether the number of games per file is limited.
+         *        Whether ECO_level > DONT_DIVIDE.
+         */
+
+static FILE *
+select_output_file(StateInfo *GameState,const char *eco)
+{   
+    if(GameState->games_per_file > 0){
+        if((GameState->num_games_matched % GameState->games_per_file) == 0){
+              /* Time to open the next one. */
+              char filename[50];
+
+              if(GameState->outputfile != NULL){
+                  (void) fclose(GameState->outputfile);
+              }
+              sprintf(filename,"%u%s",
+                        GameState->next_file_number,
+                        output_file_suffix(GameState->output_format));
+              GameState->outputfile = must_open_file(filename,"w");
+              GameState->next_file_number++;
+        }
+    }
+    else if(GameState->ECO_level > DONT_DIVIDE){
+        /* Open a file of the appropriate name. */
+        if(GameState->outputfile != NULL){
+            /* @@@ In practice, this might need refinement.
+             * Repeated opening and closing may prove inefficient.
+             */
+            (void) fclose(GameState->outputfile);
+            GameState->outputfile = open_eco_output_file(
+                                GameState->ECO_level,
+                                eco);
+        }
+    }
+    else{
+    }
+    return GameState->outputfile;
+}
+
+  /*
+   * Conditions for finishing processing, other than all the input
+   * having been processed.
+   */
+static Boolean finished_processing(void)
+{
+    return (GlobalState.matching_game_number > 0 &&
+         GlobalState.num_games_matched == GlobalState.matching_game_number);
+}
+
+static void
+ParseOptGameList(SourceFileType file_type)
+{   Move *move_list = NULL;
+
+    while(ParseGame(&move_list) && !finished_processing()){
+        if(file_type == NORMALFILE){
+            DealWithGame(move_list);
+        }
+        else if(file_type == CHECKFILE){
+            DealWithGame(move_list);
+        }
+        else if(file_type == ECOFILE){
+            if(move_list != NULL){
+                DealWithEcoLine(move_list);
+            }
+            else {
+                fprintf(GlobalState.logfile,"ECO line with zero moves.\n");
+                report_details(GlobalState.logfile);
+            }
+        }
+        else{
+            /* Unknown type. */
+            free_tags();
+            free_move_list(move_list);
+        }
+        move_list = NULL;
+        setup_for_new_game();
+    }
+}
+
+        /* Parse a game and return a pointer to any valid list of moves
+         * in returned_move_list.
+         */
+static Boolean
+ParseGame(Move **returned_move_list)
+{   /* Boolean something_found = FALSE; */
+    CommentList *prefix_comment;
+    Move *move_list = NULL;
+    char *result;
+    /* There shouldn't be a hanging comment before the result,
+     * but there sometimes is.
+     */
+    CommentList *hanging_comment;
+
+    /* Assume that we won't return anything. */
+    *returned_move_list = NULL;
+    /* Skip over any junk between games. */
+    current_symbol = skip_to_next_game(current_symbol);
+    prefix_comment = ParseOptCommentList();
+    if(prefix_comment != NULL){
+        /* Free this here, as it is hard to
+         * know whether it belongs to the game or the file.
+         * It is better to put game comments after the tags.
+         */
+        /* something_found = TRUE; */
+        free_comment_list(prefix_comment);
+        prefix_comment = NULL;
+    }
+    if(ParseOptTagList()){
+        /* something_found = TRUE; */
+    }
+    /* @@@ Beware of comments and/or tags without moves. */
+    move_list = ParseMoveList();
+
+    /* @@@ Look for a comment with no move text before the result. */
+    hanging_comment = ParseOptCommentList();
+    /* Append this to the final move, if there is one. */
+
+    /* Look for a result, even if there were no moves. */
+    result = ParseResult();
+    if(move_list != NULL){
+        /* Find the last move. */
+        Move *last_move = move_list;
+
+        while(last_move->next != NULL){
+            last_move = last_move->next;
+        }
+        if(hanging_comment != NULL) {
+            append_comments_to_move(last_move,hanging_comment);
+        }
+        if(result != NULL){
+            /* Append it to the last move. */
+            last_move->terminating_result = result;
+            check_result(GameHeader.Tags,result);
+            *returned_move_list = move_list;
+        }
+        else{
+            fprintf(GlobalState.logfile,"Missing result.\n");
+            report_details(GlobalState.logfile);
+        }
+        /* something_found = TRUE; */
+    }
+    else{
+        /* @@@ Nothing to attach the comment to. */
+        (void) free((void *) hanging_comment);
+        hanging_comment = NULL;
+        /*
+         * Workaround for games with zero moves.
+         * Check the result for consistency with the tags, but then
+         * there is no move to attach it to.
+         * When outputting a game, the missing result in this case
+         * will have to be supplied from the tags.
+         */
+        check_result(GameHeader.Tags,result);
+        if(result != NULL){
+            (void) free((void *)result);
+        }
+        *returned_move_list = NULL;
+    }
+    return current_symbol != EOF_TOKEN;
+}
+
+Boolean
+ParseOptTagList(void)
+{   Boolean something_found = FALSE;
+    CommentList *prefix_comment;
+    while(ParseTag()){
+        something_found = TRUE;
+    }
+    if(something_found){
+        /* Perform any consistency checks. */
+        if((GameHeader.Tags[SETUP_TAG] != NULL) &&
+                (strcmp(GameHeader.Tags[SETUP_TAG],"1") == 0)){
+            /* There must be a FEN_TAG to go with it. */
+            if(GameHeader.Tags[FEN_TAG] == NULL){
+                 fprintf(GlobalState.logfile,
+                        "Missing %s Tag to accompany %s Tag.\n",
+                        tag_header_string(FEN_TAG),
+                        tag_header_string(SETUP_TAG));
+                print_error_context(GlobalState.logfile);
+            }
+        }
+    }
+    prefix_comment = ParseOptCommentList();
+    if(prefix_comment != NULL){
+        GameHeader.prefix_comment = prefix_comment;
+        something_found = TRUE;
+    }
+    return something_found;
+}
+
+Boolean
+ParseTag(void)
+{   Boolean TagFound = TRUE;
+
+    if(current_symbol == TAG){
+        TagName tag_index = yylval.tag_index;
+
+        current_symbol = next_token();
+        if(current_symbol == STRING){
+            char *tag_string = yylval.token_string;
+
+            if(tag_index < GameHeader.header_tags_length){
+                GameHeader.Tags[tag_index] = tag_string;
+            }
+            else{
+                print_error_context(GlobalState.logfile);
+                fprintf(GlobalState.logfile,
+                        "Internal error: Illegal tag index %d for %s\n",
+                        tag_index,tag_string);
+                exit(1);
+            }
+            current_symbol = next_token();
+        }
+        else{
+            print_error_context(GlobalState.logfile);
+            fprintf(GlobalState.logfile,"Missing tag string.\n");
+        }
+    }
+    else if(current_symbol == STRING){
+        print_error_context(GlobalState.logfile);
+        fprintf(GlobalState.logfile,"Missing tag for %s.\n",yylval.token_string);
+        (void) free((void *)yylval.token_string);
+        current_symbol = next_token();
+    }
+    else{
+        TagFound = FALSE;
+    }
+    return TagFound;
+}
+
+
+static Move *
+ParseMoveList(void)
+{   Move *head = NULL, *tail = NULL;
+
+    head = ParseMoveAndVariants();
+    if(head != NULL){
+        Move *next_move;
+
+        tail = head;
+        while((next_move = ParseMoveAndVariants()) != NULL){
+            tail->next = next_move;
+            tail = next_move;
+        }
+    }
+    return head;
+}
+
+static Move *
+ParseMoveAndVariants(void)
+{   Move *move_details;
+
+    move_details = ParseMove();
+    if(move_details != NULL){
+        CommentList *comment;
+
+        move_details->Variants = ParseOptVariantList();
+        comment = ParseOptCommentList();
+        if(comment != NULL){
+            append_comments_to_move(move_details,comment);
+        }
+    }
+    return move_details;
+}
+
+
+static Move *
+ParseMove(void)
+{   Move *move_details = NULL;
+
+    if(ParseOptMoveNumber()){
+    }
+    /* @@@ Watch out for finding just the number. */
+    move_details = ParseMoveUnit();
+    if(move_details != NULL){
+        CommentList *comment;
+
+        move_details->Nags = ParseOptNAGList();
+        comment = ParseOptCommentList();
+        if(comment != NULL){
+            append_comments_to_move(move_details,comment);
+        }
+    }
+    return move_details;
+}
+
+static Move *
+ParseMoveUnit(void)
+{   Move *move_details = NULL;
+
+    if(current_symbol == MOVE){
+        move_details = yylval.move_details;
+
+       if(move_details->class == NULL_MOVE && RAV_level == 0) {
+            print_error_context(GlobalState.logfile);
+           fprintf(GlobalState.logfile, "Null moves (--) only allowed in variations.\n");
+       }
+
+        current_symbol = next_token();
+        if(current_symbol == CHECK_SYMBOL){
+            strcat((char *) move_details->move,"+");
+            current_symbol = next_token();
+            /* Sometimes + is followed by #, so cover this case. */
+            if(current_symbol == CHECK_SYMBOL){
+                current_symbol = next_token();
+            }
+        }
+        move_details->Comment = ParseOptCommentList();
+    }
+    return move_details;
+}
+
+static CommentList *
+ParseOptCommentList(void)
+{   CommentList *head = NULL, *tail = NULL;
+
+    while(current_symbol == COMMENT){
+        if(head == NULL){
+            head = tail = yylval.comment;
+        }
+        else{
+            tail->next = yylval.comment;
+            tail = tail->next;
+        }
+        current_symbol = next_token();
+    }
+    return head;
+}
+
+Boolean
+ParseOptMoveNumber(void)
+{   Boolean something_found = FALSE;
+
+    if(current_symbol == MOVE_NUMBER){
+        current_symbol = next_token();
+        something_found = TRUE;
+    }
+    return something_found;
+}
+
+static StringList *
+ParseOptNAGList(void)
+{   StringList *nags = NULL;
+    while(current_symbol == NAG){
+        if(GlobalState.keep_NAGs){
+            nags = save_string_list_item(nags,yylval.token_string);
+        }
+        else{
+            (void) free((void *)yylval.token_string);
+        }
+        current_symbol = next_token();
+    }
+    return nags;
+}
+
+static Variation *
+ParseOptVariantList(void)
+{   Variation *head = NULL, *tail = NULL,
+        *variation;
+    while((variation = ParseVariant()) != NULL){
+        if(head == NULL){
+            head = tail = variation;
+        }
+        else{
+            tail->next = variation;
+            tail = variation;
+        }
+    }
+    return head;
+}
+
+static Variation *
+ParseVariant(void)
+{   Variation *variation = NULL;
+
+    if(current_symbol == RAV_START){
+        CommentList *prefix_comment;
+        CommentList *suffix_comment;
+        char *result = NULL;
+        Move *moves;
+
+        RAV_level++;
+        variation = MallocOrDie(sizeof(Variation));
+
+        current_symbol = next_token();
+        prefix_comment = ParseOptCommentList();
+        if(prefix_comment != NULL){
+        }
+        moves = ParseMoveList();
+        if(moves == NULL){
+            print_error_context(GlobalState.logfile);
+            fprintf(GlobalState.logfile,"Missing move list in variation.\n");
+        }
+        result = ParseResult();
+        if((result != NULL) && (moves != NULL)){
+            /* Find the last move, to which to append the terminating
+             * result.
+             */
+            Move *last_move = moves;
+            CommentList *trailing_comment;
+
+            while(last_move->next != NULL){
+                last_move = last_move->next;
+            }
+            last_move->terminating_result = result;
+            /* Accept a comment after the result, but it will
+             * be printed out preceding the result.
+             */
+            trailing_comment = ParseOptCommentList();
+            if(trailing_comment != NULL){
+                append_comments_to_move(last_move,trailing_comment);
+            }
+        }
+        else{
+            /* Ok. */
+        }
+        if(current_symbol == RAV_END){
+            RAV_level--;
+            current_symbol = next_token();
+        }
+        else{
+            fprintf(GlobalState.logfile,"Missing ')' to close variation.\n");
+        }
+        suffix_comment = ParseOptCommentList();
+        if(suffix_comment != NULL){
+        }
+        variation->prefix_comment = prefix_comment;
+        variation->suffix_comment = suffix_comment;
+        variation->moves = moves;
+        variation->next = NULL;
+    }
+    return variation;
+}
+
+static char *
+ParseResult(void)
+{   char *result = NULL;
+
+    if(current_symbol == TERMINATING_RESULT){
+        result = yylval.token_string;
+        if(RAV_level == 0){
+            /* In the interests of skipping any intervening material
+             * between games, set the lookahead to a dummy token.
+             */
+            current_symbol = NO_TOKEN;
+        }
+        else{
+            current_symbol = next_token();
+        }
+    }
+    return result;
+}
+
+static void
+setup_for_new_game(void)
+{
+    restart_lex_for_new_game();
+    RAV_level = 0;
+}
+
+        /* Discard any data held in the GameHeader.Tags structure. */
+void
+free_tags(void)
+{   unsigned tag;
+
+    for(tag = 0; tag < GameHeader.header_tags_length; tag++){
+        if(GameHeader.Tags[tag] != NULL){
+            free(GameHeader.Tags[tag]);
+            GameHeader.Tags[tag] = NULL;
+        }
+    }
+}
+
+        /* Discard data from a gathered game. */
+void
+free_string_list(StringList *list)
+{   StringList *next;
+
+    while(list != NULL){
+        next = list;
+        list = list->next;
+        if(next->str != NULL){
+            (void) free((void *)next->str);
+        }
+        (void) free((void *)next);
+    }
+}
+
+static void
+free_comment_list(CommentList *comment_list)
+{
+    while(comment_list != NULL){
+        CommentList *this_comment = comment_list;
+
+        if(comment_list->Comment != NULL){
+            free_string_list(comment_list->Comment);
+        }
+        comment_list = comment_list->next;
+        (void) free((void *)this_comment);
+    }
+}
+
+static void
+free_variation(Variation *variation)
+{   Variation *next;
+
+    while(variation != NULL){
+        next = variation;
+        variation = variation->next;
+        if(next->prefix_comment != NULL){
+            free_comment_list(next->prefix_comment);
+        }
+        if(next->suffix_comment != NULL){
+            free_comment_list(next->suffix_comment);
+        }
+        if(next->moves != NULL){
+            (void) free_move_list((void *)next->moves);
+        }
+        (void) free((void *)next);
+    }
+}
+
+void
+free_move_list(Move *move_list)
+{   Move *next;
+
+    while(move_list != NULL){
+        next = move_list;
+        move_list = move_list->next;
+        if(next->Nags != NULL){
+            free_string_list(next->Nags);
+        }
+        if(next->Comment != NULL){
+            free_comment_list(next->Comment);
+        }
+        if(next->Variants != NULL){
+            free_variation(next->Variants);
+        }
+        if(next->epd != NULL){
+            (void) free((void *)next->epd);
+        }
+        if(next->terminating_result != NULL){
+            (void) free((void *)next->terminating_result);
+        }
+        (void) free((void *)next);
+    }
+}
+
+        /* Add str onto the tail of list and
+         * return the head of the resulting list.
+         */
+StringList *
+save_string_list_item(StringList *list,const char *str)
+{
+    if(str != NULL){
+      StringList *new_item;
+
+      new_item = (StringList *)MallocOrDie(sizeof(*new_item));
+      new_item->str = str;
+      new_item->next = NULL;
+      if(list == NULL){
+          list = new_item;
+      }
+      else{
+          StringList *tail = list;
+
+          while(tail->next != NULL){
+              tail = tail->next;
+          }
+          tail->next = new_item;
+      }
+    }
+    return list;
+}
+
+        /* Append any comments in Comment onto the end of
+         * any associated with move.
+         */
+void
+append_comments_to_move(Move *move,CommentList *Comment)
+{
+    if(Comment != NULL){
+        /* Add in to the end of any already existing. */
+        if(move->Comment == NULL){
+            move->Comment = Comment;
+        }
+        else{
+            /* Add in the final comment to 
+             * the end of any existing for this move.
+             */
+            CommentList *tail = move->Comment;
+
+            while(tail->next != NULL){
+                tail = tail->next;
+            }
+            tail->next = Comment;
+        }
+    }
+}
+
+static void
+DealWithGame(Move *move_list)
+{   Game current_game;
+    /* Record whether the game has been printed or not.
+     * This is used for the case of the -n flag which catches
+     * all non-printed games.
+     */
+    Boolean game_output = FALSE;
+    /* We need a dummy argument for apply_move_list. */
+    unsigned plycount;
+
+    /* Update the count of how many games handled. */
+    GlobalState.num_games_processed++;
+
+    /* Fill in the information currently known. */
+    current_game.tags = GameHeader.Tags;
+    current_game.tags_length = GameHeader.header_tags_length;
+    current_game.prefix_comment = GameHeader.prefix_comment;
+    current_game.moves = move_list;
+    current_game.moves_checked = FALSE;
+    current_game.moves_ok = FALSE;
+    current_game.error_ply = 0;
+  
+    /* Determine whether or not this game is wanted, on the
+     * basis of the various selection criteria available.
+     */
+    
+    /*
+     * apply_move_list checks out the moves.
+     * If it returns TRUE as a match, it will also fill in the
+     *                 current_game.final_hash_value and
+     *                 current_game.cumulative_hash_value
+     * fields of current_game so that these can be used in the
+     * previous_occurance function.
+     *
+     * If there are any tag criteria, it will be easy to quickly
+     * eliminate most games without going through the length
+     * process of game matching.
+     *
+     * If ECO adding is done, the order of checking may cause
+     * a conflict here since it won't be possible to reject a game
+     * based on its ECO code unless it already has one.
+     * Therefore, Check for the ECO tag only after everything else has
+     * been checked.
+     */
+    if(CheckTagDetailsNotECO(current_game.tags,current_game.tags_length) &&
+             apply_move_list(&current_game,&plycount) && 
+             check_move_bounds(plycount) &&
+             check_textual_variations(current_game) &&
+             check_for_ending(current_game.moves) &&
+             check_for_only_checkmate(current_game.moves) &&
+             CheckECOTag(current_game.tags)){
+        /* If there is no original filename then the game is not a
+         * duplicate.
+         */
+        const char *original_filename = previous_occurance(current_game, plycount);
+
+        if((original_filename == NULL) && GlobalState.suppress_originals){
+            /* Don't output first occurrences. */
+        }
+        else if((original_filename == NULL) || !GlobalState.suppress_duplicates){
+           GlobalState.num_games_matched++;
+            if(GlobalState.check_only) {
+               // We are only checking. 
+               if(GlobalState.verbose){
+                   /* Report progress on logfile. */
+                   report_details(GlobalState.logfile);
+               }
+           }
+           else if(GlobalState.current_file_type == CHECKFILE){
+               /* We are only checking, so don't count this as a matched game. */
+               GlobalState.num_games_matched--;
+           }
+           else if(GlobalState.matching_game_number > 0 &&
+                 GlobalState.num_games_matched != GlobalState.matching_game_number) {
+               /* This is not the right matching game to be output. */
+           }
+           else {
+                /* This game is to be kept and output. */
+                FILE *outputfile = select_output_file(&GlobalState,
+                        current_game.tags[ECO_TAG]);
+
+                /* See if we wish to separate out duplicates. */
+                if((original_filename != NULL) &&
+                        (GlobalState.duplicate_file != NULL)){
+                    static const char *last_input_file = NULL;
+  
+                    outputfile = GlobalState.duplicate_file;
+                    if((last_input_file != GlobalState.current_input_file) &&
+                       (GlobalState.current_input_file != NULL)){
+                           /* Record which file this and succeeding
+                            * duplicates come from.
+                            */
+                          print_str(outputfile,"{ From: ");
+                          print_str(outputfile,
+                                      GlobalState.current_input_file);
+                          print_str(outputfile," }");
+                          terminate_line(outputfile);
+                          last_input_file = GlobalState.current_input_file;
+                    }
+                  print_str(outputfile,"{ First found in: ");
+                  print_str(outputfile,original_filename);
+                  print_str(outputfile," }");
+                  terminate_line(outputfile);
+                }
+               /* Now output what we have. */
+               output_game(current_game,outputfile);
+               game_output = TRUE;
+               if(GlobalState.verbose){
+                   /* Report progress on logfile. */
+                   report_details(GlobalState.logfile);
+               }
+           }
+        }
+    }
+    if(!game_output && (GlobalState.non_matching_file != NULL) &&
+               GlobalState.current_file_type != CHECKFILE){
+        /* The user wants to keep everything else. */
+        if(!current_game.moves_checked){
+             /* Make sure that the move text is in a reasonable state. */
+             (void) apply_move_list(&current_game,&plycount);
+        }
+        if(current_game.moves_ok || GlobalState.keep_broken_games){
+            output_game(current_game,GlobalState.non_matching_file);
+        }
+    }
+  
+    /* Game is finished with, so free everything. */
+    if(GameHeader.prefix_comment != NULL){
+        free_comment_list(GameHeader.prefix_comment);
+    }
+    /* Ensure that the GameHeader's prefix comment is NULL for
+     * the next game.
+     */
+    GameHeader.prefix_comment = NULL;
+  
+    free_tags();
+    free_move_list(current_game.moves);
+    if((GlobalState.num_games_processed % 10) == 0){
+        fprintf(stderr,"Games: %lu\r",GlobalState.num_games_processed);
+    }
+}
+
+static void
+DealWithEcoLine(Move *move_list)
+{   Game current_game;
+    /* We need to know the length of a game to store with the
+     * hash information as a sanity check.
+     */
+    unsigned number_of_half_moves;
+
+    /* Fill in the information currently known. */
+    current_game.tags = GameHeader.Tags;
+    current_game.tags_length = GameHeader.header_tags_length;
+    current_game.prefix_comment = GameHeader.prefix_comment;
+    current_game.moves = move_list;
+    current_game.moves_checked = FALSE;
+    current_game.moves_ok = FALSE;
+    current_game.error_ply = 0;
+  
+    /* apply_eco_move_list checks out the moves.
+     * It will also fill in the
+     *                 current_game.final_hash_value and
+     *                 current_game.cumulative_hash_value
+     * fields of current_game.
+     */
+    if(apply_eco_move_list(&current_game,&number_of_half_moves)){
+        if(current_game.moves_ok){
+            /* Store the ECO code in the appropriate hash location. */
+            save_eco_details(current_game,number_of_half_moves);
+        }
+    }
+  
+    /* Game is finished with, so free everything. */
+    if(GameHeader.prefix_comment != NULL){
+        free_comment_list(GameHeader.prefix_comment);
+    }
+    /* Ensure that the GameHeader's prefix comment is NULL for
+     * the next game.
+     */
+    GameHeader.prefix_comment = NULL;
+  
+    free_tags();
+    free_move_list(current_game.moves);
+}
+
+        /* If file_type == ECOFILE we are dealing with a file of ECO
+         * input rather than a normal game file.
+         */
+int
+yyparse(SourceFileType file_type)
+{
+    setup_for_new_game();
+    current_symbol = skip_to_next_game(NO_TOKEN);
+    ParseOptGameList(file_type);
+    if(current_symbol == EOF_TOKEN){
+        /* Ok -- EOF. */
+        return 0;
+    }
+    else if(finished_processing()) {
+        /* Ok -- done all we need to. */
+       return 0;
+    }
+    else{
+        fprintf(GlobalState.logfile,"End of input reached before end of file.\n");
+        return 1;
+    }
+}
+
diff --git a/grammar.h b/grammar.h
new file mode 100644 (file)
index 0000000..c60d156
--- /dev/null
+++ b/grammar.h
@@ -0,0 +1,28 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+int yyparse(SourceFileType file_type);
+void free_string_list(StringList *list);
+void init_game_header(void);
+void increase_game_header_tags_length(unsigned new_length);
+void report_details(FILE *outfp);
+void append_comments_to_move(Move *move,CommentList *Comment);
diff --git a/hashing.c b/hashing.c
new file mode 100644 (file)
index 0000000..25fc59c
--- /dev/null
+++ b/hashing.c
@@ -0,0 +1,348 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+/* For unlink() */
+#include <io.h>
+#else
+/* For unlink() */
+#include <unistd.h>
+#endif
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "lex.h"
+#include "hashing.h"
+
+                /* Routines, similar in nature to those in apply.c
+                 * to implement a duplicate hash-table lookup using
+                 * an external file, rather than malloc'd memory.
+                 * The only limit should be a file system limit.
+                 *
+                 * This version should be slightly more accurate than
+                 * the alternative because the final_ and cumulative_
+                 * hash values are both stored, rather than the XOR
+                 * of them.
+                 */
+
+/* The name of the file used.
+ * This is overwritten each time, and removed on normal
+ * program exit.
+ */
+static char VIRTUAL_FILE[] = "virtual.tmp";
+
+/* Define the size of the hash table.
+ * Size was 8191 but that seems unduly conservative these days.
+ */
+#define LOG_TABLE_SIZE 100003
+/* Define a table to hold hash values of the extracted games.
+ * This is used to enable duplicate detection.
+ */
+typedef struct{
+    /* Record the file offset of the first and last entries
+     * for an index. (head == -1) => empty.
+     */
+  long head, tail;
+} LogHeaderEntry;
+
+/* If use_virtual_hash_table */
+static LogHeaderEntry *VirtualLogTable = NULL;
+
+/* Define a table to hold hash values of the extracted games.
+ * This is used to enable duplicate detection when not using
+ * the virtual hash table.
+ */
+static HashLog **LogTable = NULL;
+
+        /* Define a type to hold hash values of interest.
+         * This is used both to aid in duplicate detection
+         * and in finding positional variations.
+         */
+typedef struct VirtualHashLog {
+    /* Store the final position hash value and
+     * the cumulative hash value for a game.
+     */
+    HashCode final_hash_value, cumulative_hash_value;
+    /* Record the file list index for the file this game was first found in. */
+    int file_number;
+    /* Record the file offset of the next element
+     * in this list. -1 => end-of-list.
+     */
+    long next;
+} VirtualHashLog;
+
+static FILE *hash_file = NULL;
+
+static const char *previous_virtual_occurance(Game game_details);
+        
+        /* Determine which table to initialise, depending
+         * on whether use_virtual_hash_table is set or not.
+         */
+void
+init_duplicate_hash_table(void)
+{  int i;
+
+   if(GlobalState.use_virtual_hash_table){
+       VirtualLogTable = (LogHeaderEntry *)
+            MallocOrDie(LOG_TABLE_SIZE*sizeof(*VirtualLogTable));
+       for(i = 0; i < LOG_TABLE_SIZE; i++){
+           VirtualLogTable[i].head = VirtualLogTable[i].tail = -1;
+       }
+       hash_file = fopen(VIRTUAL_FILE,"w+b");
+       if(hash_file == NULL){
+           fprintf(GlobalState.logfile,"Unable to open %s\n",
+                    VIRTUAL_FILE);
+       }
+    }
+    else{
+       LogTable = (HashLog**) MallocOrDie(LOG_TABLE_SIZE*sizeof(*LogTable));
+       for(i = 0; i < LOG_TABLE_SIZE; i++){
+           LogTable[i] = NULL;
+       }
+    }
+}
+
+        /* Close and remove the temporary file if in use. */
+void
+clear_duplicate_hash_table(void)
+{
+   if(GlobalState.use_virtual_hash_table){
+      if(hash_file != NULL){
+        (void) fclose(hash_file);
+        unlink(VIRTUAL_FILE);
+       hash_file = NULL;
+      }
+   }
+}
+
+        /* Retrieve a duplicate table entry from the hash file. */
+static int
+retrieve_virtual_entry(long ix,VirtualHashLog *entry)
+{
+    if(hash_file == NULL){
+        return 0;
+    }
+    else if(fseek(hash_file,ix,SEEK_SET) != 0){
+        fprintf(GlobalState.logfile,
+                        "Fseek error to %ld in retrieve_virtual_entry\n",ix);
+        return 0;
+    }
+    else if(fread((void *)entry,sizeof(*entry),1,hash_file) != 1){
+        fprintf(GlobalState.logfile,
+                        "Fread error from %ld in retrieve_virtual_entry\n",ix);
+        return 0;
+    }
+    else{
+        return 1;
+    }
+}
+
+        /* Write a duplicate table entry to the hash file. */
+static int
+write_virtual_entry(long where,const VirtualHashLog *entry)
+{
+    if(fseek(hash_file,where,SEEK_SET) != 0){
+        fprintf(GlobalState.logfile,
+                "Fseek error to %ld in write_virtual_entry\n",where);
+        return 0;
+    }
+    else if(fwrite((void *)entry,sizeof(*entry),1,hash_file) != 1){
+        fprintf(GlobalState.logfile,
+                "Fwrite error from %ld in write_virtual_entry\n",where);
+        return 0;
+    }
+    else{
+        /* Written ok. */
+        return 1;
+    }
+}
+
+        /* Return the name of the original file if it looks like we
+         * have met the moves in game_details before, otherwise return
+         * NULL.  A match is assumed to be so if both
+         * the final_ and cumulative_ hash values in game_details
+         * are already present in VirtualLogTable.
+         */
+static const char *
+previous_virtual_occurance(Game game_details)
+{   unsigned ix = game_details.final_hash_value % LOG_TABLE_SIZE;
+    VirtualHashLog entry;
+    Boolean duplicate = FALSE;
+    const char *original_filename = NULL;
+
+
+    /* Are we keeping this information? */
+    if(GlobalState.suppress_duplicates || GlobalState.suppress_originals ||
+                GlobalState.duplicate_file != NULL){
+      if(VirtualLogTable[ix].head < 0l){
+        /* First occurrence. */
+      }
+      else{
+        int keep_going =
+                retrieve_virtual_entry(VirtualLogTable[ix].head,&entry);
+
+        while(keep_going && !duplicate){
+            if((entry.final_hash_value == game_details.final_hash_value) &&
+               (entry.cumulative_hash_value == game_details.cumulative_hash_value)){
+                /* We have a match.
+                 * Determine where it first occured.
+                 */
+                original_filename = input_file_name(entry.file_number);
+                duplicate = TRUE;
+            }
+            else if(entry.next >= 0l){
+               keep_going = retrieve_virtual_entry(entry.next,&entry);
+            }
+            else{
+               keep_going = 0;
+            }
+        }
+      }
+
+      if(!duplicate){
+        /* Write an entry for it. */
+        /* Where to write the next VirtualHashLog entry. */
+        static long next_free_entry = 0l;
+
+        /* Store the XOR of the two hash values. */
+        entry.final_hash_value = game_details.final_hash_value ;
+        entry.cumulative_hash_value = game_details.cumulative_hash_value;
+        entry.file_number = current_file_number();
+        entry.next = -1l;
+
+        /* Write out these details. */
+        if(write_virtual_entry(next_free_entry,&entry)){
+            long where_written = next_free_entry;
+            /* Move on ready for next time. */
+            next_free_entry += sizeof(entry);
+
+            /* Now update the index table. */
+            if(VirtualLogTable[ix].head < 0l){
+                /* First occurrence. */
+                VirtualLogTable[ix].head =
+                        VirtualLogTable[ix].tail = where_written;
+            }
+            else{
+                VirtualHashLog tail;
+
+                if(retrieve_virtual_entry(VirtualLogTable[ix].tail,&tail)){
+                    tail.next = where_written;
+                    (void) write_virtual_entry(VirtualLogTable[ix].tail,&tail);
+                    /* Store the new tail address. */
+                    VirtualLogTable[ix].tail = where_written;
+                }
+            }
+        }
+      }
+    }
+    return original_filename;
+}
+
+        /* Return the name of the original file if it looks like we
+         * have met the moves in game_details before, otherwise return
+         * NULL.
+        * For non-fuzzy comparision, a match is assumed to be so if both
+         * final_ and cumulative_ hash values are already present 
+        * as a pair in LogTable.
+        * Fuzzy matches depend on the match depth and do not use the
+        * cumulative hash value.
+         */
+const char *
+previous_occurance(Game game_details, int plycount)
+{
+  const char *original_filename = NULL;
+  if(GlobalState.use_virtual_hash_table){
+    original_filename = previous_virtual_occurance(game_details);
+  }
+  else{
+    unsigned ix = game_details.final_hash_value % LOG_TABLE_SIZE;
+    HashLog *entry = NULL;
+    Boolean duplicate = FALSE;
+
+    /* Are we keeping this information? */
+    if(GlobalState.suppress_duplicates || GlobalState.suppress_originals ||
+               GlobalState.fuzzy_match_duplicates ||
+                GlobalState.duplicate_file != NULL){
+        for(entry = LogTable[ix]; !duplicate && (entry != NULL);
+                                        entry = entry->next){
+            if(entry->final_hash_value == game_details.final_hash_value &&
+               entry->cumulative_hash_value == game_details.cumulative_hash_value){
+                   /* An exact match. */
+                   duplicate = TRUE;
+           }
+           else if(GlobalState.fuzzy_match_duplicates) {
+               if(GlobalState.fuzzy_match_depth == 0 &&
+                   entry->final_hash_value == game_details.final_hash_value) {
+                   /* Accept positional match at the end of the game. */
+                   duplicate = TRUE;
+               }
+               else {
+                   /* Need to check at the fuzzy_match_depth. */
+                   if(entry->final_hash_value == game_details.fuzzy_duplicate_hash) {
+                       duplicate = TRUE;
+                   }
+               }
+           }
+           if(duplicate) {
+               /* We have a match.
+                * Determine where it first occured.
+                */
+               original_filename = input_file_name(entry->file_number);
+           }
+        }
+
+        if(!duplicate){
+            /* First occurrence, so add it to the log. */
+            entry = (HashLog *) MallocOrDie(sizeof(*entry));
+
+           if(!GlobalState.fuzzy_match_duplicates) {
+               /* Store the two hash values. */
+               entry->final_hash_value = game_details.final_hash_value;
+               entry->cumulative_hash_value = game_details.cumulative_hash_value;
+           }
+           else if(GlobalState.fuzzy_match_depth > 0 && 
+                       plycount >= GlobalState.fuzzy_match_depth) {
+               /* Store just the hash value from the fuzzy depth. */
+               entry->final_hash_value = game_details.fuzzy_duplicate_hash;
+               entry->cumulative_hash_value = 0;
+           }
+           else {
+               /* Store the two hash values. */
+               entry->final_hash_value = game_details.final_hash_value;
+               entry->cumulative_hash_value = game_details.cumulative_hash_value;
+           }
+            entry->file_number = current_file_number();
+            /* Link it into the head at this index. */
+            entry->next =  LogTable[ix];
+            LogTable[ix] = entry;
+        }
+    }
+  }
+  return original_filename;
+}
diff --git a/hashing.h b/hashing.h
new file mode 100644 (file)
index 0000000..f50adc2
--- /dev/null
+++ b/hashing.h
@@ -0,0 +1,40 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+        /* Define a type to hold hash values of interest.
+         * This is used both to aid in duplicate detection
+         * and in finding positional variations.
+         */
+typedef struct HashLog {
+    /* Store both the final position hash value and
+     * the cumulative hash value for a game.
+     */
+    HashCode final_hash_value;
+    HashCode cumulative_hash_value;
+    /* Record the file list index for the file this game was first found in. */
+    unsigned file_number;
+    struct HashLog *next;
+} HashLog;
+
+void init_duplicate_hash_table(void);
+void clear_duplicate_hash_table(void);
+const char *previous_occurance(Game game_details, int plycount);
diff --git a/help.html b/help.html
new file mode 100644 (file)
index 0000000..4ee33d6
--- /dev/null
+++ b/help.html
@@ -0,0 +1,2021 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+    <title>pgn-extract: a Portable Game Notation (PGN) manipulator</title>
+    <link rel="author" href="mailto:d.j.barnes@kent.ac.uk">
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <meta name="Author" content="David J. Barnes">
+    <meta name="Description" content="Usage description for pgn-extract">
+    <meta name="Keywords"
+         content="PGN format process remove duplicates
+                  Portable Game Notation chess">
+        <link href="style.css" rel="stylesheet" type="text/css" media="all">
+</head>
+<body>
+<div id="body">
+
+<div id="banner-wrapper">
+  <div id="banner">
+<h1>pgn-extract:<br />
+A Portable Game Notation (PGN) Manipulator for Chess Games<br />
+Version 17-19 by
+<a href="http://www.cs.kent.ac.uk/~djb/">David J. Barnes</a></h1>
+  </div>
+</div>
+
+<div id="page-wrapper">
+    <div id="page">
+<h2>Overview</h2>
+<p>This page documents the free, open-source program <a href="http://www.cs.kent.ac.uk/~djb/pgn-extract">pgn-extract</a>, which is designed
+to support the processing, searching and extraction of chess games from files
+written in PGN format.
+There are several ways to specify the criteria on
+which to extract: textual move sequences, the position reached after a
+sequence of moves, information in the tag fields, and material balance
+in the ending.
+Full ANSI C source and a 32-bit Windows binary for the program are available
+under the terms of the <a href="#license">GNU General Public License</a>.
+The program includes a semantic analyser which will
+report errors in game scores and it is also able to detect duplicate
+games found in one or more of its input files.
+
+<p>The range of input move formats accepted is fairly wide and includes
+recognition of lower-case piece letters for English and upper-case
+piece letters for Dutch and German.
+The default output is in English Standard
+Algebraic Notation (SAN), although there is some support for output
+in different notations.
+
+<p>Extracted games may be written out either including or excluding
+comments, NAGs, and variations. Games may be given ECO classifications
+derived from the accompanying file eco.pgn, or a customised version
+provided by the user.
+
+<p>Plus, lots of other useful features that have gradually found their
+way into what was once a relatively simple program!
+
+<h2>Index</h2>
+<ul>
+    <li><a href="#flag-summary">Flag/Command-line Argument Summary</a>
+    <li><a href="#usage">Usage and Flags/Command-line Arguments</a>
+    <li><a href="#input">Game Input Format</a>
+    <li><a href="#-W">Output Format and Language (-W)</a>
+    <li>Files:
+       <ul>
+       <li><a href="#output">Output Files (-o, --output, -a, --append)</a>
+       <li><a href="#separate-output">Separate Output Files (-#, -E)</a>
+       <li><a href="#-l">Log files (-l, -L)</a>
+       <li><a href="#-f">File of PGN Files (-f)</a>
+       <li><a href="#-A">Storing argument Descriptions in a File (-A)</a>
+       </ul>
+    <li><a href="#-r">Check for Errors (-r)</a>
+    <li>Match criteria:
+       <ul>
+       <li><a href="#variations">Variation criteria</a>:
+           <ul>
+               <li><a href="#-x">Positional Variations (-x)</a>
+               <li><a href="#-v">Textual Variations (-v)</a>
+               <li><a href="#-P">Textual Variation Permutations (-P)</a>
+           </ul>
+       <li><a href="#-t">Tag Criteria (-t and -T)</a>
+           <ul>
+           <li><a href="#fen-t">FEN positional matches with -t</a>
+           <li><a href="#date-t">Date and Elo Matches with -t</a>
+           <li><a href="#-T">Tag Criteria on the Command Line (-T)</a>
+           <li><a href="#date-T">Date Matches with -T</a>
+           </ul>
+       <li><a href="#-b">Setting bounds on the number of moves in a game (-b)</a>
+       <li><a href="#-M">Matching only games that end in checkmate
+           (-M or --checkmate)</a>
+       <li><a href="#stalemate">Matching only games that end in stalemate
+           (--stalemate)</a>
+       <li><a href="#underpromotion">Matching only games that contain an
+       underpromotion (--underpromotion)</a>
+       <li><a href="#-S">Soundex Matching (-S)</a>
+       <li><a href="#-z">Material Matches (-z)</a>
+       </ul>
+    <li>Duplicate detection:
+    <ul>
+       <li><a href="#duplicates">Duplicate Games (-d, --duplicates and -D or --noduplicates, plus -Z)</a>
+       <li><a href="#fuzzydepth">Positional Duplicates Match
+       (--fuzzydepth)</a>
+       <li><a href="#-U">Suppression of Unique Games (-U or --nounique)</a>
+       <li><a href="#-c">Check Files for Duplicates (-c, --checkfile)</a>
+    </ul>
+    <li>Suppressing elements in the output:
+      <ul>
+       <li><a href="#suppress">Suppress annotations in the output (-C -N -V)</a>
+       <li><a href="#nomovenumbers">Suppressing move numbers (--nomovenumbers)</a>
+       <li><a href="#noresults">Suppressing results (--noresults)</a>
+       <li><a href="#notags">Suppressing Tags (--notags)</a>
+       <li><a href="#plylimit">Limiting the number of plies output (--plylimit)</a>
+      </ul>
+    <li>Tags:
+      <ul>
+       <li><a href="#-e">ECO Classification (-e)</a>
+       <li><a href="#-7">The Seven Tag Roster (-7 or --seven)</a>
+       <li><a href="#-R">User-defined Tag Roster Ordering (-R)</a>
+       <li><a href="#addhashcode">Add a Tag containing a hashcode for the game (--addhashcode)</a>
+       <li><a href="#totalplycount">Add a Tag containing the total ply count (--totalplycount)</a>
+      </ul>
+    <li>Adding annotations to games:
+      <ul>
+       <li><a href="#addhashcode">Add a Tag containing a hashcode for the game (--addhashcode)</a>
+       <li><a href="#evaluation">Include a position evaluation after each move
+                   (--evaluation)</a>
+       <li><a href="#-F">Forsyth-Edwards Notation (FEN) description of the final position (-F)</a>
+       <li><a href="#fencomments">Include a FEN comment after each move
+                   (--fencomments)</a>
+       <li><a href="#markmatches">Add a game comment for positional
+       and material matches (--markmatches)</a>
+       <li><a href="#totalplycount">Add a Tag containing the total ply count (--totalplycount)</a>
+      </ul>
+    <li><a href="#-n">Outputting Games not matched (-n)</a>
+    <li><a href="#--selectonly">Outputting a single matched game (--selectonly)</a>
+    <li><a href="#-w">Output Line Length (-w or --linelength)</a>
+    <li><a href="#keepbroken">Retain games with errors in them (--keepbroken)</a>
+
+    <li>Documentation:
+      <ul>
+       <li><a href="#mailing">Mailing List</a>
+       <li><a href="#limitations">Limitations</a>
+       <li><a href="#files">The Files</a>
+       <li><a href="#portability">Portability</a>
+       <li><a href="#acknowledgements">Acknowledgements</a>
+       <li><a href="#license">License</a>
+       <li><a href="#history">A History of Changes to the Original Release</a>
+      </ul>
+</ul>
+
+<h2 id="flag-summary">Flag/Command-line Argument Summary</h2>
+<p>There follows a brief summary of the different flags taken by pgn-extract, such
+as is produced by the -h flag.
+However, you are strongly advised to read the remainder
+of this file before attempting to use pgn-extract in earnest.
+<ul>
+      <li>-7 - output only the seven tag roster for each game. Other tags (apart
+            from FEN and possibly ECO/Opening/Variation) are discarded
+           (See <a href="#-e">-e</a>).
+      <li>-aoutputfile - the file to which extracted games are to be appended.
+            See <a href="#output">-o</a> flag for overwriting an existing file.
+      <li>-Aargsfile - read the program's arguments from argsfile.
+      <li>-b[elu]num - restricted bounds on the number of moves in a game.
+          <ul>
+               <li>lnum set a lower bound of 'num' moves,
+               <li>unum set an upper bound of 'num' moves,
+               <li>otherwise num (or enum) means equal-to 'num' moves.
+          </ul>
+      <li>-cfile[.pgn] - Use file as a list of check files for duplicates.
+      <li>-C - don't include comments in the output. Ordinarily these are retained.
+      <li>-dduplicatefile - the file to which duplicate extracted games are
+            to be written.
+      <li>-D - don't output duplicate extracted game scores.
+      <li>-eECO_file - perform ECO classification of games. The optional
+            ECO_file should contain a PGN format list of ECO lines
+            Default is to use eco.pgn from the current directory.
+      <li>-E[123 etc.] - split output into separate files according to ECO.
+        <ul>
+            <li>E1 : Produce files from ECO letter, A.pgn, B.pgn, ...
+            <li>E2 : Produce files from ECO letter and first digit, A0.pgn, ...
+            <li>E3 : Produce files from full ECO code, A00.pgn, A01.pgn, ...
+            <li>Further digits may be used to produce non-standard further
+            refined division of games.
+        </ul>
+        All files are opened in append mode.
+      <li>-ffile_list  - file_list contains the list of PGN files to be
+            searched - one per line (see <a href="#-f">-f</a>).
+      <li>-F - output a FEN string comment of the final game position.
+      <li>-h - print a list of command-line options.
+      <li>-? - same as --help.
+      <li>-llogfile  - Create a new logfile for the diagnostics rather than
+                    using stderr (see <a href="#-l">-l</a>).
+      <li>-Llogfile  - Append all diagnostics to logfile (see <a href="#-l">-l</a>).
+      <li>-M - Match only games which end in checkmate.
+      <li>-noutputfile - Write all valid games not otherwise output to outputfile.
+      <li>-N - don't include NAGs in the output. Ordinarily these are retained.
+      <li>-ooutputfile - the file to which extracted games are to be written.
+            Any existing contents of the file are lost (see <a href="#output">-a</a> flag).
+      <li>-P - don't match permutations of the textual variations (<a href="#-v">-v</a>).
+      <li>-r - report any errors but don't extract (<a href="#-r">-r</a>).
+      <li>-Rtagorder - Use the tag ordering specified in the file tagorder.
+      <li>-s - silent mode don't report each game as it is extracted.
+      <li>-S - Use a simple soundex algorithm for tag matches. If used, this
+            option must precede the -t or -T options.
+      <li>-ttagfile - file of player, date, result, or FEN extraction criteria.
+      <li>-Tcriterion - player, date, eco code, hashcode, annotator or result, extraction criteria.
+      <li>-U - don't output games that only occur once. (Use with -d to
+            identify duplicates in multiple files.)
+      <li>-vvariations - the file variations contains the textual lines of interest.
+      <li>-V - don't include variations in the output. Ordinarily these are retained.
+      <li>-wwidth - set width as an approximate line width for output.
+      <li>-W - don't rewrite the moves into Standard Algebraic Notation.
+      <li>-W[cm|epd|halg|lalg|elalg|san|uci] - specify the output format to use.
+        <ul>
+             <li>Default (i.e., without this flag) is SAN.
+             <li>-W (without anything following) selects the input format.
+             I don't know if the output produced is still valid.
+            <li>-Wepd is EPD format.
+             <li>-Whalg is hyphenated long algebraic.
+             <li>-Wlalg is long algebraic
+             <li>-Welalg[PNBRQK] is enhanced long algebraic. Use the characters
+            PNBRQK for language specific output, e.g: -WelalgBSLTDK for German.
+             <li>-Wsan[PNBRQK] Use the characters PNBRQK for language
+             specific output, e.g: -WsanBSLTDK for German.
+            <li>-Wuci is output compatible with the UCI protocol.
+             <li>-Wcm is a legacy option that output ChessMaster format.
+        </ul>
+      <li>-xvariations - the file variations contains the lines resulting in
+             positions of interest.
+      <li>-zendings - the file endings contains the end positions of interest.
+      <li>-Z - use the file virtual.tmp as an external hash table for duplicates.
+            Use when MallocOrDie messages occur with big datasets.
+      <li>-#num - output num games per file, to files named 1.pgn, 2.pgn, etc.
+      <li>--addhashcode - output a HashCode tag.
+      <li>--append - append matched games to an existing output file
+            (see <a href="#output">-a</a>).
+      <li>--checkfile - Use file as a list of check files for duplicates
+           (see <a href="#-c">-c</a>).
+      <li>--checkmate - only output games that end in checkmate
+      <li>--duplicates - file to write duplicate games to
+            (see <a href="#duplicates">-a</a>).
+      <li>--evaluation - include a position evaluation after each move.
+      <li>--fencomments - include a position evaluation after each move.
+      <li>--fuzzydepth plies - positional duplicates match.
+      <li>--help - see <a href="#-h">-h</a>
+      <li>--keepbroken - retain games with errors.
+      <li>--linelength - see <a href="#-w">-w</a>
+      <li>--markmatches comment - mark positional and material matches with
+      the given comment.
+      see <a href="#fen-t">-t</a>, <a href="-x">-x</a>
+      <li>--nochecks - don't output + and # after moves.
+      <li>--nocomments - see <a href="#-C">-C</a>
+      <li>--noduplicates - see <a href="#-D">-D</a>
+      <li>--nomovenumbers - don't output move numbers.
+      <li>--nonags - see <a href="#-N">-N</a>
+      <li>--noresults - don't output results.
+      <li>--notags - don't output any tags.
+      <li>--nounique - see <a href="#-U">-U</a>
+      <li>--output - write matched games to an output file
+            (see <a href="#output">-a</a>).
+      <li>--plylimit - limit the number of plies output.
+      <li>--seven - see <a href="#-7">-7</a>
+      <li>--selectonly N - only output the Nth matched game (N > 0)
+      <li>--stalemate - only output games that end in stalemate.
+      <li>--totalplycount - include a tag with the total number of plies in a game.
+      <li>--version - print current version number and exit.
+</ul>
+
+<h2 id="usage">Usage and Flags/Command-line Arguments</h2>
+<p>pgn-extract takes an arbitrary number of game scores as input and outputs
+zero or more of these games, typically in English Standard Algebraic
+Notation (SAN). Which of the input games are output, and the style
+of the output, depend upon the particular set of command line flags
+passed to pgn-extract.
+The general form for calling pgn-extract is as follows:
+<pre>
+pgn-extract [flags] [input-game-files]
+</pre>
+
+<p>In its simplest form, calling pgn-extract with no arguments will cause
+it to read games from its standard input, check them and reproduce those
+without errors in SAN notation on its standard output.
+
+<h2 id="input">Game Input Format</h2>
+<p>This program's principle aim is to be able to read PGN files and output
+games of interest. It follows that the input should look reasonably like PGN to
+start with.  This means that it doesn't cope well with files that
+contain news article or mail headers, for instance, although it does
+make an attempt to skip text that is obviously not game related between
+games.  Having said that, it does not require the move text be in
+Standard Algebraic Notation (SAN).  It will accept quite a few common
+formats including:
+<ul>
+    <li>Algebraic
+    <li>Long Algebraic
+    <li>various commonly-used intervening characters, such as : - x
+    <li>Dutch and German upper case piece letters.
+    (Support for Russian piece letters is in prototype.)
+    <li> lower-case English piece characters (except that it will always prefer
+    'b' to mean a pawn move rather than a Bishop move).
+</ul>
+<p>It does not
+require that there be any move numbers or PGN headers preceding a game,
+as long as the move text is terminated by a valid result designation:
+*, 1-0, 0-1, 1/2-1/2 (1/2 is also accepted).
+This makes the program reasonably suitable for entering raw game text and
+having it reformatted in proper SAN with a full set of headers.
+
+<h2 id="-f">File of PGN files (-f)</h2>
+<p>Normally, the input files from which games are to be extracted are listed on the
+command line:
+<pre>
+pgn-extract file1.pgn [file2.pgn ...]
+</pre>
+
+<p>An alternative to listing the game files on the command line is to list
+their names, one per line, in a file which is then given after the -f flag:
+<pre>
+pgn-extract -ffile_list
+</pre>
+
+<p>In order to save the output in a file rather than standard output,
+use <a href="#output">-o, --output, -a, --append</a> to indicate the output
+file name, for instance:
+<pre>
+pgn-extract -oall.pgn file1.pgn file2.pgn file3.pgn
+pgn-extract --output all.pgn file1.pgn file2.pgn file3.pgn
+</pre>
+
+<p>While pgn-extract can be used simply to check and reformat all the input games,
+it is more usual to use it to select subsets of the input games.
+Several different criteria are available on
+which to extract: <a href="#variations">move variations</a>,
+<a href="#-t">information in the tag fields</a>, and
+<a href="#-z">material balance
+in the ending</a>, for instance.
+All of these criteria are described in detail below.
+
+<h2 id="output">Output Files (-o, --output, -a, --append)</h2>
+<p>In order to output all matched games to a single new file, the -o flag is used:
+<pre>
+pgn-extract -onew.pgn file1.pgn file2.pgn
+</pre>
+<p>This has the effect of creating new.pgn from the contents of file1.pgn
+and file2.pgn.
+The games
+in both source files are checked and rewritten, if necessary, into SAN.
+Any previous contents of new.pgn will be lost with the -o flag. In order to
+avoid this and append to an existing file, use the -a flag:
+<pre>
+pgn-extract -anew.pgn file1.pgn file2.pgn
+</pre>
+<p>Note that there must be no space between either -o or -a and the output file name.
+
+<p>The long-form --output and --append are provided as alternatives to -o and -a,
+respectively. In these cases, there must be a space between the
+flag and the output filename. For instance:
+<pre>
+pgn-extract --output new.pgn file1.pgn file2.pgn
+pgn-extract --append new.pgn file1.pgn file2.pgn
+</pre>
+
+<h2 id="-r">Check for Errors (-r)</h2>
+<p>Check the input files for errors but do not output any matched games.
+Useful for cleaning up files of games before proper processing.
+<pre>
+pgn-extract -r file.pgn
+</pre>
+<p>Useful with -s (silent mode) for checking a big file of games without
+having progress reported and just seeing the errors.
+
+<h2 id="keepbroken">Retaining games with errors</h2>
+<p>Normally, pgn-extract reports games with errors but does not output them.
+Games with errors may be output with the --keepbroken argument.
+The errors are still reported by the
+moves from the point where the error was detected onwards are placed in a comment rather
+than being retained as part of the game.
+
+<h2 id="-l">Log files (-l, -L)</h2>
+<p>Error messages and verbose reporting is done to the standard error
+output unless the -l or -L flag is used.
+Both are immediately followed by the name of a file to which a log
+should be written.
+The -l flag creates a new log file, while -L appends to an existing log file:
+<pre>
+pgn-extract -llog.txt file.pgn
+pgn-extract -Llog.txt file.pgn
+</pre>
+<p>This option is useful in combination with <a href="#-r">-r</a> (report)
+to generate diagnostic information without outputting games while game
+data is being checked and cleaned.
+<p>A log file will contain only error reports if the <a href="#-s"">-s</a> 
+(silent) flag is used.
+
+<h2 id="variations">Variations (-v, -x and -P)</h2>
+<p>There are two distinct ways to specify variations of interest;
+positional variations (the <a href="#-x">the -x</a> flag) and
+textual variations (the <a href="#-v">-v</a> flag).
+The major difference between the two is that positional variations
+specify a complete move sequence whose end position is the primary
+point of interest, whereas textual variations allow incomplete and
+fuzzy move sequence matches on the text of a game to select games.
+Whilst it is possible to use both
+flags together, this would be unusual as a game must match with both to
+be extracted.
+
+<ul>
+<li id="-x"><p>Positional Variations (-x)<br />
+<p>The variations in which you are interested should be placed in a file
+whose name is supplied with the -x flag. For instance:
+<pre>
+pgn-extract -xvars
+</pre>
+<p>where each variation is
+listed on a single line in the file vars (the filename is immaterial).
+The following set of moves:
+<pre>
+e4 c5 Nf3 d6 d4 cxd4 Nxd4 Nf6 Nc3 a6
+</pre>
+<p>indicates that you wish to pick up all games reaching the Najdorf
+variation position of the Sicilian Defence.
+Games reaching the end position of this sequence are
+selected regardless of the route that was taken to reach it.  This
+allows various transpositional sequences to be specified by quoting
+just one line to reach the required point.  Therefore, games employing
+the following move order will be picked up by quoting the line above.
+<pre>
+e4 c5 Nc3 d6 Nge2 Nf6 d4 cxd4 Nxd4 a6
+</pre>
+<p>A position is considered to match a required variation if it generates
+the same board hash value. In the interests of reasonable efficiency,
+no attempt is made to actually examine the state
+of the board. There is, therefore, the potential for false hits but in
+my usage of pgn-extract I have not found this to be a problem.
+
+<p>With this option, games are only searched to a depth approximately equal
+to the length of the longest positional variation, in order to make
+processing of large data sets faster than with a search of the whole
+game.
+
+<p>A comment line may be placed in a variation file by using a '%' as the
+first character of the line. Move numbers are optional within the
+list of moves.
+
+<p>Positional matches are also available using a FEN description of the
+desired position.
+See the description of the <a href="#-t">-t flag</a>
+for how to specify a FEN position,
+and <a href="#-F">the -F flag</a>
+for a simple way to generate a FEN description from
+a game score.
+
+<li id="-v"><p>Textual Variations (-v) <br />
+<p>With this option, the matching is purely textual in nature,
+in contrast to the <a href="#-x">-x</a> flag.  The -v flag works by
+string matching on the input text of moves,
+so there is no facility for picking up transpositions automatically.
+The variations in which you are interested should be placed in a file
+whose name is supplied with the -v flag. For instance:
+<pre>
+pgn-extract -vvars
+</pre>
+<p>Each variation should be listed on a single line
+in the file vars (the filename is immaterial).
+The move sequence:
+<pre>
+e4 c5 Nf3 d6 d4 cxd4 Nxd4 Nf6 Nc3 a6
+</pre>
+<p>indicates that you wish to pick up all games following the normal move
+order of the Najdorf variation of the Sicilian Defence, and
+<pre>
+d4 Nf6 c4 e6 Nc3 Bb4
+</pre>
+<p>that you are interested in Nimzo-Indian games.
+The order in which the moves are played by either White or Black
+is immaterial. All combinations are tried, so the ordering:
+<pre>
+c4 e6 Nc3 Bb4 d4 Nf6
+</pre>
+<p>will produce the same set of matches as the previous ordering of the
+Nimzo-Indian moves (see <a href="#-P">the -P flag</a> for how
+to prevent this).
+
+<p>A comment line may be placed in a variation file by using a '%' as the
+first character of the line. Move numbers are optional within the
+list of moves.
+
+<p>As transpositions are not picked up automatically with this flag,
+if you also wanted to
+recognise the following as a Najdorf, you would have to add this line
+to the variations file in addition to that given above:
+<pre>
+e4 c5 Nc3 d6 Nge2 Nf6 d4 cxd4 Nxd4 a6
+</pre>
+<p>However, because of the way in which the matching is done, it is
+possible to specify slight alternatives on the way in which individual
+moves are written.  Notational alternatives for a single move are just
+written separated from each other with a non-move character.  This
+variation specifies both the shorter and longer ways of writing the
+captures in a Najdorf:
+<pre>
+e4 c5 Nf3 d6 d4 cxd4|cd Nxd4|Nd4 Nf6 Nc3 a6
+</pre>
+<p>However, given the variety of possible ways of writing various moves in
+non-SAN format, e.g.
+<pre>
+cxd4|cd|c5d4|c5-d4
+</pre>
+<p>variation lists can get quite messy and I believe that this approach is
+best avoided by ensuring that the input is proper SAN and only using
+SAN notation in the variations file. In this way, the alternative-separator
+can then be used purely for indicating genuine alternative moves at
+that point, e.g.
+<pre>
+e4 c5 Nf3 d6 d4|d3
+</pre>
+<p>An important point when listing moves is that check and mate indicators
+should be included where appropriate, otherwise moves incorporating
+these characters in games to be searched will fail to match.
+
+<p>There is little point in using the -v flag in preference to
+the <a href="#-x">-x</a> flag
+if you are only interested in finding games that reach a particular
+position.  The real use for -v is when you wish to pick up games
+in a more general way.  For instance, the character '*' may be used in
+place of any move to indicate that you don't care what was played at
+that point.  So the following:
+<pre>
+* b6
+</pre>
+<p>means that you are interested in all games in which Black replied
+1 ... b6 regardless of White's first move.
+The sequence:
+<pre>
+d4 * c4 * Nc3 *
+</pre>
+<p>will pick up Nimzo-Indian, Grunfeld, King's Indian, etc. defences.
+This notation is not possible with <a href="#-x">positional variations</a>.
+
+<p>In addition, the character '!' may be used in front of any move to
+indicate that you wish to disallow particular moves from matching at
+this point.  For instance, if you want to find Sicilian games where
+White did not reply with Nf3 at move 2 you would specify:
+<pre>
+e4 c5 !Nf3
+</pre>
+<p>If you wished to disallow 2.Ne2 as well then
+<pre>
+e4 c5 !Nf3|Ne2
+</pre>
+<p>does the job.  (Adding parentheses makes no difference as the '!' is
+applied to all of the following move string.)
+
+<p>Care should be taken combining '!', '*' and variation permutations (see <a
+href="#-P">the -P flag</a>).
+Disallowed moves take precedence over '*' moves.  If a single
+disallowed move is found in a game within the length of the variation,
+that game is excluded.  This was the most sensible interpretation that
+I could find to place on this usage.
+
+<li id="-P"><p>Textual Variation Permutations (-P)<br />
+<p>Normally, all permutations of a textual variation (see <a href=
+"#-v">the -v flag</a>) are tried against the
+moves of a game.  This cuts down on the number of separate
+transpositional orderings that it is necessary to list, at the cost of
+slower matching of each game.  If the following were used to look for
+Nimzo-Indian games:
+<pre>
+d4 Nf6 c4 e6 Nf6 Nc3 Bb4
+</pre>
+<p>a side-effect would be that it will also pick up games which start as:
+<pre>
+1. c4 Nf6 2. Nc3 e6 3. d4 Bb4
+</pre>
+<p>for instance.
+The -P flag requests that textual variations are matched against the
+moves of the game strictly in the order in which they are listed,
+without trying different orders.  So, if you want to find only those
+games that follow a particular move order, use this flag to suppress
+permutations.
+</ul>
+
+<h2 id="duplicates" id="-d" id="-D">Duplicate Games (-d, --duplicates and -D or --noduplicates, plus -Z)</h2>
+<p>If either the -d, --duplicates or -D flag is used, pgn-extract
+attempts to recognise duplicate extracted games.
+Using the -d or --duplicates flag indicates that you wish copies of the
+duplicate
+games to be written to the indicated file:
+<pre>
+pgn-extract -ddupes.pgn -ounique.pgn file.pgn
+pgn-extract --duplicates dupes.pgn --output unique.pgn file.pgn
+</pre>
+<p>will both extract from file.pgn the unique set of games into unique.pgn and
+the duplicates (i.e., the second and subsequent copies of a game)
+to dupes.pgn.
+A comment identifying in which file a
+duplicate was found precedes the first duplicate found in that file and
+each duplicate game has a prefix comment indicating the file in which
+the first version was found.
+Note that there must be no space between <code>-d</code> and the filename
+but a space between if <code>--duplicates</code> is used.
+
+<p>With the -D flag duplicate games are suppressed
+from the output. These two flags are mutually exclusive, therefore.
+
+<p>Duplicates are identified by comparing a hash value for the board of
+the end positions of extracted games and an additional cumulative hash
+value generated from the move sequence.
+If these both values match then games are considered to be
+duplicates.
+This is not guaranteed to be exact but it gives a good approximation.
+If the position is important but the move sequence is not then use
+<a href="#fuzzydepth">--fuzzydepth</a>.
+
+<p>You should note that games are only considered to be duplicates on the
+basis of the moves played.  It may be that a game considered to be a
+duplicate contains annotations and variations not present in the one
+found earlier, so it might be necessary to do some swapping around to
+obtain those you really wish to retain. You should, therefore, use the
+-D flag with caution if you are trying to reorganise your master
+collection rather than selecting out specific games for examination.
+(See also <a href="#-U">the -U flag</a>.)
+
+<p>Detecting duplicates requires memory for the storage of a hash table
+containing information on each game.
+Large databases can result in a MallocOrDie error.
+If this is the case, try using the -Z flag which
+forces pgn-extract to store its hash table externally, in a file called
+virtual.tmp. Each game requires 16 bytes of file space. Clearly, if a
+very large database is being processed, there is a risk of filling up
+the available file space if there is insufficient available.
+
+<h2 id="fuzzydepth">Positional Duplicates Match</h2>
+<p>This flag allows a match on the basis of board position at the
+indicated number of plies or the end of the game.
+The flag is followed by the ply depth at which matches are to be
+considered. The value 0 is used to request matching at the end of
+games. It should always be used in combination with at least
+one of: <a href="#duplicates">-d/--duplicates, -D/--noduplicates</a>, <a href="#-U">-U</a>.
+
+<p>In contrast to the <a href="#duplicates">--duplicates</a> matching,
+the match does not consider the move sequence used to reach the
+match position.
+
+<p>For example:
+<pre>
+pgn-extract --fuzzydepth 40 -D games.pgn
+</pre>
+<p>would suppress from the output multiple copies of games reaching 
+identical positions after 40 ply.
+
+<p>The following example would suppress the unique games and
+store the games considered to be duplicate at their final
+position in dupes.pgn:
+<pre>
+pgn-extract --fuzzydepth 0 -U -ddupes.pgn games.pgn
+</pre>
+
+<h2 id="-U">Suppression of Unique Games (-U or --nounique)</h2>
+<p>The -U flag suppresses output of the first occurrence of a particular
+game.  This is useful when combined with <a href="#duplicates">the -d flag</a>
+as a means of
+identifying just those games that are duplicated in a list of multiple
+files.  As the duplicate games are commented with the file in which
+they were located, it then becomes possible to prune a set of files
+containing common games.  For instance, suppose oldfile.pgn contains a
+set of games without duplicates, and you wish to know which games in
+newfile.pgn already occur in oldfile.pgn:
+<pre>
+pgn-extract -U -ddupes.pgn oldfile.pgn newfile.pgn
+</pre>
+<p>will write to dupes.pgn the duplicate games so that you can go through
+newfile.pgn and remove them.  Of course, if you simply want to hold the
+combined set of unique games in a single file you would use something like:
+<pre>
+pgn-extract -D -onewset.pgn oldfile.pgn newfile.pgn
+</pre>
+<p>See <a href="#duplicates">Duplicate Games</a> for dealing
+with MallocOrDie errors.
+
+<h2 id="-c">Check Files for Duplicates (-c, --checkfile)</h2>
+<p>Check files contain games that are to be used in duplicate detection,
+but not to form part of the output. If the filename appended to the
+argument has a .pgn/.PGN suffix it is assumed to be a single file of
+games. If it does not have this suffix then it is assumed to be a file
+containing a list of the names of PGN game files, one per line, to be
+used as check files.
+
+<p>A typical use for this is to select new games of
+interest from a file that probably contains games that exist elsewhere.
+In the following example, we wish to select Nimzo-Indian games from
+newfile.pgn that don't already occur in the master file nimzo.pgn:
+<pre>
+pgn-extract -cnimzo.pgn -vnimzo.var -D -onewnimzo.pgn newfile.pgn
+</pre>
+<p>The games in nimzo.pgn act as the source for duplicate detection so
+duplicates of these will be suppressed (<a href="#duplicates">the -D flag</a>).
+Only those games from
+newfile.pgn that are not in nimzo.pgn will be output to newnimzo.pgn.
+Contrast this behaviour with the following, which would create a new
+master file of games from the combination of nimzo.pgn and
+newfile.pgn:
+<pre>
+pgn-extract -vnimzo.var -D -onewnimzo.pgn nimzo.pgn newfile.pgn
+</pre>
+
+<p>--checkfile is available as an alternative to -c and must be followed
+by a space before the filename, e.g.:
+<pre>
+pgn-extract --checkfile nimzo.pgn -vnimzo.var -D -onewnimzo.pgn newfile.pgn
+</pre>
+
+<h2 id="-t">Matching on Tag Criteria (-t)</h2>
+<p>There are two ways to specify that you wish to use information in the
+tag fields as extraction criteria: the -t flag and
+<a href="#-T">the -T flag</a>.  The -t flag takes a file name
+argument and is the preferred method because of its ease of use and
+greater flexibility:
+<pre>
+pgn-extract -ttags games.pgn
+</pre>
+<p>where tags is an arbitrary file name.
+In the file are listed tag name and value pairs
+corresponding to the extraction criteria you wish to use.
+Each line of this file should be of the form:
+<pre>
+PGN-Tag-name Tag-string
+</pre>
+for instance:
+<pre>
+White "Tal"
+</pre>
+<p>(note the need to include double quotes around the tag value).
+This requests that only those games where Tal had the White pieces are
+to be considered for extraction.
+If you wish to limit the year in
+which those games were played you might list:
+<pre>
+White "Tal"
+Date "1962"
+</pre>
+<p>Multiple pairs with the same tag name are or-ed together so:
+<pre>
+% Find games in the period 1960-1962.
+Date "1960"
+Date "1961"
+Date "1962"
+</pre>
+<p>will select all games from the three listed years.
+Note that comments may be included in the tag file.
+
+<p>In general, tags names that differ are and-ed together, so:
+<pre>
+White "Tal"
+Black "Fischer"
+Date "1962"
+Result "1-0"
+</pre>
+<p>selects only those games that Tal won with the White pieces against
+Fischer in 1962.
+
+<p>It is important to note that:
+<pre>
+White "Tal"
+Black "Tal"
+</pre>
+<p>does not find all games played by Tal, but only those that he played
+against himself.  In order to overcome this, I have introduced a
+non-PGN tag that should only be used in the extraction criteria file:
+<pre>
+Player "Tal"
+Date "1962"
+</pre>
+<p>finds all games from 1962 in which Tal had either the White pieces or
+the Black.  In effect, the White and Black player lists are or-ed
+together rather than and-ed using this pseudo-tag.
+
+<p>Prefix matching on tag values is done so that a criterion should be a prefix
+of the complete Tag string.  Thus,
+<pre>
+Player "Karpov"
+</pre>  
+<p>would match:
+<pre>
+[White "Karpov"]
+[White "Karpov, A"]
+[White "Karpov, An"]
+[White "Karpov, Alexander"]
+</pre>
+<p>but not
+<pre>
+[White "Anatoli Karpov"]
+</pre>
+<p>See the <a href="#-S">-S</a> flag for a soundex facility with tag matching.
+
+<p>All tag criteria except ECO classification are checked before the moves
+of the game in the interests of efficiency (tag checking is relatively
+fast whereas positional checking of the game is not). Only once the
+game has been processed is it checked to see whether an ECO tag match
+has been requested.  The consequence of this is that using <a href="#-e">the
+-e flag</a>
+in combination with ECO tag criteria you can search for games in
+particular ECO lines without an ECO tag having been present in the
+input form.
+
+<ul>
+<li id="fen-t"><p>FEN positional matches with -t<br />
+<p>Use of a FEN tag with the -t flag has
+a special meaning. Rather than using this to match FEN tags in 
+the header of a game, a FEN description is used to indicate a search
+for a positional match (similar to use of <a href="#-x">the -x</a> flag).
+If a FEN description is provided with the -t flag, the indicated
+position is searched for in each game processed, and only those
+games that reach the indicated position are output.
+A FEN tag-pair for the starting position would be described by:
+<pre>
+FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
+</pre>
+<p>The position after the two moves e4 c5 would be:
+<pre>
+FEN "rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2"
+</pre>
+<p>See details of <a href="#-F">the -F flag</a> for a simple way to generate a FEN
+description from a game score.
+
+<p>There is a variation on use of a FEN with -t flag.
+The pseudo tag FENPattern takes a FEN-like description of a board
+containing meta characters that allow a fuzzy board match.
+In addition to the standard FEN characters having their usual
+meaning (1, 2, ... 8, R, N, B, etc.), the following
+meta characters are used:
+
+<ul>
+  <li>? - match any square. The square may be occupied or unoccupied.
+  <li>! - match any occupied square. The square may be occupied by a piece of any type and colour.
+  <li>A - match a single White piece.
+  <li>a - match a single Black piece.
+  <li>* - match zero or more squares, occupied or unoccupied.
+  <li>[<em>xyz</em>] - match any of <em>xyz</em>, where <em>xyz</em> represents
+  any of the English piece-letter names (KQRNBPkqrnbp) and is case-sensitive.
+  In addition, 'A' and 'a' (as defined above) are available.
+  For instance: [Qq] matches either a White or Black queen;
+  [BbNn] matches any White or Black bishop or knight;
+  [Ar] matches any White piece or a Black rook.
+  <li>[^<em>xyz</em>] If the first character inside the square brackets
+  is '^' then the match is inverted; i.e., match any piece that is <em>not</em>
+  listed. For instance, [^BbNn] matches any piece that is not
+  a White or Black bishop or knight.
+</ul>
+<p>Ranks within the pattern are separated with a '/' character, as usual,
+but there should be no characters other than the board position.
+<p>
+For instance:
+<pre>
+FENPattern "rnbqkbnr/*/*/*/*/*/*/RNBQKBNR"
+</pre>
+<p>would match any board in which at least every non-pawn piece is 
+on its starting square.
+<pre>
+FENPattern "?????rk?/?????aaa/*/*/*/8/P[BP]P*/??KR????"
+</pre>
+<p>would match a board in which Black has a Kingside castled position behind three
+Black pieces (not necessarily pawns),
+White has a Queenside castled position with
+either a White pawn or bishop on b2 and the third rank is empty.
+</ul>
+
+<li id="date-t"><p>Date and Elo Matches with -t<br />
+<p>From a <a href="#-t">-t tag file</a>,
+more complex matching of dates and Elo values may be performed by
+placing an operator between the tag name and the tag string to be
+matched:
+<pre>
+Date &lt; "1962"
+</pre>
+<p>would only match games played before 1962. Only the year value
+participates in the matching process, as this is done using integer
+values rather than strings.
+<pre>
+WhiteElo &gt;= "2500"
+</pre>
+<p>only matches games where White is a strong player. Probably of more
+general use is another pseudo-tag that I have introduced purely for
+this purpose: Elo.
+<pre>
+Elo &gt;= "2500"
+</pre>
+<p>matches games in which either player has an Elo tag matching that
+relationship.
+The operators allowed are &gt;, &gt;=, &lt;, &lt;=, =, and &lt;&gt; (not
+equal to).
+</ul>
+
+<h2 id="-T">Tag Criteria on the Command Line (-T)</h2>
+<p>An alternative to the <a href="#-t">-t flag</a> is the
+-T flag, for use where command line arguments are
+more convenient - perhaps where pgn-extract is being invoked from another
+program.  The tag coverage is not as extensive as with a tag file, and
+the syntax is rather cumbersome.  It is used as follows: after the -T
+comes a single letter from the limited set [abdeprw] to select string
+prefixes of the tag fields of a game.  For instance:
+<ul>
+  <li>-TaAnnotator - Extract games Annotated by Annotator.
+  <li>-TbPlayer - Extract games where Player has the Black pieces.
+  <li>-TdDate   - Extract games played on Date.
+  <li>-TeEco - Extract games with ECO designation Eco.
+  <li>-ThHashCode - Extract games with HashCode designation HashCode.
+  <li>-TpPlayer - Extract games where Player has either colour.
+  <li>-TrResult - Extract games with result Result.
+  <li>-TwPlayer - Extract games where Player has the White pieces.
+</ul>
+<p>For example,
+<pre>
+pgn-extract -TwTal -TbFischer file.pgn
+</pre>
+<p>would extract games from file.pgn in which Tal had the White pieces and
+Fischer the Black.
+
+<p>Criteria of the same tag type are or-ed together, so
+<pre>
+pgn-extract -Tr1-0 -Tr0-1 file.pgn
+</pre>
+<p>extracts only decisive games.
+
+<p>Criteria of different tag types are and-ed together so
+<pre>
+pgn-extract -TwTal -Td1962 -Tr1-0 file.pgn
+</pre>
+<p>would extract only those games in which Tal played with the White
+pieces in 1962 and won.
+
+<p>The ECO classification (see <a href="#-e">the -e flag</a>)
+is performed before attempting to match an ECO tag, so:
+<pre>
+pgn-extract -TeA01 -e file.pgn
+</pre>
+<p>will perform ECO classification on the input file and extract games
+with ECO classification A01 (Nimzo-Larsen attack), for instance.
+
+<ul>
+<li id="date-T"><p>Date Matches with -T<br />
+<p>A simple form of relational date matching is available.
+A date year may be prefixed with either 'b' or 'a' in order
+to match games played either before or after the specified date. This
+assumes that the date is stored in the game's date tag string in the
+normal form: YYYY.MM.DD
+
+<p>So,
+<pre>
+pgn-extract -Tdb1962 file.pgn
+</pre>
+<p>will look for games played before 1962. A much fuller capability
+is available in tag files with <a href="#-t">the -t flag</a>.
+</ul>
+
+<h2 id="-A">Argument Descriptions in a File (-A)</h2>
+<p>It can be inconvenient to repeatedly type long argument lists
+on the command line. The -A flag makes it possible to list
+arguments in a file, rather than on a command line.  Each
+argument line within the file must be immediately preceded by
+a ':' (colon) character. Consider selecting games by Tal from
+a file caro.pgn and writing them to talgames.pgn. Using
+command line arguments, this would have the following form:
+<pre>
+pgn-extract -TpTal -otalgames.pgn caro.pgn
+</pre>
+<p>We can do the same job placing the argument list in the file args:
+<pre>
+% Select games by Tal.
+:-TpTal
+% Where to output the matched games.
+:-otalgames.pgn
+</pre>
+<p>and the same selection made with:
+<pre>
+pgn-extract -Aargs caro.pgn
+</pre>
+<p>Note that comments may be included using a '%' character.
+
+<p>Each argument should be listed on its own line, and all the
+arguments are available in this way.
+The PGN source files may also be listed in the argument file.
+They must be listed one per line, with a preceding colon
+character. So an alternative for the above would be:
+<pre>
+% Select games by Tal.
+:-TpTal
+% Where to output the matched games.
+:-otalgames.pgn
+% The game files to be read.
+:caro.pgn
+</pre>
+<p>and the command invoked as simply:
+<pre>
+pgn-extract -Aargs
+</pre>
+
+<p>The <a href="#-t">-t</a>, <a href="#-v">-v</a>, <a href="#-x">-x</a>,
+<a href="#-z">-z</a>, and <a href="#-R">-R</a>
+flags have slightly special treatment in an argument file.
+Where the tags, variations, positions, endings and/or roster ordering
+are to be read from
+files of those names, say, then the format of these arguments in the
+argument file might be as you would expect:
+<pre>
+:-ttags
+:-vvariations
+:-xpositions
+:-zendings
+:-Rroster
+</pre>
+<p>However, within an argument file, the file names are optional and,
+where omitted, the data that would have been stored in a file for
+these flags is listed on lines immediately following.
+For instance, an alternative to:
+<pre>
+:-TpTal
+</pre>
+<p>we could say:
+<pre>
+:-t
+Player "Tal"
+</pre>
+<p>Notice that no colon should be present on the lines following the
+flag line.
+In the following example, we select games won by Tal as White
+reaching a particular position in the Caro Kann:
+<pre>
+:-t
+White "Tal"
+Result "1-0"
+:-otalwins.pgn
+:-x
+e4 c6 d4 d5 exd5 cxd5
+% Which game files to process.
+:caro.pgn
+</pre>
+<p>The arguments file may, itself, also contain -A arguments. This should
+make it possible to build up hierarchies of game selection criteria
+if desired. However, beware that there is no check for circularities
+in the dependencies.
+
+<h2 id="-n">Outputting Games not Matched (-n)</h2>
+<p>The -n flag will cause all valid games not output via other criteria to
+be saved in a given file. The purpose of this is to make it easier to
+reorganise files in different ways. For instance, if you wish to remove
+all of the games played by Tal from one file, you might do:
+<pre>
+pgn-extract -TpTal -otalgames.pgn -nothers.pgn file.pgn
+</pre>
+<p>After which, the file others.pgn will contain all of the valid games
+from the original file, with the exception of Tal's.
+
+<h2 id="--selectonly">Outputting a single matched game (--selectonly)</h2>
+<p>The --selectonly flag takes a single numerical argument N (N &gt; 0) to
+request that only the Nth matched game is output. For instance, if only the first
+game played against Fischer is required from a file of Tal games, the following
+would be used:
+<pre>
+pgn-extract -TpFischer --selectonly 1 talgames.pgn
+</pre>
+<p>Note that, once the required game has been output, the program will terminate and
+not continue processing the rest of the input files.
+
+<h2 id="notags">Don't Output Any Tags (--notags)</h2>
+<p>The tags for a game will not be output.
+
+<h2 id="suppress">Suppress annotations in the output (-C -N -V)</h2>
+<p>If comments (-C or --nocomments),
+NAGs (-N or --nonags) and/or variations (-V or --novars) are not required in
+the output then these can be suppressed by using one or more of these flags.
+
+<h2 id="nomovenumbers">Suppressing move numbers (--nomovenumbers)</h2>
+<p>Move numbers can be suppressed from the output with --nomovenumbers.
+Used in combination with
+<a href="#notags">--notags</a>,
+<a href="#noresults">--noresults</a>,
+<a href="#suppress">-C, -N, and -V</a>
+this can be used to output just the moves of a game:
+<pre>
+pgn-extract --nomovenumbers --noresults --notags -C -N -V file.pgn
+</pre>
+<p>If it is desired to have all the moves on a single line, use the <a href=
+"#-w">-w</a> flag as well.
+<p>See also the <a href="#plylimit">--plylimit</a> flag.
+
+<h2 id="noresults">Suppressing results (--noresults)</h2>
+<p>Results at the ends of games and variations
+can be suppressed from the output with --noresults.
+See <a href="#nomovenumbers">suppressing move numbers</a> for a possible use.
+
+<h2 id="plylimit">Limiting the number of plies (&gt;= 0) output
+               (--plylimit)</h2>
+<p>The number of moves (actually plies) output for a game can be limited
+by using --plylimit. This must be followed by the maximum
+number of plies to be output for a game.
+For instance,
+<pre>
+pgn-extract --plylimit 10 --nomovenumbers --notags file.pgn
+</pre>
+<p>will output games up to a maximum of 10 plies (including variation lines),
+without game tags and no line numbers.
+
+<p>Note: If the game has not ended before the ply limit is reached then *
+will be used as the terminating result to indicate an incomplete game (see
+<a href="#noresults">--noresults</a> for how to suppress this.)
+
+<h2 id="-b">Setting bounds on the number of moves in a game (-b)</h2>
+<p>The -b flag allows you to select games which have a number of moves
+within the bounds you set. You can set a lower bound on the number of moves
+by using -bl ('l' = lower bound), or an upper limit
+by using -bu ('u' = upper bound). Both are followed by
+the number of moves so
+<pre>
+pgn-extract -bu20 file.pgn
+</pre>
+<p>will find brevities of 20 moves or less, whilst
+<pre>
+pgn-extract -bl60 file.pgn
+</pre>
+<p>will find games of 60 moves or move. Bounds may be combined so
+<pre>
+pgn-extract -bl30 -bu40 file.pgn
+</pre>
+<p>will find games in the range [30..40] moves. If neither 'l' nor 'u'
+is used, but just a number following the -b, this means that the number
+of moves must exactly match that number. Alternatively, 'e' can be
+used to stand for 'equal to'. The following are equivalent and find
+all games of exactly 35 moves.
+<pre>
+pgn-extract -b35 file.pgn
+pgn-extract -be35 file.pgn
+</pre>
+
+<h2 id="-M">Matching only games that end in checkmate (-M or --checkmate)</h2>
+<p>The -M flag requests that only games that end in checkmate are matched:
+<pre>
+pgn-extract -M file.pgn
+</pre>
+
+<h2 id="stalemate">Matching only games that end in stalemate (--stalemate)</h2>
+<p>The --stalemate flag requests that only games that end in stalemate are matched:
+<pre>
+pgn-extract --stalemate file.pgn
+</pre>
+
+<h2 id="underpromotion">Matching only games that contain an underpromotion
+(--underpromotion)</h2>
+<p>The --underpromotion flag requests that only games that contain an
+underpromotion are matched:
+<pre>
+pgn-extract --underpromotion file.pgn
+</pre>
+
+<h2 id="-e">ECO Classification (-e)</h2>
+<p>A <a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/eco.pgn">PGN
+file of ECO classifications</a> is distributed with this version. I
+believe that this was put together by Ewart Shaw, Franz Hemmer and
+others, to whom appropriate thanks is due.  The -e flag requests
+pgn-extract to add/replace ECO classifications in the games it outputs.
+This is done by firstly reading a file of ECO lines in PGN format
+(eco.pgn in the current directory, by default) and building a table of
+resulting positions. As the games are then read they are looked up in
+the table to find a classification. The deepest match is found.
+A match is allowed within six half moves of the length of the ECO line.
+The supplied file has ECO, Opening, and Variation tag strings for many
+lines. If present, pgn-extract will add/replace these as well as
+SubVariation tags if available.
+
+<p>An alternative file to the default eco.pgn may be supplied in two
+ways:
+<ul>
+    <li><p>Appending a file name to the -e flag
+<pre>
+-emy_eco_codes.pgn
+</pre>
+<p>Note that there must not be a space between the -e and
+the name of the file, otherwise the default ECO file will be assumed.
+    <li><p>By setting the environment variable ECO_FILE to the full path name
+of the file.
+Under Windows this can be done with
+<pre>
+set ECO_FILE=full-eco-file-path
+</pre>
+<p>at the Cmd window prompt, or more permanently via the
+System/Environment/Advanced area.
+Under UNIX csh this can be done with
+<pre>
+setenv ECO_FILE full-eco-file-path
+</pre>
+<p>in the .cshrc, for instance.
+</ul>
+
+<p>Having the ECO data read as plain text on program startup has the
+obvious disadvantage that there is a high initial time overhead. On the
+other hand, it has the advantage that users may add their own
+classifications to the file very easily.  It is fairly demanding of
+memory, so you advised not to combine this with duplicate detection
+(<a href="#-U">-U</a>,
+<a href="#duplicates">-D and -d</a>), which can also consume a lot
+of memory with big databases.
+
+<p>Because an ECO tag match with either the <a href="#-t">-t flag</a> or
+the <a href="#-T">-T flag</a> is delayed until after ECO 
+classification, this makes it relatively easy to select games with
+particular ECO codes even if they weren't present in the source form.
+
+<p>Usage of -e with the Seven Tag Roster flag (<a href="#-7">-7</a>)
+results in the ECO
+tags (ECO, Opening, Variation, SubVariation) being included in the
+output games.
+
+<h2 id="separate-output">Separate Output Files (-#, -E)</h2>
+<p>The -# and -E flags permit the output to be split into multiple files.
+However, be warned that where the input involves a lot of games,
+these flags might result in
+the creation of a large number of output files.
+
+<p>The -# flag takes an unsigned integer argument specifying the maximum number
+of games to output to a single file. Successive output files are numbered 1.pgn,
+2.pgn, etc. Any existing contents of these files are always overwritten on each
+run of pgn-extract.
+<pre>
+pgn-extract -#250 file.pgn
+</pre>
+<p>will check and split file.pgn into separate files of, at most, 250 games each.
+<pre>
+pgn-extract -#1 file.pgn
+</pre>
+<p>will split file.pgn into separate files containing only a single game each.
+
+<p>The -E flag normally takes a numeric argument of value 1, 2, or 3. This is
+used to indicate the level of subdivision required based upon the ECO tag
+found in a game.
+<pre>
+pgn-extract -E3 file.pgn
+</pre>
+<p>will fully subdivide file.pgn into separate files based on the full ECO
+code of each game, with names such as B03.pgn, A01.pgn, D45.pgn, etc.
+If a game does not contain an ECO tag, or the tag appears to be malformed,
+it will be written to a file called, noeco.pgn. All of these files are
+written to in append mode, so that existing contents are not lost. However,
+beware of using an input file whose name is the same as one that will be
+written to by this operation. This could lead to infinite operation.
+
+<p>Level 1 classification uses just the initial letter of the ECO
+classification to append to files A.pgn, B.pgn, etc. Level 2 uses the initial
+letter and first digit, producing A0.pgn, B3.pgn, etc.
+
+<p>In fact, values greater than 3 may be used to produce separation of even
+finer granularity if more than two digits have been used in the classification
+of a game.
+
+<h2 id="-S">Soundex Matching (-S)</h2>
+<p>There is a simple soundex algorithm available that attempts soundex
+matches on White, Black, Site, Event, and Annotator tags if the -S flag
+is used in combination with either the <a href="#-t">-t flag</a> or
+the <a href="#-T">-T flag</a>.  The -S flag should
+precede all -t and -T arguments.  It should be noted that the soundex
+matching does produce false matches.
+
+<h2 id="-w">Output Line Length (-w or --linelength)</h2>
+<p>The -w flag allows an approximate line length to be set for output.
+Normally games are output with lines up to a maximum of 75 characters.
+Use the -w flag if you want longer output lines.
+For instance, you might want all the moves of a game to appear on a single
+line. You would get this effect by specifying -w1000 (say):
+<pre>
+pgn-extract -w1000 file.pgn
+</pre>
+<p>If some games are more than 1000 characters long then just increase the value.
+
+<h2 id="-W">Output Format and Language (-W)</h2>
+<p>By default, pgn-extract rewrites the game score into English Standard Algebraic
+Notation (SAN) because it is reasonably flexible about the input form
+that it will accept.  To prevent it from rewriting the original form of
+the moves it reads, use the -W flag.
+<ul>
+  <li>By itself, -W outputs the moves using the input text.
+  <li>Using -Whalg writes the moves in hyphenated long algebraic (e.g., e2-e4).
+  <li>Using -Wlalg writes the moves in long algebraic form (e.g., e2e4).
+  <li>Using -Welalg writes the moves in enhanced long algebraic form (e.g.,
+  Ne2e4, e5d6ep). The purpose of enhanced long algebraic form is to reduce the
+  amount of chess-specific knowledge that a post-procesing program might
+  need in order to interpret a chess game.
+  For instance, in order to provide a visualisation.
+  <li>Using -Wuci causes the moves of the game to be output in
+  a format that should close to being suitable for input to a
+  <a href="http://wbec-ridderkerk.nl/html/UCIProtocol.html">UCI-compatible</a> engine.
+  The output format is the same as with -Wlalg but all comments, NAGs,
+  variations, move numbers and checks removed.
+  In addition the whole game is output on a single line.
+</ul>
+
+<p>Output using non-English piece letters is possible using a variation
+of the -Wsan flag. This flag may have a six-letter suffix indicating
+the letters to be used in representing pawn, knight, bishop, rook,
+queen and king in game scores and diagrams. So:
+<pre>
+pgn-extract -WsanPNBRQK ...
+</pre>
+<p>would output in the (default) English notation, and
+<pre>
+pgn-extract -WsanBSLTDK ...
+</pre>
+<p>would output in German. Note that the letter for a pawn is required because
+board positions are sometimes output when an error is detected in
+a game score.
+
+<p>-Wepd outputs in EPD (Extended Position Description).
+A game is output as a sequence of EPD descriptions of
+the position at the start of the game, and following each move.
+Each EPD line contains the FEN board description, the active colour,
+castling availability and en passant target square. A c0 comment contains
+a synopsis of the player, event, site and date tags from the game's header.
+
+<p>-Wuci outputs in long-algebraic notation (-Wlalg) but also strips the
+game of everything apart from its moves, tags and result.
+It provides the equivalent of using the following multiple arguments:
+<pre>
+-Wlalg -C -N -V -w5000 --nomovenumbers --nochecks
+</pre>
+Use the --noresults and --notags options if tags and results are also
+to be removed.
+
+<p>-Wcm is an obsolete legacy flag and
+outputs the moves in what I believe to be (or used to be) ChessMaster format.
+
+<h2 id="-F">Forsyth-Edwards Notation (FEN) Descriptions (-F)</h2>
+<p>The -F flag provides a convenience method for generating
+a suitable FEN description of an arbitrary position.
+The -F flag causes pgn-extract to output a FEN description of the final
+position reached in a game, within the text of a comment.
+For instance, suppose you were interested in finding games that
+reach the position after the following moves.
+<pre>
+d4 Nf6 c4 e6 Nf3 b6 Nc3 Bb7 e3 Bb4 Bd3 O-O O-O Bxc3 bxc3 c5 *
+</pre>
+<p>Storing these moves in the file fen.pgn and running
+<pre>
+pgn-extract -F fen.pgn
+</pre>
+<p>would generate the score:
+<pre>
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "*"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Nc3 Bb7 5. e3 Bb4 6. Bd3 O-O 7. O-O Bxc3 8.
+bxc3 c5 
+{ "rn1q1rk1/pb1p1ppp/1p2pn2/2p5/2PP4/2PBPN2/P4PPP/R1BQ1RK1/ w - c6 0 9" } *
+</pre>
+<p>The <a href="#-t">-t flag</a>
+makes it possible to use Forsyth-Edwards Notation (FEN) in the
+description of a position
+to be matched. For instance, the FEN string above
+could be cut and pasted to <a href="#-A">an argument file</a> and used with
+the <a href="#-t">-t flag</a> to supply matches:
+<pre>
+:-t
+FEN "rn1q1rk1/pb1p1ppp/1p2pn2/2p5/2PP4/2PBPN2/P4PPP/R1BQ1RK1/ w - c6 0 9"
+</pre>
+<p>See <a href="#fencomments">--fencomments</a> for the option to add
+a FEN comment after every move, including the final one.
+
+<h2 id="-z">Material Matches (-z)</h2>
+<p>The -z flag takes a filename of material balances for which you wish to
+search in games.  The basic structure of the file is one or
+more lines of the form
+<pre>
+pieces1 pieces2
+</pre>
+<p>Pieces1 and pieces2 are lists of English piece letters for the material
+for the two sides that you wish to look for in a game.
+For instance:
+<pre>
+rp nb
+</pre>
+<p>looks for an game in which a lone Rook and Pawn for one side are
+competing against a lone Knight and Bishop for the other.
+
+<p>Text may be added after the piece lists as a form of comment.
+
+<p>A comment line may be placed in a material balance file by using a '%'
+as the first character of the line.
+
+<p>The <a href="#markmatches">--markmatches</a> flag may
+be used to add a comment at the point that the match is found.
+<p>The case of the
+letters is immaterial, there is no need to include Kings in the
+description, and the order of the pieces does not matter.  Apart from
+Kings, if a piece letter is not listed for a side then that piece
+is not present within that side's material.
+A match will be tested for from both White and Black's point of view, so the
+example above matches the same games as:
+<pre>
+nb rp
+</pre>
+<p>Some notation may be added after any piece letter, typically to
+indicate something about the number of occurrences of that piece on one
+side.
+
+<p>The following are valid for each piece:
+<ul>
+    <li>* (zero or more of that piece).
+    <li>+ (one or more of that piece).
+    <li>d (exactly d occurrences of that piece, where d is a digit).
+    <li>d+ (d or more occurrences of that piece).
+    <li>d- (d or fewer occurrences of that piece).
+</ul>
+<p>So:
+<pre>
+QR2B2N2P8 QR2B2N2P8
+</pre>
+<p>is the starting material position, and QR+B*N*P7- represents material
+in which we require at least one pawn to be missing from one side and
+they should have a Queen and Rook, but we don't care about the minor
+pieces.
+
+<p>In addition, some extra notation is available to specify material
+relative to the opponent's.
+These are placed after the piece letter to which they refer.
+<ul>
+    <li>= (the number of these pieces must be the same as the opponent's).
+    <li># (the number of these pieces must be different the opponent's).
+    <li>&gt; (the number of these pieces more than the opponent has).
+    <li>&lt; (the number of these pieces less than the opponent has).
+</ul>
+<p>So,
+<pre>
+R+P+ R=P#
+</pre>
+<p>looks for Rook and Pawn games with an equal number of Rooks but
+unbalanced pawns.
+
+<p>In addition &gt; and &lt; may be preceded by a digit:
+<ul>
+    <li>d&gt;
+    (the number of these pieces must be at least d more than the opponent's).
+    <li>d&lt;
+    (the number of these pieces must be at least d less than the opponent's).
+</ul>
+<p>Two more notations, &gt;=, &lt;= may be preceded by an optional digit
+(the default is 1).
+The meaning of this may not be intuitively obvious and, to an extent, they
+represent a notational compromise.
+<ul>
+    <li>d&gt;=
+    (the number of these pieces must be exactly d more than the opponent's).
+    <li>d&lt;=
+    (the number of these pieces must be exactly d less than the opponent's).
+</ul>
+<p>In this example, both sides have a pair or Rooks but one has exactly one
+pawn more than the other:
+<pre>
+r2p* r=p1&gt;=
+</pre>
+<p>Here is an example where one side has sacrificed a Rook and Pawn for
+Knight and Bishop and we don't care whether Queens are on or off the
+board, so long as they are balanced:
+<pre>
+q*r+n*b*p+ q=r&lt;n&gt;b&gt;p1&lt;
+</pre>
+<p>This example represents some of the imprecision that can occur with
+matches.  The meaning of 'r&lt;' is such that this could match positions
+in which one side as 2 Rooks and the other none. This can be corrected
+with:
+<pre>
+q*r+n*b*p+ q=r1&lt;=n&gt;b&gt;p1&lt;
+</pre>
+<p>enforcing strictly one Rook less. We ought also to correct the same
+problem with the minor pieces:
+<pre>
+q*r+n*b*p+ q=r1&lt;=n1&gt;=b1&gt;=p1&lt;
+</pre>
+<p>In practice, we probably want to allow general matching of minor pieces
+so the letter 'L' may be used to stand for a minor piece (Bishop or
+Knight). This example represents a similar sacrifice of Rook and Pawn for
+two minor pieces.
+<pre>
+q*r+l*p+ q=r1&lt;=l2&gt;=p1&lt;
+</pre>
+<p>I would advise against mixing the minor piece letter with Knight and
+Bishop letters in the piece set for a single side, however, as I am not
+convinced that it will produce exact results.
+
+<ul>
+<li><p>Position Stability with -z<br />
+<p>The piece sets may be preceded by an optional number indicating the
+required stability of the position. Normally, if you are looking for a
+position with a particular set of material characteristics then you
+probably want that position to last for a reasonable number of moves in
+order to study its characteristics. The number before the piece sets is
+how many half-moves you wish that material balance to last. By default,
+this has a value of 2 so that fleeting positions in the middle of pairs
+of exchanges do not produce unwanted matches.
+This example looks for double-Rook and pawn games that last at least
+10 half-moves:
+<pre>
+10 R2P+ R=P*
+</pre>
+</ul>
+
+<h2 id="-7">The Seven Tag Roster (-7 or --seven)</h2>
+<p>This flag discards tag pairs that are not part of the Seven Tag
+Roster:
+<pre>
+Event, Site, Date, Round, White, Black and Result.
+</pre>
+<p>However, if the original game included a FEN tag, this is
+included in the output, as the moves will make no sense
+otherwise. In addition, if <a href="#-e">the -e flag</a> has been used for ECO
+classification, any ECO, Opening, Variation and SubVariation tags
+are also output.
+
+<h2 id="-R">User-defined Tag Roster Ordering (-R)</h2>
+<p>The -R flag makes it possible for to define the order in which
+tags for a game are listed in the output.
+The flag should be immediately followed by the name of a file
+that contains a list of tag names, one per line, for instance:
+<pre>
+pgn-extract -Rroster file.pgn
+</pre>
+<p>where roster might contain:
+<pre>
+% Output the tags of the seven tag roster alphabetically.
+Black
+Date
+Event
+Result
+Round
+Site
+White
+</pre>
+<p>The '%' character may be used to include comments in the file.
+Tags not listed in such a file will appear after the required
+tags have been output.
+
+<h2 id="evaluation">Include a position evaluation after each move (--evaluation)</h2>
+<p>The --evaluation argument causes a comment to be appended to every move,
+which contains an evaluation of the position immediately following that
+move.
+The default evaluation is a simplified version of 
+<a href="http://en.wikipedia.org/wiki/Claude_Shannon">Shannon's board
+evaluation</a>. In this case, the evaluation is the difference between the
+value of White's position and Black's, where the value of a position is
+a weighted sum of the pieces plus a multiplier (0.1) applied to
+the number of available moves for that player.
+
+<p>I see this primarily as being a hook for people who wish to embed their
+own evaluations in the output.
+See the <code>evaluate</code> function in <code>apply.c</code> if you wish to
+write your own.
+
+<h2 id="fencomments">Include a comment with a FEN string for
+the position after each move (--fencomments)</h2>
+<p>The --fencomments argument causes a comment to be appended to every move,
+which contains a FEN string for the position immediately following that
+move. See <a href="#-F">-F</a> for adding a comment after just the
+final move.
+
+<h2 id="markmatches">Add a game comment on positional and material matches
+(--markmatches)</h2>
+<p>Add a game comment with the text immediately following --markmatches
+after the move which causes a positional or material match.
+For instance:
+<pre>
+pgn-extract -xvars --markmatches MATCH file.pgn
+</pre>
+<p>would add the comment <em>{ MATCH }</em> after every move that
+caused a match from the positional matches specified in the <em>vars</em> file.
+<p>See <a href="#-x">-x</a> for positional matches with moves,
+<a href="#fen-t">-t</a> for positional matches with FEN patterns,
+and <a href="#-z">-z</a> for material matches.
+
+<h2 id="addhashcode">Add a Tag containing a hashcode for the game (--addhashcode)</h2>
+<p>Add the tag HashCode to the tags. This contains a hashcode value
+generated from the moves of the game. Identical move sequences will
+produce the same hash code.
+
+<h2 id="totalplycount">Add a Tag containing the total ply count (--totalplycount)</h2>
+<p>Add the tag TotalPlyCount to the tags. This contains a count of
+the number of ply present in the game being output.
+Unless <a href="#suppress">variations have been suppressed</a> this will include
+all moves in variations as well as the main line.
+
+<h2 id="mailing">Mailing List</h2>
+<p>I don't run a proper mailing list but if you find the program useful
+and would like or to offer suggestions that you think
+others might be interested in, then drop me a line at
+<a href="mailto:d.j.barnes@kent.ac.uk">d.j.barnes@kent.ac.uk</a>
+
+<h2 id="limitations">Limitations</h2>
+<p>The moves, variations, and commentary of each game are held internally
+and reformatted when a game is extracted, rather than reproducing the
+original text of the game source.
+
+<p>Lower-case 'b' as the first character of a move is taken to be a move
+of the b-pawn if one to match the move can be found. Otherwise, Bishop
+moves are tried as an alternative.  There is no back-up on failure if
+picking a valid pawn move was the wrong choice.
+
+<p>Lower-case 'b' as the first character of a Bishop move is not
+acceptable in the variations files.
+
+<p>Duplicate detection is not guaranteed to be exact.
+The -Z flag has slightly more potential to avoid false duplicates
+as it compares separate values for the end position and move sequence,
+whereas these are XORed to save space when -Z is not used.
+However, this will only make a difference and avoid false
+matches if
+two different games at the same hashtable index
+also produce identical XORed values.
+
+<p>The results of the -x, -v, and -t/-T search criteria are AND-ed
+together.  There might be occasions when you wanted to search for games
+that matched either positional variations or textual variations at the
+same time, for instance.  This requires multiple runs of pgn-extract.
+
+<p>The -Wsan variation that allows selection of the output language
+is tied to single-character piece descriptions. This does
+not support Russian usage, for instance, in which the King
+is described as a character pair.
+
+<h2 id="files">The Files</h2>
+<p>The sources include a Makefile for the GNU make program, gmake.
+I also use this with the <a href="http://www.mingw.org/">Minimalist
+GNU for Windows</a> compiler
+to produce a Windows command-line executable (see <a
+href="#portability">Portability</a>).
+
+<p>The distribution comes with the following files.
+<table>
+    <tr>
+    <td>COPYING</td><td>GNU General Public License</td>
+    </tr>
+    <tr>
+    <td>Makefile</td><td>A build file suitable for use with the GNU make utility.
+    <br />Windows users might like to use the
+    <a href="<a href="http://www.mingw.org/">mingw - Minimalist GNU for Windows</a> version.</td>
+    </tr>
+    <tr>
+    <td>apply.[ch]</td><td>functions concerned with applying moves to a board.</td>
+    </tr>
+    <tr>
+    <td>argsfile.[ch]</td><td>functions concerned with command line argument processing.</td>
+    </tr>
+    <tr>
+    <td>bool.h</td><td>Boolean type definition.</td>
+    </tr>
+    <tr>
+    <td>decode.[ch]</td><td>functions for decoding the text of a move.</td>
+    </tr>
+    <tr>
+    <td>defs.h</td><td>definitions relating to boards.</td>
+    </tr>
+    <tr>
+    <td>eco.[ch]</td><td>functions for looking up ECO classifications.</td>
+    </tr>
+    <tr>
+    <td>eco.pgn</td><td>PGN file of ECO classifications.</td>
+    </tr>
+    <tr>
+    <td>end.[ch]</td><td>functions for looking for matching endgames.</td>
+    </tr>
+    <tr>
+    <td>fenmatcher.[ch]</td><td>pattern matching for the FENPattern
+    pseudo tag.</td>
+    </tr>
+    <tr>
+    <td>grammar.[ch]</td><td>the parser.</td>
+    </tr>
+    <tr>
+    <td>hashing.[ch]</td><td>duplicate detection hash tables.</td>
+    </tr>
+    <tr>
+    <td>help.html</td><td>This file.</td>
+    </tr>
+    <tr>
+    <td>lex.[ch]</td><td>the lexical analyser.</td>
+    </tr>
+    <tr>
+    <td>lines.[ch]</td><td>functions for reading lines.</td>
+    </tr>
+    <tr>
+    <td>lists.[ch]</td><td>functions for holding the extraction criteria.</td>
+    </tr>
+    <tr>
+    <td>map.[ch]</td><td>functions for implementing move semantics.</td>
+    </tr>
+    <tr>
+    <td>moves.[ch]</td><td>functions for collecting moves and variations.</td>
+    </tr>
+    <tr>
+    <td>mymalloc.[ch]</td><td>functions for memory allocation.</td>
+    </tr>
+    <tr>
+    <td>output.[ch]</td><td>functions concerned with outputting the games.</td>
+    </tr>
+    <tr>
+    <td>taglist.h</td><td>constants for tag and pseudo-tag names</td>
+    </tr>
+    <tr>
+    <td>tokens.h</td><td>type definition for lexical tokens.</td>
+    </tr>
+    <tr>
+    <td>typedef.h</td><td>type definitions.</td>
+    </tr>
+</table>
+
+<h2 id="portability">Portability</h2>
+<p>pgn-extract is regularly used under Windows/DOS
+(using <a href="http://www.mingw.org/">Minimalist
+GNU for Windows</a>),
+and various versions of Linux and Mac OSX.
+
+<h2 id="acknowledgements">Acknowledgements</h2>
+<p>I would like to thank all those who used the program and made
+suggestions for things to add.  In particular, thanks to Michael Kerry
+whose help led to better determination of game boundaries in earlier
+versions, and V. Armando Sole whose own filter
+program was the inspiration for adding textual variation permutations.
+John Brogan suggested adding the ! notation to the variation file and
+provided the spur for duplicate detection.
+He also supplied the original code for soundex matching (-S).
+<p>Jaroslav Poriz, Ron Leamon, Ed Leonard, Charles
+Frohman, and Robert Wilhelm helped with testing at various times.
+Bernhard Maerz was instrumental in encouraging the inclusion of ECO
+classification and material balance matches.
+He and Peter Otterstaetter
+suggested the relational operators in tag files, with Peter also
+providing the spur to make duplicate detection work with bigger game files
+(-Z) and doing some very useful testing for me.
+<p>Kayvan Sylvan requested
+long algebraic output and identified an error in ECO classification.
+Cameron Hayne suggested matching on the number of moves in a game.
+Owen D. Lyne suggested extension of the -E flag,
+and both tested and provided diagnostic data to help refine the
+ECO classification aspects of the program.
+Karl-Martin Skontorp provided the incentive and testing help that
+enabled me to add the -Wepd option.
+<p>FEN pattern matching is based on pattern matching code by Rob Pike.
+Taken from:
+http://www.cs.princeton.edu/courses/archive/spr09/cos333/beautiful.html
+and ideas from Kernighan and Plauger's "Software Tools".
+<p>Finally, thanks, of course, to Steven Edwards
+for his work on developing the PGN standard.
+
+<h2 id="license">License</h2>
+<p>pgn-extract: a Portable Game Notation (PGN) extractor.<br>
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+<p>This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+<p>You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+<p>David Barnes may be contacted as
+<a href="mailto:d.j.barnes@kent.ac.uk">d.j.barnes@kent.ac.uk</a>, <a href="http://twitter.com/kentdjb/">@kentdjb</a> on Twitter,
+or via
+<a href="http://www.cs.kent.ac.uk/people/staff/djb/">http://www.cs.kent.ac.uk/people/staff/djb/</a>
+
+<h2 id="history">Change History</h2>
+<ul>
+    <li>28th October 2014. Added --selectonly after a suggestion by Francis Steen.
+    <li>2nd September 2014. Corrected an error in the generation of hashcodes
+    when a promotion is made.
+    <li>31st May 2014. Added --addhashcode.
+    <li>25th May 2014. Added --totalplycount for Erich K&ouml;rber.
+    <li>5th March 2014. Added --keepbroken to allow broken games to be output.
+    Added at the request of Mark Crowther primarily to deal with the problem of live
+    recording where the kings are moved to the centre of the board at the end of
+    a game and erroneously included in the score.
+
+    <li>6th September 2013. Corrected failure to 'or' together multiple
+    dates with -T and -t.
+
+    <li>16th May 2013. Corrected an error in the whole-move number in
+    FEN output, thanks to Vincent Fleuranceau.
+
+    <li>14th May 2013. Null move notation (--) in variations recognised.
+
+    <li>16th April 2013. Added --fuzzydepth. This is due to Owen D. Lyne who
+    requested this functionality years ago - sorry for taking so long, Owen!
+
+    <li>11th April 2013. Added -Wuci.
+
+    <li>29th March 2013. Added --version.
+
+    <li>26th March 2013. Fixed crash when a string to be output is longer than the output line length.
+
+    <li>12th March 2013. Added long-form versions of -a, -c, -d and -o:
+    --append, --checkfile, --duplicates and --output.
+
+    <li>9th February 2013. Added pattern matching based on
+    FEN descriptions and --markmatches for JS.
+
+    <li>23rd December 2012. Added --fencomments for Tyler Eaves.
+
+    <li>2nd December 2012. Allowed 0 for --plylimit.
+
+    <li>22nd September 2008. Added --stalemate for Wieland Belka.
+
+    <li>15th September 2008. Added --nochecks and fixed -A so that it
+    handles long-form arguments properly.
+
+    <li>22nd December 2007. Added --notags, --plylimit, --nomovenumbers and
+    <a href="#noresults">--noresults</a>
+    after a suggestion by Wieland Belka to be able to create opening books.
+
+    <br>Added --evaluation for Folkert van Heusden.
+
+    <br>Added --stalemate for Norm Pollock.
+
+    <br>Added calculation of the half-move clock to FEN strings.
+
+    <br>Most of the arguments taking filenames can now be separated from
+    the filename with a space.
+
+    <br>Gradually adding long-form alternatives for arguments, e.g.
+    --seven, --notags, etc.
+
+    <li>24th April 2007. Fixed a bug with mate annotation. Added the -M flag for
+    checkmate matches, which is due to Richard Jones.
+
+    <li>19th October 2005. Added language-specific letters to -Welalg
+    following a suggestion from Folkert van Heusden.
+
+    <li>1st May 2004: Fixed an error with ECO classification that
+    was causing the file list to be out of sync.
+
+    <li>29th April 2004: Buffered game text before outputting it,
+    so that trailing spaces on lines (which violate the PGN spec)
+    can be deleted.<br>
+    Games with zero moves are now acceptable.
+    <li>26th April 2004: Slight modification to one of the hashing
+
+    values made in order to try to avoid clashes in ECO matches.
+    ECO matches now have a discretion of up to 6 half moves.
+
+    <li>13th February 2002: Added -Welalg as an output format following
+    a suggestion from Rafal Furdzik.
+
+    <li>27th March 2001
+      <ul>
+       <li>Added output of EPD via -Wepd.
+       <li>Fixed a long standing error in FEN castling rights. These were
+           not being withdrawn if a Rook was captured on its home square.
+           Pointed out by Karl-Martin Skontorp, who also provided the
+           incentive to add -Wepd.
+      </ul>
+
+    <li>26th April 2000
+    Added the -R flag for tag ordering.
+
+    <li>22nd April 2000
+    Completed implementation of -A to work with all flags.
+
+    <li>21st April 2000
+      <ul>
+        <li>Added the -F flag.
+        <li>Added support for reading Russian source files.
+      </ul>
+
+    <li>11th April 2000
+      <ul>
+        <li>Added the -A flag.
+        <li>Extended usage of -Wsan to support output in different languages.
+        <li>Usage of -e with -7 retains an ECO tag in matched games.
+        <li>FEN tags with the -t flag are used as positional matches
+        (equivalent to -x matches).
+        <li>Non-standard tags are now retained in game output.
+      </ul>
+
+    <li>12th January 2000
+    C compiler with Red Hat Linux 6 was no longer happy with
+    static initialisations involving stdin, stdout and stderr.
+    Changes made to lex.c and main.c to work around this.
+    Pointed out by Mladen Bestvina.
+
+    <li>18th October 1999
+    Numbers greater than 3 allowed with -E, at the request of Owen Lyne.
+
+    <li>15th December 1997
+    Treat \r as WHITESPACE (for DOS files).
+
+    <li>8th June 1997
+    Added -b flag to set bounds on the number of moves in a game to
+    be matched.
+
+    <li>2nd May 1997
+    Corrected small error when strings were not terminated properly.
+    In tags, this resulted in the corrected tag ending in ]"] instead
+    of "].
+
+    <li>17th February 1997
+    Added a little more error recovery.
+
+    <li>15th November 1996
+    Added -Z.
+
+    <li>23rd Sep 1996
+    It is no longer necessary to omit move numbers from the variations
+    files (-v and -x). This makes it easier to cut and paste games
+    of interest into these files.
+
+    <li>28th Jun 1996
+    It is no longer necessary to terminate the tag file (-t).
+    Relational operators added in the tag file (-t).
+    Added -E flag.
+
+    <li>7th May 1996
+    Corrected failure to make ECO classification when combined with -x.
+    Added lalg and halg as long algebraic output formats.
+
+    <li>9th Oct 1995
+    Add -#
+
+    <li>25th Sep 1995:
+    Default to reading stdin if no file arguments are provided.
+
+    <li>24th Jul 1995:
+    Added setup from FEN tags.
+
+    <li>18th Jul 1995:
+      <ul>
+        <li>Added material balance matches with -z.
+        <li>Added 'L' as a minor piece letter in ending files.
+      </ul>
+
+    <li>14th Jul 1995:
+    Made the order of arguments immaterial.
+
+    <li>5th Jul 1995:
+      <ul>
+        <li>Added ECO classification with -e.
+        <li>Fixed false partial substring matches with -v, e.g. textual
+        variation move Nc6 is now no longer matched by game move c6.
+      </ul>
+
+    <li>22nd Mar 1995:
+    Made permutation matching with -v the default and added -P
+    to suppress it.
+
+    <li>Jan 1995: Added -n and -L.
+
+    <li>17th Nov 1994: Liberated the program from using YACC and Lex.
+
+    <li>13th Oct 1994: Released test version with ChessMaster output.
+
+    <li>20th Sep 1994: Added move rewriting and -W flag.
+
+    <li>7th Sep 1994: Added -D flag.
+
+    <li>6th Sep 1994: Added -C and -V flags and soundex matching.
+
+    <li>5th Sep 1994:
+      <ul>
+        <li>Integrated the positional variation code from a separately
+    developed program.
+        <li>Added -N flag.
+        <li>Added ! to the textual variation syntax.
+        <li>Removed the writing to extract.pgn that was present in an
+    earlier unreleased version.
+        <li>Added -d flag.
+      </ul>
+
+    <li>8th Jul 1994:
+      <ul>
+        <li>Added -o flag.
+        <li>Discarded writing to standard output in DOS version because of
+        extensive problems trying to make this work with redirected
+        output.  Instead, output is written to the file extract.pgn.
+      </ul>
+
+    <li>6th Jul 1994: Added -7 flag.
+
+    <li>9th May 1994: Added -p flag for variation permutations.
+
+    <li>6th May 1994: Added * as a don't-care move in variations files.
+
+    <li>26th Apr 1994: Added the -t flag for files of extraction criteria.
+
+    <li>25th Apr 1994: Added the -T flag for extraction criteria.
+
+    <li>22nd Apr 1994: Added the -f flag for handling lists of PGN files.
+
+    <li>13th Apr 1994:
+      <ul>
+        <li>Cleaned up the game-length determination by reading/writing files
+    in binary-mode.
+        <li>Added -a flag for appending to existing .pgn files.
+        <li>Added multiple input files.
+        <li>Made verbose output the default behaviour.
+      </ul>
+</ul>
+<hr>
+</div>
+</div>
+
+  <div id="footer">
+<address>
+<p>Copyright (C) 1994-2014 David J. Barnes<br />
+<a href="mailto:d.j.barnes@kent.ac.uk">d.j.barnes@kent.ac.uk</a><br />
+<a href="http://www.cs.kent.ac.uk/~djb/">http:www.cs.kent.ac.uk/~djb/</a><br />
+Date of this version: 28th October 2014<br>
+Version Number: 17-19<br>
+</address>
+  </div>
+</div>
+</body>
diff --git a/index.html b/index.html
new file mode 100644 (file)
index 0000000..c2b6d53
--- /dev/null
@@ -0,0 +1,190 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<html>
+<head>
+       <title>pgn-extract: Portable Game Notation (PGN) Manipulator for Chess Games</title>
+       <link rev="made" href="mailto:D.J.Barnes @at@ kent.ac.uk">
+       <meta name="Author" content="David Barnes">
+       <meta name="Description"
+             CONTENT="FTP Directory with source of program to manipulate
+             chess games recorded in Portable Game Notation (PGN)
+             format">
+       <meta name="Keywords" content="Chess PGN Portable Game Notation
+                       Database
+                       pgn-extract">
+        <link href="style.css" rel="stylesheet" type="text/css" media="all">
+</head>
+<body>
+<div id="body">
+
+  <div id="banner-wrapper">
+    <div id="banner">
+<h1 align="center">pgn-extract:<br />A Portable Game Notation (PGN) Manipulator for Chess Games<br />
+Version 17-14 by <a href="http://www.cs.kent.ac.uk/~djb/">David J. Barnes</a>
+(<a href="https://twitter.com/kentdjb">@kentdjb</a>)<br />
+<a href="pgn-extract.xml">
+<img src="feed.png" width="25" height="25"></a>
+</h1>
+    </div>
+  </div>
+
+  <div id="page-wrapper">
+    <div id="page">
+<h2>Introduction</h2>
+<p>This is the home page for
+the <em>pgn-extract</em> program,
+which is a <em>command-line</em> program for manipulating
+chess games recorded in the Portable Game Notation (PGN).
+<p>A <a href="http://www.cs.kent.ac.uk/people/staff/djb/pgn-extract/help.html">full
+description of pgn-extract's functionality</a> is available and included
+with the sources.
+
+<p>Here you can find the C source code and win32 binary for the current
+version.
+pgn-extract compiles and runs under Windows, Linux and Mac OSX.
+This program is made available under the terms of the
+<a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/COPYING">GNU
+General Public License (Version 1).</a>
+
+<h2>Overview</h2>
+<p>The program is designed to make it easy to extract selected games from a
+PGN format data file based on a wide variety of criteria.
+The criteria include:
+<ul>
+<li><p>textual move sequences;</p></li>
+<li><p>the position reached after a sequence of moves;</p></li>
+<li><p>information in the tag fields;</p></li>
+<li><p>fuzzy board position;</p></li>
+<li><p>and material balance in the ending.</p></li>
+</ul>
+<p>The program includes a semantic analyser which will
+report errors in game scores and it is also able to detect duplicate
+games found in its input files.
+
+<p>The range of input move formats accepted is fairly wide and includes
+recognition of lower-case piece letters for English and upper-case
+piece letters for Dutch and German.  The output is normally in English Standard
+Algebraic Notation (SAN), but this can be varied.
+
+<p>Extracted games may be written out either including or excluding
+comments, NAGs, variations, move numbers, tags and/or results.
+Games may be given ECO classifications
+derived from the accompanying file eco.pgn, or a customised version
+provided by the user.
+
+<p>The program is designed to be relatively memory-friendly, so it
+does not retain a game's moves in memory once it has been processed.
+
+<p>Use the <em>--help</em> argument to the program to
+get the full lists of arguments.
+
+<h2>New in version 17-1x</h2>
+<p>These are the major additions in version 17-1x:
+<ul>
+    <li><p>Null moves (--) in variations now recognised.
+    This is non-standard PGN notation.
+    Note that there is scope for semantic errors here, so please let me know
+    if you come across any game scores containing null moves that
+    pgn-extract does not deal with
+    correctly.
+    <li><p>v17-14 corrected a long-standing error in the whole-move number
+    in FEN output.
+    <li><p><a href="help.html#fuzzydepth">--fuzzydepth flag</a>
+    allows duplicate detection based on position reached
+    at a particular ply depth.
+    <li><p><a href="help.html#-W">-Wuci</a> outputs a game in a format suitable for input to
+    a <a href="http://wbec-ridderkerk.nl/html/UCIProtocol.html">UCI-compatible</a> engine.
+    <li><p>Board position matches with <a href="help.html#fen-t">the -t flag</a> that
+    allow fuzzy board position matches.
+    <li><p>A test suite of the program's basic functionality to support
+    regression testing. This won't be of interest to users but might be
+    to developers.
+</ul>
+
+<h2>Available Files</h2>
+<p>You can take a copy of the full source and
+documentation as either
+<a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/pgn-extract-17-14.tgz">pgn-extract-17-14.tgz</a> 
+or
+<a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/pgn-extract-17-14.zip">pgn-extract-17-14.zip</a>.
+Alternatively, <a
+href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/pgn-extract-17-14.exe">a win32
+binary</a> is available.
+<p />
+    <table border cellpadding=5>
+    <tr>
+    <td align="center"><b>Name</b></td>
+    <td align="center"><b>Description</b></td>
+    <td align="center"><b>Size</b></td>
+    <td align="center"><b>Date</b></td>
+    </tr>
+
+    <tr valign="top">
+    <td><a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/pgn-extract-17-14.tgz">pgn-extract-17-14.tgz</a><br>
+    <td>GZipped tar file
+    of the complete source of version 17-14 of the program.<br>
+    Includes <a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/help.html">help.html</a>,
+    Makefile for compilation and
+    <a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/eco.pgn">eco.pgn</a> file for ECO classification.</td>
+    <td align="right">291524 bytes</td><td>Jun 19 2013</td>
+    </tr>
+
+    <tr valign="top">
+    <td><a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/pgn-extract-17-14.zip">pgn-extract-17-14.zip</a></td>
+    <td>Zipped file of the complete source of version 17-14 of the program.<br>
+    Includes <a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/help.html">help.html</a>, Makefile for compilation and
+    <a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/eco.pgn">eco.pgn</a> file for ECO classification.</td>
+    <td align="right">403727 bytes</td><td>Jun 19 2013</td>
+    </tr>
+
+    <tr>
+    <td><a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/pgn-extract-17-14.exe">pgn-extract-17-14.exe</a></td>
+    <td>win32 binary of version 17-14 of the program.</td>
+    <td align="right">482419 bytes</td><td>Jun 29 2013</td>
+    </tr>
+
+    <tr>
+    <td><a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/pgn-extract-17-14.exe">pgn-extract-17-14c.exe</a></td>
+    <td>Alternative win32 binary of version 17-14 of the program (requires <a href="http://www.cygwin.com">cygwin</a>).</td>
+    <td align="right">386378 bytes</td><td>Jun 19 2013</td>
+    </tr>
+
+    <tr>
+    <td><a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/eco.zip">eco.zip</a></td>
+    <td>Zipped version of <a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/eco.pgn">eco.pgn</a>.</td>
+    <td align="right">32081 bytes</td><td>May 24 2013</td>
+    </tr>
+
+    <tr valign="top">
+    <td><a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/eco.pgn">eco.pgn</a></td>
+    <td>File of openings with PGN classification.<br>
+       This file is already included in the source archives.
+    </td>
+    <td align="right">254723 bytes</td><td>May 24 2013</td>
+    </tr>
+
+    <tr>
+    <td><a href="ftp://ftp.cs.kent.ac.uk/pub/djb/pgn-extract/COPYING">COPYING</a></td>
+    <td>GNU General Public License (version 1).</td>
+    <td align="right">12488 bytes</td><td>Dec 05  1997</td>
+    </tr>
+    </table>
+
+<h2>Feedback</h2>
+<p>Feedback and suggestions for further features are always welcome, although I can't always
+promise to undertake significant development work.
+<hr>
+    </div>
+  </div>
+
+  <div id="footer">
+<address>
+<p>&#169; 1994-2013 David J. Barnes<br />
+<a href="http://www.cs.kent.ac.uk/~djb/">My home page.</a><br />
+<a href="mailto:d.j.barnes@kent.ac.uk">d.j.barnes@kent.ac.uk</a><br />
+Last updated: 29th Jun 2013 - non-cygwin version of the Windows
+executable added.<br />
+</address>
+  </div>
+</div>
+</body>
+</html>
diff --git a/lex.c b/lex.c
new file mode 100644 (file)
index 0000000..2b1b60f
--- /dev/null
+++ b/lex.c
@@ -0,0 +1,1270 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#include <io.h>
+#ifndef R_OK
+#define R_OK 0
+#endif
+#else
+#include <unistd.h>
+#endif
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "lex.h"
+#include "moves.h"
+#include "lists.h"
+#include "decode.h"
+#include "lines.h"
+#include "grammar.h"
+#include "apply.h"
+#include "output.h"
+
+        /* Prototypes for the functions in this file. */
+static void save_string(const char *result);
+/* When a move is saved, what is known of its source and destination coordinates
+ * should also be saved.
+ */
+static void save_move(const unsigned char *move);
+static void save_q_castle(void);
+static void save_k_castle(void);
+static void terminate_input(void);
+static Boolean extract_yytext(const unsigned char *symbol_start,
+                              const unsigned char *linep);
+static Boolean open_input(const char *infile);
+static Boolean open_input_file(int file_number);
+
+static unsigned long line_number = 0;
+/* Keep track of the Recursive Annotation Variation level. */
+static unsigned RAV_level = 0;
+/* Keep track of the last move found. */
+static unsigned char last_move[MAX_MOVE_LEN+1];
+/* How many games we have extracted from this file. */
+static unsigned games_in_file = 0;
+
+/* Provide an input file pointer.
+ * This is intialised in init_lex_tables.
+ */
+static FILE *yyin = NULL;
+
+/* Define space for holding matched tokens. */
+#define MAX_YYTEXT 100
+static unsigned char yytext[MAX_YYTEXT+1];
+YYSTYPE yylval;
+
+#define MAX_CHAR 256
+#define ALPHA_DIST ('a'-'A')
+/* Table of symbol classifications. */
+static TokenType ChTab[MAX_CHAR];
+/* A boolean array as to whether a character is allowed in a move or not. */
+static short MoveChars[MAX_CHAR];
+
+/* Define a table to hold the list of tag strings and the corresponding
+ * TagName index. This is initialised in init_list_of_known_tags().
+ */
+static const char **TagList;
+static unsigned tag_list_length = 0;
+
+        /* Initialise the TagList. This should be stored in alphabetical order,
+         * by virtue of the order in which the _TAG values are defined.
+         */
+static void
+init_list_of_known_tags(void)
+{
+    unsigned i;
+    tag_list_length = ORIGINAL_NUMBER_OF_TAGS;
+    TagList = (const char **) MallocOrDie(tag_list_length*sizeof(*TagList));
+    /* Be paranoid and put a string in every entry. */
+    for(i = 0; i < tag_list_length; i++){
+        TagList[i] = "";
+    }
+    TagList[ANNOTATOR_TAG] = "Annotator";
+    TagList[BLACK_TAG] = "Black";
+    TagList[BLACK_ELO_TAG] = "BlackElo";
+    TagList[BLACK_NA_TAG] = "BlackNA";
+    TagList[BLACK_TITLE_TAG] = "BlackTitle";
+    TagList[BLACK_TYPE_TAG] = "BlackType";
+    TagList[BLACK_USCF_TAG] = "BlackUSCF";
+    TagList[BOARD_TAG] = "Board";
+    TagList[DATE_TAG] = "Date";
+    TagList[ECO_TAG] = "ECO";
+    TagList[PSEUDO_ELO_TAG] = "Elo";
+    TagList[EVENT_TAG] = "Event";
+    TagList[EVENT_DATE_TAG] = "EventDate";
+    TagList[EVENT_SPONSOR_TAG] = "EventSponsor";
+    TagList[FEN_TAG] = "FEN";
+    TagList[PSEUDO_FEN_PATTERN_TAG] = "FENPattern";
+    TagList[HASHCODE_TAG] = "HashCode";
+    TagList[LONG_ECO_TAG] = "LongECO";
+    TagList[MODE_TAG] = "Mode";
+    TagList[NIC_TAG] = "NIC";
+    TagList[OPENING_TAG] = "Opening";
+    TagList[PSEUDO_PLAYER_TAG] = "Player";
+    TagList[PLY_COUNT_TAG] = "PlyCount";
+    TagList[RESULT_TAG] = "Result";
+    TagList[ROUND_TAG] = "Round";
+    TagList[SECTION_TAG] = "Section";
+    TagList[SETUP_TAG] = "SetUp";
+    TagList[SITE_TAG] = "Site";
+    TagList[STAGE_TAG] = "Stage";
+    TagList[SUB_VARIATION_TAG] = "SubVariation";
+    TagList[TERMINATION_TAG] = "Termination";
+    TagList[TIME_TAG] = "Time";
+    TagList[TIME_CONTROL_TAG] = "TimeControl";
+    TagList[TOTAL_PLY_COUNT_TAG] = "TotalPlyCount";
+    TagList[UTC_DATE_TAG] = "UTCDate";
+    TagList[UTC_TIME_TAG] = "UTCTime";
+    TagList[VARIATION_TAG] = "Variation";
+    TagList[WHITE_TAG] = "White";
+    TagList[WHITE_ELO_TAG] = "WhiteElo";
+    TagList[WHITE_NA_TAG] = "WhiteNA";
+    TagList[WHITE_TITLE_TAG] = "WhiteTitle";
+    TagList[WHITE_TYPE_TAG] = "WhiteType";
+    TagList[WHITE_USCF_TAG] = "WhiteUSCF";
+}
+
+    /* Extend TagList to accomodate a new tag string.
+     * Return the current value of tag_list_length as its
+     * index, having incremented its value.
+     */
+static TagName
+make_new_tag(const char *tag)
+{   unsigned tag_index = tag_list_length;
+    tag_list_length++;
+    TagList = (const char **) ReallocOrDie((void *)TagList,
+                    tag_list_length*sizeof(*TagList));
+    TagList[tag_index] = copy_string(tag);
+    /* Ensure that the game header's tags array can accommodate
+     * the new tag.
+     */
+    increase_game_header_tags_length(tag_list_length);
+    return tag_index;
+}
+
+const char *
+tag_header_string(TagName tag)
+{
+    if(tag < tag_list_length){
+        return TagList[tag];
+    }
+    else{
+        fprintf(GlobalState.logfile,"Internal error in tag_header_string(%d)\n",
+                                tag);
+        return NULL;
+    }
+}
+
+        /* Initialise ChTab[], the classification of the initial characters
+         * of symbols.
+         * Initialise MoveChars, the classification of secondary characters
+         * of moves.
+         */
+void
+init_lex_tables(void)
+{   int i;
+
+    /* Assume standard input will be used, until we know otherwise. */
+    yyin = stdin;
+    init_list_of_known_tags();
+    /* Initialise ChTab[]. */
+    for(i = 0; i < MAX_CHAR; i++){
+        ChTab[i] = ERROR_TOKEN;
+    }
+    ChTab[' '] = WHITESPACE;
+    ChTab['\t'] = WHITESPACE;
+    /* Take account of DOS line-ends. */
+    ChTab['\r'] = WHITESPACE;
+    ChTab['['] = TAG_START;
+    ChTab[']'] = TAG_END;
+    ChTab['"'] = DOUBLE_QUOTE;
+    ChTab['{'] = COMMENT_START;
+    ChTab['}'] = COMMENT_END;
+    ChTab['$'] = NAG;
+    ChTab['!'] = ANNOTATE;
+    ChTab['?'] = ANNOTATE;
+    ChTab['+'] = CHECK_SYMBOL;
+    ChTab['#'] = CHECK_SYMBOL;
+    ChTab['.'] = DOT;
+    ChTab['('] = RAV_START;
+    ChTab[')'] = RAV_END;
+    ChTab['%'] = PERCENT;
+    ChTab['\\'] = ESCAPE;
+    ChTab['\0'] = EOS;
+    ChTab['*'] = STAR;
+    ChTab['-'] = DASH;
+
+    /* Operators allowed only in the tag file. */
+    ChTab['<'] = OPERATOR;
+    ChTab['>'] = OPERATOR;
+    ChTab['='] = OPERATOR;        /* Overloaded in MoveChars. */
+
+    for(i = '0'; i <= '9'; i++){
+        ChTab[i] = DIGIT;
+    }
+    for(i = 'A'; i <= 'Z'; i++){
+        ChTab[i] = ALPHA;
+        ChTab[i+ALPHA_DIST] = ALPHA;
+    }
+    ChTab['_'] = ALPHA;
+
+    /* Classify the Russian piece letters as ALPHA. */
+    ChTab[RUSSIAN_KNIGHT_OR_KING] = ALPHA; /* King and Knight. */
+    ChTab[RUSSIAN_KING_SECOND_LETTER] = ALPHA; /* King (second character). */
+    ChTab[RUSSIAN_QUEEN] = ALPHA; /* Queen. */
+    ChTab[RUSSIAN_ROOK] = ALPHA; /* Rook. */
+    ChTab[RUSSIAN_BISHOP] = ALPHA; /* Bishop. */
+
+    /* Initialise MoveChars[]. */
+    for(i = 0; i < MAX_CHAR; i++){
+        MoveChars[i] = 0;
+    }
+    /* Files. */
+    for(i = 'a'; i <= 'h'; i++){
+        MoveChars[i] = 1;
+    }
+    /* Ranks. */
+    for(i = '1'; i <= '8'; i++){
+        MoveChars[i] = 1;
+    }
+    /* Upper-case pieces. */
+    MoveChars['K'] = 1;
+    MoveChars['Q'] = 1;
+    MoveChars['R'] = 1;
+    MoveChars['N'] = 1;
+    MoveChars['B'] = 1;
+    /* Lower-case pieces. */
+    MoveChars['k'] = 1;
+    MoveChars['q'] = 1;
+    MoveChars['r'] = 1;
+    MoveChars['n'] = 1;
+    MoveChars['b'] = 1;
+    /* Other u-c Dutch/German characters. */
+    MoveChars['D'] = 1; /* Queen. */
+    MoveChars['T'] = 1; /* Rook. */
+    MoveChars['S'] = 1; /* Knight. */
+    MoveChars['P'] = 1; /* Knight. */
+    MoveChars['L'] = 1; /* Bishop. */
+    /* Russian characters. */
+    MoveChars[RUSSIAN_KNIGHT_OR_KING] = 1; /* King and Knight. */
+    MoveChars[RUSSIAN_KING_SECOND_LETTER] = 1; /* King (second character). */
+    MoveChars[RUSSIAN_QUEEN] = 1; /* Queen. */
+    MoveChars[RUSSIAN_ROOK] = 1; /* Rook. */
+    MoveChars[RUSSIAN_BISHOP] = 1; /* Bishop. */
+
+    /* Capture and square separators. */
+    MoveChars['x'] = 1;
+    MoveChars['X'] = 1;
+    MoveChars[':'] = 1;
+    MoveChars['-'] = 1;
+    /* Promotion character. */
+    MoveChars['='] = 1;
+    /* Castling. */
+    MoveChars['O'] = 1;
+    MoveChars['o'] = 1;
+    MoveChars['0'] = 1;
+    /* Allow a trailing p for ep. */
+    MoveChars['p'] = 1;
+}
+
+        /* Starting from linep in line, gather up the string until
+         * the closing quote.  Skip over the closing quote.
+         */
+LinePair
+gather_string(char *line, unsigned char *linep)
+{   LinePair resulting_line;
+    char ch;
+    unsigned len = 0;
+    char *str;
+
+    do{ ch = *linep++;
+        len++;
+        if(ch == '\\'){
+            /* Escape the next character. */
+            len++;
+            ch = *linep++;
+            if(ch != '\0'){
+              len++;
+              ch = *linep++;
+            }
+        }
+    } while((ch != '"') && (ch != '\0'));
+    /* The last one doesn't belong in the string. */
+    len--;
+    /* Allocate space for the result. */
+    str = MallocOrDie(len+1);
+    strncpy(str,(const char *) (linep-len-1),len);
+    str[len] = '\0';
+    /* Store it in yylval. */
+    yylval.token_string = str;
+
+    /* Make sure that the string was properly terminated, by
+     * looking at the last character examined.
+     */
+    if(ch == '\0'){
+        /* Too far. */
+        if(!GlobalState.skipping_current_game) {
+            fprintf(GlobalState.logfile,"Missing closing quote in %s\n",line);
+       }
+        if(len != 1){
+            /* Move back to the null. */
+            linep--;
+            str[len-1] = '\0';
+        }
+    }
+    else{
+        /* We have already skipped over the closing quote. */
+    }
+    resulting_line.line = line;
+    resulting_line.linep = linep;
+    resulting_line.token = STRING;
+    return resulting_line;
+}
+
+       /*
+        * Is ch of the given character class?
+        * External access to ChTab.
+        */
+Boolean
+is_character_class(unsigned char ch, TokenType character_class)
+{
+    return ChTab[ch] == character_class;
+}
+
+        /* Starting from linep in line, gather up a comment until
+         * the END_COMMENT.  Skip over the END_COMMENT.
+         */
+static LinePair
+gather_comment(char *line, unsigned char *linep)
+{   LinePair resulting_line;
+    char ch;
+    unsigned len = 0;
+    /* The string list in which the current comment will be gathered. */
+    StringList *current_comment = NULL;
+    /* The pointer to be returned. */
+    CommentList *comment;
+
+    do{
+        /* Restart a new segment. */
+        len = 0;
+        do{ ch = *linep++;
+            len++;
+        } while((ch != '}') && (ch != '\0'));
+        /* The last one doesn't belong in the comment. */
+        len--;
+        if(GlobalState.keep_comments){
+            char *comment_str;
+
+            /* Allocate space for the result. */
+            comment_str = (char *)MallocOrDie(len+1);
+            strncpy(comment_str,(const char *) (linep-len-1) ,len);
+            comment_str[len] = '\0';
+            current_comment = save_string_list_item(current_comment,comment_str);
+        }
+        if(ch == '\0'){
+            line = next_input_line(yyin);
+            linep = (unsigned char *) line;
+        }
+    } while((ch != '}') && (line != NULL));
+
+    /* Set up the structure to be returned. */
+    comment = MallocOrDie(sizeof(*comment));
+    comment->Comment = current_comment;
+    comment->next = NULL;
+    yylval.comment = comment;
+
+    resulting_line.line = line;
+    resulting_line.linep = linep;
+    resulting_line.token = COMMENT;
+    return resulting_line;
+}
+
+        /* Remember that 0 can start 0-1 and 0-0.
+         * Remember that 1 can start 1-0 and 1/2.
+         */
+static LinePair
+gather_possible_numeric(char *line, unsigned char *linep, char initial_digit)
+{   LinePair resulting_line;
+    TokenType token = MOVE_NUMBER;
+    /* Keep a record of where this token started. */
+    const unsigned char *symbol_start = linep-1;
+
+    if(initial_digit == '0'){
+        /* Could be castling or a result. */
+        if(strncmp((const char *) linep,"-1",2) == 0){
+            token = TERMINATING_RESULT;
+            save_string("0-1");
+            linep += 2;
+        }
+        else if(strncmp((const char *) linep,"-0-0",4) == 0){
+            token = MOVE;
+            save_q_castle();
+            linep += 4;
+        }
+        else if(strncmp((const char *) linep,"-0",2) == 0){
+            token = MOVE;
+            save_k_castle();
+            linep += 2;
+        }
+        else{
+            /* MOVE_NUMBER */
+        }
+    }
+    else if(initial_digit == '1'){
+        if(strncmp((const char *) linep,"-0",2) == 0){
+            token = TERMINATING_RESULT;
+            save_string("1-0");
+            linep += 2;
+        }
+        else if(strncmp((const char *) linep,"/2",2) == 0){
+            token = TERMINATING_RESULT;
+            linep += 2;
+            /* Check for the full form. */
+            if(strncmp((const char *) linep,"-1/2",4) == 0){
+                token = TERMINATING_RESULT;
+                linep += 4;
+            }
+            /* Make sure that the full form of the draw result
+             * is saved. 
+             */
+            save_string("1/2-1/2");
+        }
+        else{
+            /* MOVE_NUMBER */
+        }
+    }
+    else{
+        /* MOVE_NUMBER */
+    }
+    if(token == MOVE_NUMBER){
+        /* Gather the remaining digits. */
+        while(isdigit((unsigned) *linep)){
+            linep++;
+        }
+    }
+    if(token == MOVE_NUMBER){
+        /* Fill out the fields of yylval. */
+        if(extract_yytext(symbol_start,linep)){
+                yylval.move_number = 0;
+                (void) sscanf((const char *)yytext,"%u",&yylval.move_number);
+                /* Skip any trailing dots. */
+                while(*linep == '.'){
+                    linep++;
+                }
+            }
+        else{
+            token = NO_TOKEN;
+        }
+    }
+    else{
+        /* TERMINATING_RESULT and MOVE have already been dealt with. */
+    }
+    resulting_line.line = line;
+    resulting_line.linep = linep;
+    resulting_line.token = token;
+    return resulting_line;
+}
+
+    /* Look up tag_string in TagList[] and return its _TAG
+     * value or -1 if it isn't there.
+     * Although the strings are sorted initially, further
+     * tags identified in the source files will be appended
+     * without further sorting. So we cannot use a binary
+     * search on the list.
+     */
+static int
+identify_tag(const char *tag_string)
+{   unsigned tag_index;
+
+    for(tag_index = 0; tag_index < tag_list_length; tag_index++){
+        if(strcmp(tag_string,TagList[tag_index]) == 0){
+            return tag_index;
+        }
+    }
+    /* Not found. */
+    return -1;
+}
+
+        /* Starting from linep in line, gather up the tag name.
+         * Skip over any preceding white space.
+         */
+LinePair
+gather_tag(char *line, unsigned char *linep)
+{   LinePair resulting_line;
+    char ch;
+    unsigned len = 0;
+
+    do{
+        /* Check for end of line while skipping white space. */
+        if(*linep == '\0'){
+            line = next_input_line(yyin);
+            linep = (unsigned char *) line;
+        }
+        if(line != NULL) {
+            while(ChTab[(unsigned)*linep] == WHITESPACE){
+                linep++;
+            }
+        }
+    }
+    while((line != NULL) && (ChTab[(unsigned)*linep] == '\0'));
+
+    if(line != NULL){
+        ch = *linep++;
+        while(isalpha((unsigned) ch) || isdigit((unsigned) ch) || (ch == '_')){
+            len++;
+            ch = *linep++;
+        }
+        /* The last one wasn't part of the tag. */
+        linep--;
+        if(len > 0){
+            int tag_item;
+            char *tag_string;
+
+            /* Allocate space for the result. */
+            tag_string = MallocOrDie(len+1);
+            strncpy((char *)tag_string,(const char *)(linep-len),len);
+            tag_string[len] = '\0';
+            tag_item = identify_tag(tag_string);
+            if(tag_item < 0){
+                tag_item = make_new_tag(tag_string);
+            }
+            if(tag_item >= 0 && ((unsigned) tag_item) < tag_list_length){
+                yylval.tag_index = tag_item;
+                resulting_line.token = TAG;
+                (void) free((void *)tag_string);
+            }
+            else{
+                fprintf(GlobalState.logfile,
+                    "Internal error: invalid tag index %d in gather_tag.\n",
+                    tag_item);
+                exit(1);
+            }
+        }
+        else{
+            resulting_line.token = NO_TOKEN;
+        }
+    }
+    else{
+        resulting_line.token = NO_TOKEN;
+    }
+    resulting_line.line = line;
+    resulting_line.linep = linep;
+    return resulting_line;
+}
+
+static Boolean
+extract_yytext(const unsigned char *symbol_start,const unsigned char *linep)
+{   /* Whether the string fitted. */
+    Boolean Ok = TRUE;
+    long len = linep-symbol_start;
+
+    if(len < MAX_YYTEXT){
+        strncpy((char *) yytext,(const char *) symbol_start,len);
+        yytext[len] = '\0';
+    }
+    else{
+        strncpy((char *) yytext,(const char *) symbol_start,MAX_YYTEXT);
+        yytext[MAX_YYTEXT] = '\0';
+        if(!GlobalState.skipping_current_game)
+            fprintf(GlobalState.logfile,"Symbol %s exceeds length of %u.\n",
+                        yytext, MAX_YYTEXT);
+        Ok = FALSE;
+    }
+    return Ok;
+}
+
+        /* Identify the next symbol.
+         * Don't take any action on EOF -- leave that to next_token.
+         */
+static TokenType
+get_next_symbol(void)
+{   static char *line = NULL;
+    static unsigned char *linep = NULL;
+    /* The token to be returned. */
+    TokenType token;
+    LinePair resulting_line;
+
+    do{
+        /* Remember where in line the current symbol starts. */
+        const unsigned char *symbol_start;
+
+        /* Clear any remaining symbol. */
+        *yytext = '\0';
+        if(line == NULL){
+            line = next_input_line(yyin);
+            linep = (unsigned char *) line;
+            if(line != NULL){
+                token = NO_TOKEN;
+            }
+            else{
+                token = EOF_TOKEN;
+            }
+        }
+        else{
+            int next_char = *linep & 0x0ff;
+
+            /* Remember where we start. */
+            symbol_start = linep;
+            linep++;
+            token = ChTab[next_char];
+
+            switch(token){
+                case WHITESPACE:
+                    while(ChTab[(unsigned)*linep] == WHITESPACE)
+                        linep++;
+                    token = NO_TOKEN;
+                    break;
+                case TAG_START:
+                    resulting_line = gather_tag(line,linep);
+                    /* Pick up where we are now. */
+                    line = resulting_line.line;
+                    linep = resulting_line.linep;
+                    token = resulting_line.token;
+                    break;
+                case TAG_END:
+                    token = NO_TOKEN;
+                    break;
+                case DOUBLE_QUOTE:
+                    resulting_line = gather_string(line,linep);
+                    /* Pick up where we are now. */
+                    line = resulting_line.line;
+                    linep = resulting_line.linep;
+                    token = resulting_line.token;
+                    break;
+                case COMMENT_START:
+                    resulting_line = gather_comment(line,linep);
+                    /* Pick up where we are now. */
+                    line = resulting_line.line;
+                    linep = resulting_line.linep;
+                    token = resulting_line.token;
+                    break;
+                case COMMENT_END:
+                    if(!GlobalState.skipping_current_game) {
+                        fprintf(GlobalState.logfile,"Unmatched comment end.\n");
+                   }
+                    token = NO_TOKEN;
+                    break;
+                case NAG:
+                    while(isdigit((unsigned) *linep)){
+                        linep++;
+                    }
+                    if(extract_yytext(symbol_start,linep)){
+                        save_string((const char *) yytext);
+                    }
+                    else{
+                        token = NO_TOKEN;
+                    }
+                    break;
+                case ANNOTATE:
+                    /* Don't return anything in case of error. */
+                    token = NO_TOKEN;
+                    while(ChTab[(unsigned)*linep] == ANNOTATE){
+                        linep++;
+                    }
+                    if(extract_yytext(symbol_start,linep)){
+                        switch(yytext[0]){
+                            case '!':
+                                switch(yytext[1]){
+                                    case '!':
+                                        save_string("$3");
+                                        break;
+                                    case '?':
+                                        save_string("$5");
+                                        break;
+                                    default:
+                                        save_string("$1");
+                                        break;
+                                }
+                                token = NAG;
+                                break;
+                            case '?':
+                                switch(yytext[1]){
+                                    case '!':
+                                        save_string("$6");
+                                        break;
+                                    case '?':
+                                        save_string("$4");
+                                        break;
+                                    default:
+                                        save_string("$2");
+                                        break;
+                                }
+                                token = NAG;
+                                break;
+                        }
+                    }
+                    break;
+                case CHECK_SYMBOL:
+                    /* Allow ++ */
+                    while(ChTab[(unsigned)*linep] == CHECK_SYMBOL){
+                        linep++;
+                    }
+                    break;
+                case DOT:
+                    while(ChTab[(unsigned)*linep] == DOT)
+                        linep++;
+                    token = NO_TOKEN;
+                    break;
+                case PERCENT:
+                    /* Trash the rest of the line. */
+                    line = next_input_line(yyin);
+                    linep = (unsigned char *) line;
+                    token = NO_TOKEN;
+                    break;
+                case ESCAPE:
+                    /* @@@ What to do about this? */
+                    if(*linep != '\0'){
+                        linep++;
+                    }
+                    token = NO_TOKEN;
+                    break;
+                case ALPHA:
+                    /* Not all ALPHAs are move characters. */
+                    if(MoveChars[next_char]){
+                        /* Scan through the possible move characters. */
+                        while(MoveChars[*linep & 0x0ff]){
+                            linep++;
+                        }
+                        if(extract_yytext(symbol_start,linep)){
+                            /* Only classify it as a move if it
+                             * seems to be a complete move.
+                             */
+                            if(move_seems_valid(yytext)){
+                                save_move(yytext);
+                                token = MOVE;
+                            }
+                            else{
+                                if(!GlobalState.skipping_current_game){
+                                    print_error_context(GlobalState.logfile);
+                                    fprintf(GlobalState.logfile,
+                                                "Unknown move text %s.\n",yytext);
+                                }
+                                token = NO_TOKEN;
+                            }
+                        }
+                        else{
+                            token = NO_TOKEN;
+                        }
+                    }
+                    else{
+                        if(!GlobalState.skipping_current_game){
+                            print_error_context(GlobalState.logfile);
+                            fprintf(GlobalState.logfile,
+                                    "Unknown character %c (Hex: %x).\n",
+                                    next_char,next_char);
+                        }
+                        /* Skip any sequence of them. */
+                        while(ChTab[(unsigned)*linep] == ERROR_TOKEN)
+                            linep++;
+                    }
+                    break;
+                case DIGIT:
+                    /* Remember that 0 can start 0-1 and 0-0.
+                     * Remember that 1 can start 1-0 and 1/2.
+                     */
+                    resulting_line = gather_possible_numeric(
+                                        line,linep,next_char);
+                    /* Pick up where we are now. */
+                    line = resulting_line.line;
+                    linep = resulting_line.linep;
+                    token = resulting_line.token;
+                    break;
+                case EOF_TOKEN:
+                    break;
+                case RAV_START:
+                    RAV_level++;
+                    break;
+                case RAV_END:
+                    if(RAV_level > 0){
+                        RAV_level--;
+                    }
+                    else{
+                        if(!GlobalState.skipping_current_game){
+                            print_error_context(GlobalState.logfile);
+                            fprintf(GlobalState.logfile,"Too many ')' found.\n");
+                        }
+                        token = NO_TOKEN;
+                    }
+                    break;
+                case STAR:
+                    save_string("*");
+                    token = TERMINATING_RESULT;
+                    break;
+               case DASH:
+                   if(ChTab[(unsigned) *linep] == DASH) {
+                       linep++;
+                       save_move((const unsigned char *) NULL_MOVE_STRING);
+                       token = MOVE;
+                   }
+                   else {
+                        fprintf(GlobalState.logfile,"Single '-' not allowed.\n");
+                       print_error_context(GlobalState.logfile);
+                       token = NO_TOKEN;
+                   }
+                   break;
+                case EOS:
+                    /* End of the string. */
+                    line = next_input_line(yyin);
+                    linep = (unsigned char *) line;
+                    token = NO_TOKEN;
+                    break;
+                case ERROR_TOKEN:
+                    if(!GlobalState.skipping_current_game){
+                        print_error_context(GlobalState.logfile);
+                        fprintf(GlobalState.logfile,
+                                "Unknown character %c (Hex: %x).\n",
+                                next_char,next_char);
+                    }
+                    /* Skip any sequence of them. */
+                    while(ChTab[(unsigned)*linep] == ERROR_TOKEN)
+                        linep++;
+                    break;
+                case OPERATOR:
+                    print_error_context(GlobalState.logfile);
+                    fprintf(GlobalState.logfile,
+                        "Operator in illegal context: %c.\n",*symbol_start);
+                    /* Skip any sequence of them. */
+                    while(ChTab[(unsigned)*linep] == OPERATOR)
+                        linep++;
+                    token = NO_TOKEN;
+                    break;
+                default:
+                    if(!GlobalState.skipping_current_game){
+                        print_error_context(GlobalState.logfile);
+                        fprintf(GlobalState.logfile,
+                            "Internal error: Missing case for %d on char %x.\n",
+                            token,next_char);
+                    }
+                    token = NO_TOKEN;
+                    break;
+            }
+        }
+    } while(token == NO_TOKEN);
+    return token;
+}
+
+TokenType
+next_token(void)
+{   TokenType token = get_next_symbol();
+
+        /* Don't call yywrap if parsing the ECO file. */
+    while((token == EOF_TOKEN) && !GlobalState.parsing_ECO_file &&
+                        !yywrap()){
+        token = get_next_symbol();
+    }
+    return token;
+}
+
+        /* Return TRUE if token is one to skip when looking for
+         * the start or end of a game.
+         */
+static Boolean
+skip_token(TokenType token)
+{
+    switch(token){
+        case TERMINATING_RESULT:
+        case TAG:
+        case MOVE:
+        case EOF_TOKEN:
+            return FALSE;
+        default:
+            return TRUE;
+    }
+}
+
+        /* Skip tokens until the next game looks like it is
+         * about to start. This is signalled by
+         * a tag section a terminating result from the
+         * previous game, or a move.
+         */
+TokenType
+skip_to_next_game(TokenType token)
+{   
+    if(skip_token(token)){
+        GlobalState.skipping_current_game = TRUE;
+        do{
+            if(token == COMMENT){
+                /* Free the space. */
+                if((yylval.comment != NULL) &&
+                                (yylval.comment->Comment != NULL)){
+                    free_string_list(yylval.comment->Comment);
+                    free((void *)yylval.comment);
+                    yylval.comment = NULL;
+                }
+            }
+            token = next_token();
+        } while(skip_token(token));
+        GlobalState.skipping_current_game = FALSE;
+    }
+    return token;
+}
+
+        /* Save castling moves in a standard way. */
+static void
+save_q_castle(void)
+{
+    save_move((const unsigned char *) "O-O-O");
+}
+
+        /* Save castling moves in a standard way. */
+static void
+save_k_castle(void)
+{
+    save_move((const unsigned char *) "O-O");
+}
+
+        /* Make a copy of the matched text of the move. */
+static void
+save_move(const unsigned char *move)
+{
+    /* Decode the move into its components. */
+    yylval.move_details = decode_move(move);
+    /* Remember the last move. */
+    strcpy((char *) last_move,(const char *) move);
+}
+
+void
+restart_lex_for_new_game(void)
+{
+    *last_move = '\0';
+    RAV_level = 0;
+}
+
+        /* Make it possible to read multiple input files.
+         * These are held in list_of_files. The list
+         * is built up from the program's arguments.
+         */
+static int current_file_num = 0;
+    /* Keep track of the list of PGN files.  These will either be the
+     * remaining arguments once flags have been dealt with, or
+     * those read from -c and -f arguments.
+     */
+static FILE_LIST list_of_files = {
+        (const char **) NULL,
+        (SourceFileType *) NULL,
+        0, 0
+};
+
+    /* Return the index number of the current input file in list_of_files. */
+unsigned
+current_file_number(void)
+{
+    return current_file_num;
+}
+
+
+        /* Read a list of lines from fp. These are the names of files
+         * to be added to the existing list_of_files.
+         * list_of_files.list must have a (char *)NULL on the end.
+         */
+void
+add_filename_list_from_file(FILE *fp,SourceFileType file_type)
+{
+    if((list_of_files.files == NULL) || (list_of_files.max_files == 0)){
+         /* Allocate an initial number of pointers for the lines.
+          * This must always include an extra one for terminating NULL.
+          */
+         list_of_files.files = (const char **) MallocOrDie((INIT_LIST_SPACE+1)*
+                                                sizeof(const char *));
+         list_of_files.file_type = (SourceFileType *) MallocOrDie((INIT_LIST_SPACE+1)*
+                                                sizeof(SourceFileType));
+         list_of_files.max_files = INIT_LIST_SPACE;
+         list_of_files.num_files = 0;
+    }
+    if(list_of_files.files != NULL){
+        /* Find the first line. */
+        char *line = read_line(fp);
+
+        while(line != NULL){
+             if(non_blank_line(line)){
+                 add_filename_to_source_list(line,file_type);
+             }
+             else{
+                 (void) free((void *)line);
+             }
+             line = read_line(fp);
+        }
+     }
+}
+
+void
+add_filename_to_source_list(const char *filename,SourceFileType file_type)
+{    /* Where to put it. */
+     unsigned location = list_of_files.num_files;
+
+     if(access(filename,R_OK) != 0){
+         fprintf(GlobalState.logfile,"Unable to find %s\n",filename);
+         exit(1);
+     }
+     else{
+         /* Ok. */
+     }
+     /* See if there is room. */
+     if(list_of_files.num_files == list_of_files.max_files){
+         /* There isn't, so increase the amount of available space,
+          * ensuring that there is always an extra slot for the terminating
+          * NULL.
+          */
+        if((list_of_files.files == NULL) || (list_of_files.max_files == 0)){
+             /* Allocate an initial number of pointers for the lines.
+              * This must always include an extra one for terminating NULL.
+              */
+             list_of_files.files = (const char **) MallocOrDie((INIT_LIST_SPACE+1)*
+                                                    sizeof(const char *));
+             list_of_files.file_type = (SourceFileType *)
+                                MallocOrDie((INIT_LIST_SPACE+1)*
+                                                    sizeof(SourceFileType));
+             list_of_files.max_files = INIT_LIST_SPACE;
+             list_of_files.num_files = 0;
+        }
+        else{
+             list_of_files.files = (const char **)realloc((void *)list_of_files.files,
+                    (list_of_files.max_files+MORE_LIST_SPACE+1)*
+                                                    sizeof(const char *));
+             list_of_files.file_type = (SourceFileType *)
+                    realloc((void *)list_of_files.file_type,
+                    (list_of_files.max_files+MORE_LIST_SPACE+1)*
+                                                    sizeof(SourceFileType));
+             list_of_files.max_files += MORE_LIST_SPACE;
+            if((list_of_files.files == NULL) && (list_of_files.file_type == NULL)){
+                perror("");
+                abort();
+            }
+        }
+     }
+     /* We know that there is space. Ensure that CHECKFILEs are all
+      * stored before NORMALFILEs.
+      */
+     if(file_type == CHECKFILE){
+
+         for(location = 0; (location < list_of_files.num_files) &&
+                        (list_of_files.file_type[location] == CHECKFILE); location++){
+            /* Do nothing. */
+         }
+         if(location < list_of_files.num_files){
+            /* Put the new one here.
+             * Move the rest down.
+             */
+            unsigned j;
+
+            for(j = list_of_files.num_files; j > location; j--){
+                list_of_files.files[j] = list_of_files.files[j-1];
+                list_of_files.file_type[j] = list_of_files.file_type[j-1];
+            }
+        }
+    }
+    list_of_files.files[location] = copy_string(filename);
+    list_of_files.file_type[location] = file_type;
+    list_of_files.num_files++;
+    /* Keep the list properly terminated. */
+    list_of_files.files[list_of_files.num_files] = (char *) NULL;
+}
+
+        /* Use infile as the input source. */
+static Boolean
+open_input(const char *infile)
+{   
+    yyin = fopen(infile,"r");
+    if(yyin != NULL){
+        GlobalState.current_input_file = infile;
+        if(GlobalState.verbose){
+            fprintf(GlobalState.logfile,"Processing %s\n",
+                                GlobalState.current_input_file);
+        }
+    }
+    return yyin != NULL;
+}
+
+        /* Simple interface to open_input for the ECO file. */
+Boolean
+open_eco_file(const char *eco_file)
+{
+    return open_input(eco_file);
+}
+
+        /* Open the input file whose number is the argument. */
+static Boolean
+open_input_file(int file_number)
+{
+    /* Depending on the type of file, ensure that the
+     * current_file_type is set correctly.
+     */
+    if(open_input(list_of_files.files[file_number])){
+        GlobalState.current_file_type = list_of_files.file_type[file_number];
+        return TRUE;
+    }
+    else{
+        return FALSE;
+    }
+}
+
+        /* Open the first input file. */
+Boolean
+open_first_file(void)
+{   Boolean ok = TRUE;
+
+    if(list_of_files.num_files == 0){
+        /* Use standard input. */
+        yyin = stdin;
+        GlobalState.current_input_file = "stdin";
+        /* @@@ Should this be set?
+        GlobalState.current_file_type = NORMALFILE;
+         */
+        if(GlobalState.verbose){
+            fprintf(GlobalState.logfile,"Processing %s\n",
+                                GlobalState.current_input_file);
+        }
+    }
+    else if(open_input_file(0)){
+    }
+    else{
+        fprintf(GlobalState.logfile,
+                        "Unable to open the PGN file: %s\n",input_file_name(0));
+        ok = FALSE;
+    }
+    return ok;
+}
+
+        /* Return the name of the file corresponding to the given
+         * file number.
+         */
+const char *
+input_file_name(unsigned file_number)
+{
+    if(file_number >= list_of_files.num_files) {
+        return NULL;
+    }
+    else {
+        return list_of_files.files[file_number];
+    }
+}
+
+
+        /* Give some error information. */
+void
+print_error_context(FILE *fp)
+{
+    if(GlobalState.current_input_file != NULL){
+        fprintf(fp,"File %s: ",GlobalState.current_input_file);
+    }
+    fprintf(fp,"Line number: %lu\n",line_number);
+}
+
+
+        /* Make the given str accessible. */
+static void
+save_string(const char *str)
+{   const size_t len = strlen(str);
+    char *token;
+
+    token = MallocOrDie(len+1);
+    strcpy(token,str);
+    yylval.token_string = token;
+}
+
+        /* Return the next line of input from fp. */
+char *
+next_input_line(FILE *fp)
+{   /* Retain each line in turn, so as to be able to free it. */
+    static char *line = NULL;
+
+    if(line != NULL){
+        (void) free((void *)line);
+    }
+
+    line = read_line(fp);
+
+    if(line != NULL){
+        line_number++;
+    }
+    return line;
+}
+
+        /* Handle the end of a file. */
+int
+yywrap(void)
+{   int time_to_exit;
+
+    /* Beware of this being called in inappropriate circumstances. */
+    if(list_of_files.files == NULL){
+        /* There are no files. */
+        time_to_exit = 1;
+    }
+    else if(input_file_name(current_file_num) == NULL){
+        /* There was no last file! */
+        time_to_exit = 1;
+    }
+    else{
+        /* Close the input files.  */
+        terminate_input();
+        /* See if there is another. */
+        current_file_num++;
+        if(input_file_name(current_file_num) == NULL){
+            /* We have processed the last file. */
+            time_to_exit = 1;
+        }
+        else if(!open_input_file(current_file_num)){
+            fprintf(GlobalState.logfile,"Unable to open the PGN file: %s\n",
+                                        input_file_name(current_file_num));
+            time_to_exit = 1;
+        }
+        else{
+            /* Ok, we opened it. */
+            time_to_exit = 0;
+            /* Set everything up for a new file. */
+            /* Depending on the type of file, ensure that the
+             * current_file_type is set correctly.
+             */
+            GlobalState.current_file_type =
+                list_of_files.file_type[current_file_num];
+            restart_lex_for_new_game();
+            games_in_file = 0;
+            reset_line_number();
+        }
+    }
+    return time_to_exit;
+}
+
+
+    /* Reset the file's line number. */
+void
+reset_line_number(void)
+{
+    line_number = 0;
+}
+
+static void
+terminate_input(void)
+{
+    if((yyin != stdin) && (yyin != NULL)){
+        (void) fclose(yyin);
+        yyin = NULL;
+    }
+}
+
diff --git a/lex.h b/lex.h
new file mode 100644 (file)
index 0000000..a86c425
--- /dev/null
+++ b/lex.h
@@ -0,0 +1,89 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+        /* Define a type to make it easy to return where we are
+         * in the input line.  This type is returned from those functions
+         * that may modify the line/linep pair in next_token().
+         */
+typedef struct{
+    /* Start of the malloc'ed line. */
+    char *line;
+    /* The next char to access in line, if line is not NULL. */
+    unsigned char *linep;
+    /* What token resulted. */
+    TokenType token;
+} LinePair;
+
+/* Define a type to hold a list of input files. */
+typedef struct {
+    /* The list should have a (char *)NULL on the end. */
+    const char **files;
+    SourceFileType *file_type;
+    /* Keep track of the number of files in the list. */
+    unsigned num_files;
+    /* Keep track of how many the list may hold. */
+    unsigned max_files;
+} FILE_LIST;
+
+#if 1
+#define RUSSIAN_KNIGHT_OR_KING (0x008a)
+#define RUSSIAN_KING_SECOND_LETTER (0x00e0)
+#define RUSSIAN_QUEEN (0x0094)
+#define RUSSIAN_ROOK (0x008b)
+#define RUSSIAN_BISHOP (0x0091)
+#define RUSSIAN_PAWN (0x00af)
+#else
+#define RUSSIAN_KNIGHT_OR_KING (0x00eb)
+#define RUSSIAN_KING_SECOND_LETTER (0x00d2)
+#define RUSSIAN_QUEEN (0x00e6)
+#define RUSSIAN_ROOK (0x00ec)
+#define RUSSIAN_BISHOP (0x00f3)
+#endif
+/* Define a macro for checking the value of a char against
+ * one of the Russian piece letters.
+ */
+#define RUSSIAN_PIECE_CHECK(c) ((c) & 0x00ff)
+
+    /* Shared prototypes for the non-static functions in the
+     * lexical analyser.
+     */
+void yyerror(const char *s);
+void save_assessment(const char *assess);
+void restart_lex_for_new_game(void);
+void free_move_list(Move *move_list);
+void print_error_context(FILE *fp);
+void init_lex_tables(void);
+TokenType next_token(void);
+TokenType skip_to_next_game(TokenType token);
+const char *tag_header_string(TagName tag);
+Boolean open_first_file(void);
+const char *input_file_name(unsigned file_number);
+unsigned current_file_number(void);
+Boolean open_eco_file(const char *eco_file);
+int yywrap(void);
+void add_filename_to_source_list(const char *filename,SourceFileType file_type);
+void add_filename_list_from_file(FILE *fp,SourceFileType file_type);
+void reset_line_number(void);
+char *next_input_line(FILE *fp);
+LinePair gather_tag(char *line, unsigned char *linep);
+LinePair gather_string(char *line, unsigned char *linep);
+Boolean is_character_class(unsigned char ch, TokenType character_class);
diff --git a/lines.c b/lines.c
new file mode 100644 (file)
index 0000000..5d45e17
--- /dev/null
+++ b/lines.c
@@ -0,0 +1,115 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "lines.h"
+
+    /* Read a single line of input. */
+#define INIT_LINE_LENGTH 80
+#define LINE_INCREMENT 20
+
+/* Define a character that may be used to comment a line in, e.g.
+ * the variations files.
+ * Use the PGN escape mechanism character, for consistency.
+ */
+#define COMMENT_CHAR '%'
+
+char *
+read_line(FILE *fpin)
+{   char *line = NULL;
+    unsigned len = 0;
+    unsigned max_length;
+    int ch;
+
+     ch = getc(fpin);
+     if(ch != EOF){
+        line = (char *) MallocOrDie(INIT_LINE_LENGTH + 1);
+        max_length = INIT_LINE_LENGTH;
+        while((ch != '\n') && (ch != '\r') && (ch != EOF)){
+            /* Another character to add. */
+            if(len == max_length){
+                 line = (char *)ReallocOrDie((void *)line,
+                                            max_length+LINE_INCREMENT+1);
+                 if(line == NULL){
+                     return NULL;
+                 }
+                 max_length += LINE_INCREMENT;
+            }
+            line[len] = ch;
+            len++;
+            ch = getc(fpin);
+        }
+        line[len] = '\0';
+       if(ch == '\r') {
+           /* Try to avoid double counting lines in dos-format files. */
+           ch = getc(fpin);
+           if(ch != '\n' && ch != EOF) {
+               ungetc(ch, fpin);
+           }
+       }
+     }
+     return line;
+}
+
+        /* Return TRUE if line contains a non-space character, but
+         * is not a comment line.
+         */
+Boolean
+non_blank_line(const char *line)
+{   Boolean blank = TRUE;
+
+    if(line != NULL){
+        if(comment_line(line)){
+            /* Comment lines count as blanks. */
+        }
+        else{
+            while(blank && (*line != '\0')){
+                if(!isspace((int) *line)){
+                    blank = FALSE;
+                }
+                else{
+                    line++;
+                }
+            }
+        }
+    }
+    return !blank;
+}
+
+Boolean
+blank_line(const char *line)
+{
+    return !non_blank_line(line);
+}
+
+
+        /* Should the given line be regarded as a comment line? */
+Boolean
+comment_line(const char *line)
+{
+    return *line == COMMENT_CHAR;
+}
diff --git a/lines.h b/lines.h
new file mode 100644 (file)
index 0000000..b957132
--- /dev/null
+++ b/lines.h
@@ -0,0 +1,26 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+char *read_line(FILE *fpin);
+Boolean non_blank_line(const char *line);
+Boolean blank_line(const char *line);
+Boolean comment_line(const char *line);
diff --git a/lists.c b/lists.c
new file mode 100644 (file)
index 0000000..7ffd8c2
--- /dev/null
+++ b/lists.c
@@ -0,0 +1,657 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "lists.h"
+#include "taglist.h"
+
+    /* Define a type to permit tag strings to be associated with
+     * a TagOperator for selecting relationships between them
+     * and a game to be matched.
+     */
+typedef struct{
+    char *tag_string;
+    TagOperator operator;
+} TagSelection;
+
+    /* Definitions for maintaining arrays of tag strings.
+     * These arrays are used for various purposes:
+     *        lists of white/black players to extract on.
+     *        lists of other criteria to extract on.
+     */
+
+typedef struct {
+    /* How many elements we have currently allocated for.
+     * If this is > 0 then we should always have allocated exactly
+     * one more than this number to simplify the (char **)NULL
+     * termination of the list.
+     */
+    unsigned num_allocated_elements;
+    /* num_used_elements should always be <= num_allocated elements. */
+    unsigned num_used_elements;
+    /* The list of elements.
+     * Elements 0 .. num_used_elements point to null-terminated strings.
+     * list[num_used_elements] == (char **)NULL once the list is complete.
+     */
+    TagSelection *tag_strings;
+} StringArray;
+
+        /* Functions to allow creation of string lists. */
+/* Allow a string list for every known tag.
+ * It is important that these lists should be initialised to
+ *         { 0, 0, (TagSelection *) NULL }
+ * which happens by default, anyway.
+ * This array, and its length (tag_list_length) are initialised
+ * by calling init_tag_lists.
+ */
+static StringArray *TagLists;
+static int tag_list_length  =  0;
+
+static char *soundex(const char *str);
+static Boolean CheckList(int tag,const char *tag_string,StringArray *list);
+
+void init_tag_lists(void)
+{
+    int i;
+    tag_list_length = ORIGINAL_NUMBER_OF_TAGS;
+    TagLists = (StringArray *) MallocOrDie(tag_list_length*sizeof(*TagLists));
+    for(i = 0; i < tag_list_length; i++){
+        TagLists[i].num_allocated_elements  = 0;
+        TagLists[i].num_used_elements  = 0;
+        TagLists[i].tag_strings  = (TagSelection *) NULL;
+    }
+}
+
+    /*
+     * Extend the tag list to the new length.
+     */
+static void
+extend_tag_list_length(int new_length)
+{
+    if(new_length < tag_list_length){
+        fprintf(GlobalState.logfile,
+                "Internal error: inappropriate call to extend_tag_list_length().\n");
+        fprintf(GlobalState.logfile,
+                "New length of %d is not greater than existing length of %d\n",
+                new_length,tag_list_length);
+        exit(1);
+    }
+    else{
+        int i;
+        TagLists = (StringArray *) ReallocOrDie((void *) TagLists,
+                                           new_length*sizeof(*TagLists));
+        for(i = tag_list_length; i < new_length; i++){
+             TagLists[i].num_allocated_elements  = 0;
+             TagLists[i].num_used_elements  = 0;
+             TagLists[i].tag_strings  = (TagSelection *) NULL;
+        }
+        tag_list_length = new_length;
+    }
+}
+
+        /* Add str to the list of strings in list.
+         * List may be a new list, in which case space is allocated
+         * for it.
+         * Return the index on success, otherwise -1.
+         */
+static int
+add_to_taglist(const char *str,StringArray *list)
+{   Boolean everything_ok = TRUE;
+
+    if(list->num_allocated_elements == list->num_used_elements){
+        /* We need more space. */
+        if(list->num_allocated_elements == 0){
+            /* No elements in the list. */
+            list->tag_strings = (TagSelection *)MallocOrDie((INIT_LIST_SPACE+1)*
+                                                sizeof(TagSelection));
+            if(list->tag_strings != NULL){
+                list->num_allocated_elements = INIT_LIST_SPACE;
+                list->num_used_elements = 0;
+            }
+            else{
+                everything_ok = FALSE;
+            }
+        }
+        else{
+            list->tag_strings = (TagSelection *)realloc((void *)list->tag_strings,
+                                (list->num_allocated_elements+MORE_LIST_SPACE+1)*
+                                                        sizeof(TagSelection));
+            if(list->tag_strings != NULL){
+                list->num_allocated_elements += MORE_LIST_SPACE;
+            }
+            else{
+                everything_ok = FALSE;
+            }
+        }
+    }
+    if(everything_ok){
+        /* There is space. */
+        unsigned ix = list->num_used_elements;
+
+        list->tag_strings[ix].operator = NONE;
+        list->tag_strings[ix].tag_string = (char *) MallocOrDie(strlen(str)+1);
+        if(list->tag_strings[ix].tag_string != NULL){
+            strcpy(list->tag_strings[ix].tag_string,str);
+            list->num_used_elements++;
+            /* Make sure that the list is properly terminated at all times. */
+            list->tag_strings[ix+1].tag_string = NULL;
+            return (int) ix;
+        }
+        else{
+            return -1;
+        }
+    }
+    else{
+        return -1;
+    }
+}
+
+    /* Simple soundex code supplied by John Brogan
+     * (jwbrogan@unix2.netaxs.com), 26th Aug 1994.
+     * John writes:
+     * "In recognition of the large number of strong players from countries
+     * with Slavic based languages, I tried to tailor the soundex code
+     * to match any reasonable transliteration of a Slavic name into
+     * English.  Thus, Nimzovich will match Nimsowitsch, Tal will match
+     * Talj, etc.  Unfortunately, in order to be sure not to miss any
+     * valid matches, I had to make the code so tolerant that it sometimes
+     * comes up with some wildly false matches.  This, to me, is better
+     * than missing some games, but your mileage may differ."
+     *
+     * This looks like it was originally derived from the public domain
+     * version released by N. Dean Pentcheff, 1989, which was, itself,
+     * based on that in D.E. Knuth's "The art of computer programming.",
+     * Volume 3: Sorting and searching.  Addison-Wesley Publishing Company:
+     * Reading, Mass. Page 392.
+     * Amended by David Barnes, 2nd Sep 1994.
+     */
+
+/* Define a maximum length for the soundex result. */
+#define MAXSOUNDEX 50
+
+        /* Calculate a soundex string for instr.
+         * The space used is statically allocated, so the caller
+         * will have to allocate its own for the result if it
+         * to be retained across different calls.
+         */
+static char *
+soundex(const char *str)
+{   static char sbuf[MAXSOUNDEX+1];
+    /* An index into sbuf. */
+    unsigned sindex = 0;
+    /* Keep track of the last character to compress repeated letters. */
+    char lastc = ' ';
+    /*                     ABCDEFGHIJKLMNOPQRSTUVWXYZ */
+    const char *mapping = "01230120002455012622011202";
+    char initial_letter = *str;
+
+    /* Special case for names that begin with 'J',
+     * otherwise Janosevic == Nimzovich.
+     * In addition, we really want Yusupov to match Jusupov.
+     */
+    if(islower((int) initial_letter)){
+        initial_letter = toupper(initial_letter);
+    }
+    if((initial_letter == 'Y') || (initial_letter == 'J')){
+          sbuf[sindex] = '7';
+          str++;
+          sindex++;
+    }
+
+    while((*str != '\0') && (sindex < MAXSOUNDEX)){
+        char ch = *str;
+
+        /* We are only interested in alphabetics, and duplicate
+         * characters are reduced to singletons.
+         */
+        if(isalpha((int) ch) && (ch != lastc)){
+             char translation;
+
+             if(islower((int) ch)){
+                 ch = toupper(ch);
+             }
+             /* Pick up the translation. */
+             translation = mapping[ch - 'A'];
+             if((translation != '0') && (translation != lastc)){
+                sbuf[sindex] = translation;
+                sindex++;
+                lastc = translation;
+             }
+        }
+        str++; 
+    }
+    sbuf[sindex] = '\0';
+    return(sbuf);
+}
+
+        /* Return TRUE if tag is one on which soundex matching should
+         * be used, if requested.
+         */
+static Boolean
+soundex_tag(int tag)
+{   Boolean use_soundex = FALSE;
+
+    switch(tag){
+        case WHITE_TAG:
+        case BLACK_TAG:
+        case PSEUDO_PLAYER_TAG:
+        case EVENT_TAG:
+        case SITE_TAG:
+        case ANNOTATOR_TAG:
+            use_soundex = TRUE;
+            break;
+    }
+    return use_soundex;
+}
+
+        /* Add tagstr to the list of tags to be matched.
+         * If we are using soundex matching, then store
+         * its soundex version rather than its plain text.
+         */
+void
+add_tag_to_list(int tag,const char *tagstr,TagOperator operator)
+{
+    if(tag >= tag_list_length){
+        /* A new tag - one without a pre-defined _TAG #define.
+         * Make sure there is room for it in TagList.
+         */
+        extend_tag_list_length(tag+1);
+    }
+    if((tag >= 0) && (tag < tag_list_length)){
+        const char *string_to_store = tagstr;
+        int ix;
+
+        if(GlobalState.use_soundex){
+            if(soundex_tag(tag)){
+                string_to_store = soundex(tagstr);
+            }
+        }
+        ix = add_to_taglist(string_to_store,&TagLists[tag]);
+        if(ix >= 0){
+            TagLists[tag].tag_strings[ix].operator = operator;
+        }
+        /* Ensure that we know we are checking tags. */
+        GlobalState.check_tags = TRUE;
+    }
+    else{
+        fprintf(GlobalState.logfile,
+                "Illegal tag number %d in add_tag_to_list.\n",tag);
+    }
+}
+
+        /* Argstr is an extraction argument.
+         * The type of argument is indicated by the first letter of
+         * argstr:
+         *        a -- annotator of the game
+         *        b -- player of the black pieces
+         *        d -- date of the game
+         *        e -- ECO code
+         *        p -- player of either colour
+         *        r -- result
+         *        w -- player of the white pieces
+         * The remainder of argstr is the argument string to be entered
+         * into the appropriate list.
+         */
+void
+extract_tag_argument(const char *argstr)
+{   const char *arg = &(argstr[1]);
+
+    switch(*argstr){
+        case 'a':
+            add_tag_to_list(ANNOTATOR_TAG,arg,NONE);
+            break;
+        case 'b':
+            add_tag_to_list(BLACK_TAG,arg,NONE);
+            break;
+        case 'd':
+            add_tag_to_list(DATE_TAG,arg,NONE);
+            break;
+        case 'e':
+            add_tag_to_list(ECO_TAG,arg,NONE);
+            break;
+        case 'h':
+            add_tag_to_list(HASHCODE_TAG,arg,NONE);
+            break;
+        case 'p':
+            add_tag_to_list(PSEUDO_PLAYER_TAG,arg,NONE);
+            break;
+        case 'r':
+            add_tag_to_list(RESULT_TAG,arg,NONE);
+            break;
+        case 'w':
+            add_tag_to_list(WHITE_TAG,arg,NONE);
+            break;
+        default:
+            fprintf(GlobalState.logfile,
+                    "Unknown type of tag extraction argument: %s\n",
+                        argstr);
+            exit(1);
+            break;
+    }
+}
+
+        /* Check for one of list->strings matching the date_string.
+         * Return TRUE on match, FALSE on failure.
+         * It is only necessary for a prefix of tag to match
+         * the string.
+         */
+
+/* Set limits on the allowable ranges for dates extracted from games.
+ * Because of century changes, it is difficult to know what
+ * best to do with two digit year numbers; so exclude them.
+ */
+#define MINDATE 100
+#define MAXDATE 3000
+
+static Boolean
+CheckDate(const char *date_string,StringArray *list)
+{   unsigned list_index;
+
+    /* Care needed because dates with operators must be ANDed and
+     * dates without operators must be ORed.
+     * The first match is used to set wanted properly for the first time.
+     */
+    Boolean wanted = FALSE;
+    for(list_index = 0; list_index < list->num_used_elements; list_index++){
+        const char *list_string = list->tag_strings[list_index].tag_string;
+        TagOperator operator = list->tag_strings[list_index].operator;
+
+        if(*list_string == 'b'){
+            operator = LESS_THAN;
+            list_string++;
+        }
+        else if(*list_string == 'a'){
+            operator = GREATER_THAN;
+            list_string++;
+        }
+        else{
+            /* No prefix. */
+        }
+        if(operator != NONE){
+            /* We have a relational comparison. */
+            unsigned game_date, list_date;
+            /* Try to extract dates from both strings. */
+            if((sscanf(list_string,"%u",&list_date) == 1) &&
+                  (sscanf(date_string,"%u",&game_date) == 1) &&
+                  (game_date > MINDATE) && (game_date < MAXDATE)){
+               Boolean matches;
+                switch(operator){
+                    case LESS_THAN:
+                        matches = game_date < list_date;
+                        break;
+                    case LESS_THAN_OR_EQUAL_TO:
+                        matches = game_date <= list_date;
+                        break;
+                    case GREATER_THAN:
+                        matches = game_date > list_date;
+                        break;
+                    case GREATER_THAN_OR_EQUAL_TO:
+                        matches = game_date >= list_date;
+                        break;
+                    case EQUAL_TO:
+                        matches = game_date == list_date;
+                        break;
+                    case NOT_EQUAL_TO:
+                        matches = game_date != list_date;
+                        break;
+                    case NONE:
+                   default:
+                        /* Should have been covered above. */
+                       matches = FALSE;
+                        break;
+                }
+               if(list_index == 0) {
+                   wanted = matches;
+               }
+               else {
+                   wanted = wanted && matches;
+               }
+            }
+            else{
+                /* Bad format, or out of range. Assume not wanted. */
+               wanted = FALSE;
+            }
+        }
+        else{
+           /* No need to check if we already have a match. */
+           if(list_index == 0 || !wanted) {
+               /* Just a straight prefix match. */
+               wanted = strncmp(date_string,list_string,strlen(list_string)) == 0;
+           }
+        }
+    }
+    return wanted;
+}
+
+static Boolean
+CheckElo(const char *elo_string,StringArray *list)
+{   unsigned list_index;
+    Boolean wanted = TRUE;
+
+    for(list_index = 0; (list_index < list->num_used_elements) && wanted;
+                                list_index++){
+        const char *list_string = list->tag_strings[list_index].tag_string;
+        TagOperator operator = list->tag_strings[list_index].operator;
+
+        if(operator != NONE){
+            /* We have a relational comparison. */
+            unsigned game_elo, list_elo;
+            /* Try to extract elos from both strings. */
+            if((sscanf(list_string,"%u",&list_elo) == 1) &&
+                  (sscanf(elo_string,"%u",&game_elo) == 1)){
+                switch(operator){
+                    case LESS_THAN:
+                        wanted = game_elo < list_elo;
+                        break;
+                    case LESS_THAN_OR_EQUAL_TO:
+                        wanted = game_elo <= list_elo;
+                        break;
+                    case GREATER_THAN:
+                        wanted = game_elo > list_elo;
+                        break;
+                    case GREATER_THAN_OR_EQUAL_TO:
+                        wanted = game_elo >= list_elo;
+                        break;
+                    case EQUAL_TO:
+                        wanted = game_elo == list_elo;
+                        break;
+                    case NOT_EQUAL_TO:
+                        wanted = game_elo != list_elo;
+                        break;
+                    case NONE:
+                        /* Already covered above. */
+                        break;
+                }
+            }
+            else{
+                /* Bad format, or out of range. Assume not wanted. */
+                wanted = FALSE;
+            }
+        }
+        else{
+            /* Just a straight prefix match. */
+            if(strncmp(elo_string,list_string,strlen(list_string)) == 0){
+                wanted = TRUE;
+            }
+        }
+    }
+    return wanted;
+}
+
+        /* Check for one of list->strings matching the tag.
+         * Return TRUE on match, FALSE on failure.
+         * It is only necessary for a prefix of tag to match
+         * the string.
+         */
+static Boolean
+CheckList(int tag,const char *tag_string,StringArray *list)
+{   unsigned list_index;
+    Boolean wanted = FALSE;
+    const char *search_str;
+
+    if(GlobalState.use_soundex && soundex_tag(tag)){
+        search_str = soundex(tag_string);
+    }
+    else{
+        search_str = tag_string;
+    }
+    for(list_index = 0; (list_index < list->num_used_elements) && !wanted;
+                                list_index++){
+        const char *list_string = list->tag_strings[list_index].tag_string;
+
+        if(strncmp(search_str,list_string,strlen(list_string)) == 0){
+            wanted = TRUE;
+        }
+    }
+    return wanted;
+}
+
+        /* Check the Tag Details of this current game against those in
+         * the wanted lists. Check all details apart from any ECO
+         * tag as this is checked separately by CheckECOTag.
+         * An empty list implies that there is no restriction on
+         * the values in the corresponding tag field.
+         * In consequence, completely empty lists imply that all
+         * games reaching this far are wanted.
+         * Return TRUE if wanted, FALSE otherwise.
+         */
+Boolean
+CheckTagDetailsNotECO(char *Details[],int num_details)
+{   Boolean wanted = TRUE;
+    int tag;
+
+    if(GlobalState.check_tags){
+        /* Sanity check. */
+        if(num_details < tag_list_length){
+            fprintf(GlobalState.logfile,
+                   "Internal error: mismatch in tag set lengths in ");
+            fprintf(GlobalState.logfile,
+                   "CheckTagDetailsNotECO: %d vs %d\n",
+                   num_details,tag_list_length);
+            exit(1);
+        }
+
+        /* PSEUDO_PLAYER_TAG and PSEUDO_ELO_TAG are treated differently,
+         * since they have the effect of or-ing together the WHITE_ and BLACK_ lists.
+         * Otherwise, different tag lists are and-ed.
+         */
+        if(TagLists[PSEUDO_PLAYER_TAG].num_used_elements != 0){
+            /* Check both the White and Black lists. */
+            if(Details[WHITE_TAG] != NULL){
+                wanted = CheckList(WHITE_TAG,Details[WHITE_TAG],
+                                    &TagLists[PSEUDO_PLAYER_TAG]);
+                /* If we didn't find a player there, try for the opponent. */
+                if(!wanted && (Details[BLACK_TAG] != NULL)){
+                    wanted = CheckList(BLACK_TAG,Details[BLACK_TAG],
+                                    &TagLists[PSEUDO_PLAYER_TAG]);
+                }
+            }
+            else if(Details[BLACK_TAG] != NULL){
+                wanted = CheckList(BLACK_TAG,Details[BLACK_TAG],
+                                    &TagLists[PSEUDO_PLAYER_TAG]);
+            }
+            else{
+                wanted = FALSE;
+            }
+        }
+        else if(TagLists[PSEUDO_ELO_TAG].num_used_elements != 0){
+            /* Check both the White and Black lists. */
+            if(Details[WHITE_ELO_TAG] != NULL){
+                wanted = CheckElo(Details[WHITE_ELO_TAG],
+                                    &TagLists[PSEUDO_ELO_TAG]);
+                /* If we didn't find a player there, try for the opponent. */
+                if(!wanted && (Details[BLACK_ELO_TAG] != NULL)){
+                    wanted = CheckElo(Details[BLACK_ELO_TAG],
+                                    &TagLists[PSEUDO_ELO_TAG]);
+                }
+            }
+            else if(Details[BLACK_ELO_TAG] != NULL){
+                wanted = CheckElo(Details[BLACK_ELO_TAG],
+                                    &TagLists[PSEUDO_ELO_TAG]);
+            }
+            else{
+                wanted = FALSE;
+            }
+        }
+        else{
+            /* No PSEUDO_*_TAG info to check. */
+        }
+
+        /* Check the remaining tags in turn as long as we still have a match. */
+        for(tag = 0; (tag < tag_list_length) && wanted; tag++){
+            if(tag == PSEUDO_PLAYER_TAG){
+            }
+            else if(tag == PSEUDO_ELO_TAG){
+            }
+            else if(tag == ECO_TAG){
+                /* This is handled separately. */
+            }
+            else if(TagLists[tag].num_used_elements != 0){
+                if(Details[tag] != NULL){
+                    if(tag == DATE_TAG){
+                        wanted = CheckDate(Details[tag],&TagLists[tag]);
+                    }
+                    else if((tag == WHITE_ELO_TAG) || (tag == BLACK_ELO_TAG)){
+                        wanted = CheckElo(Details[tag],&TagLists[tag]);
+                    }
+                    else{
+                        wanted = CheckList(tag,Details[tag],&TagLists[tag]);
+                    }
+                }
+                else{
+                    /* Required tag not present. */
+                    wanted = FALSE;
+                }
+            }
+            else{
+                /* Not used. */
+            }
+        }
+    }
+    return wanted;
+}
+
+        /* Check just the ECO tag from the game's tag details. */
+Boolean
+CheckECOTag(char *Details[])
+{   Boolean wanted = TRUE;
+
+    if(GlobalState.check_tags){
+        if(TagLists[ECO_TAG].num_used_elements != 0){
+            if(Details[ECO_TAG] != NULL){
+                wanted = CheckList(ECO_TAG,Details[ECO_TAG],&TagLists[ECO_TAG]);
+            }
+            else{
+                /* Required tag not present. */
+                wanted = FALSE;
+            }
+        }
+    }
+    return wanted;
+}
diff --git a/lists.h b/lists.h
new file mode 100644 (file)
index 0000000..ba2ac55
--- /dev/null
+++ b/lists.h
@@ -0,0 +1,46 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+        /* Define values for the amount of space to initially malloc
+         * and incrementally realloc in a list.
+         */
+#define INIT_LIST_SPACE 10
+#define MORE_LIST_SPACE 5
+
+        /* Tags to be sought may have an operator to specify the
+         * relationship between value in the tag list and that in
+         * the game. For instance, in order to find games before 1962
+         * use Date < "1962". The < turns into a LESS_THAN operator.
+         * Potentially any tag may have an operator, but not all make
+         * sense in all circumstances.
+         */
+typedef enum {
+    NONE,
+    LESS_THAN, GREATER_THAN, EQUAL_TO, NOT_EQUAL_TO,
+    LESS_THAN_OR_EQUAL_TO, GREATER_THAN_OR_EQUAL_TO
+} TagOperator;
+
+void extract_tag_argument(const char *argstr);
+void add_tag_to_list(int tag,const char *tagstr,TagOperator operator);
+Boolean CheckTagDetailsNotECO(char *Details[],int num_details);
+Boolean CheckECOTag(char *Details[]);
+void init_tag_lists(void);
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..5439f11
--- /dev/null
+++ b/main.c
@@ -0,0 +1,367 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2012 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "lex.h"
+#include "moves.h"
+#include "map.h"
+#include "lists.h"
+#include "output.h"
+#include "end.h"
+#include "grammar.h"
+#include "hashing.h"
+#include "argsfile.h"
+
+/* The maximum length of an output line.  This is conservatively
+ * slightly smaller than the PGN export standard of 80.
+ */
+#define MAX_LINE_LENGTH 75
+
+/* Define a file name relative to the current directory representing
+ * a file of ECO classificiations.
+ */
+#ifndef DEFAULT_ECO_FILE
+#define DEFAULT_ECO_FILE "eco.pgn"
+#endif
+
+    /* This structure holds details of the program state
+     * available to all parts of the program.
+     * This goes against the grain of good structured programming
+     * principles, but most of these fields are set from the program's
+     * arguments and are read-only thereafter. If I had done this in
+     * C++ there would have been a cleaner interface!
+     */
+StateInfo GlobalState = {
+    FALSE,                /* skipping_current_game */
+    FALSE,                /* check_only (-r) */
+    TRUE,                 /* verbose (-s) */
+    TRUE,                 /* keep_NAGs (-N) */
+    TRUE,                 /* keep_comments (-C) */
+    TRUE,                 /* keep_variations (-V) */
+    ALL_TAGS,             /* tag_output_form (-7, --notags) */
+    TRUE,                 /* match_permutations (-v) */
+    FALSE,                /* positional_variations (-x) */
+    FALSE,                /* use_soundex (-S) */
+    FALSE,                /* suppress_duplicates (-D) */
+    FALSE,                /* suppress_originals (-U) */
+    FALSE,               /* fuzzy_match_duplicates (--fuzzy) */
+    0,                   /* fuzzy_match_depth (--fuzzy) */
+    FALSE,                /* check_tags */
+    FALSE,                /* add_ECO (-e) */
+    FALSE,                /* parsing_ECO_file (-e) */
+    DONT_DIVIDE,          /* ECO_level (-E) */
+    SAN,                  /* output_format (-W) */
+    MAX_LINE_LENGTH,      /* max_line_length (-w) */
+    FALSE,                /* use_virtual_hash_table (-Z) */
+    FALSE,                /* check_move_bounds (-b) */
+    FALSE,                /* match_only_checkmate (-M) */
+    FALSE,                /* match_only_stalemate (--stalemate) */
+    TRUE,                 /* keep_move_numbers (--nomovenumbers) */
+    TRUE,                 /* keep_results (--noresults) */
+    TRUE,                 /* keep_checks (--nochecks) */
+    FALSE,                /* output_evaluation (--evaluation) */
+    FALSE,                /* keep_broken_games (--keepbroken) */
+    0,                    /* depth_of_positional_search */
+    0,                    /* num_games_processed */
+    0,                    /* num_games_matched */
+    0,                    /* games_per_file (-#) */
+    1,                    /* next_file_number */
+    0,                    /* lower_move_bound */
+    10000,                /* upper_move_bound */
+    -1,                   /* output_ply_limit (--plylimit) */
+    0,                    /* matching_game_number */
+    FALSE,                /* output_FEN_string */
+    FALSE,                /* add_FEN_comments (--fencomments) */
+    FALSE,                /* add_position_match_comments (--markmatches) */
+    FALSE,                /* output_total_plycount (--totalplycount) */
+    FALSE,                /* add_hashcode_tag (--addhashcode) */
+    "MATCH",             /* position_match_comment (--markpositionmatches) */
+    (char *)NULL,         /* current_input_file */
+    NORMALFILE,           /* current_file_type */
+    DEFAULT_ECO_FILE,     /* eco_file (-e) */
+    (FILE *)NULL,         /* outputfile (-o, -a). Default is stdout */
+    (char *)NULL,         /* output_filename (-o, -a) */
+    (FILE *)NULL,         /* logfile (-l). Default is stderr */
+    (FILE *)NULL,         /* duplicate_file (-d) */
+    (FILE *)NULL,         /* non_matching_file (-n) */
+};
+
+         /* Prepare the output file handles in GlobalState. */
+static void
+init_default_global_state(void)
+{
+    GlobalState.outputfile = stdout;
+    GlobalState.logfile = stderr;
+    set_output_line_length(MAX_LINE_LENGTH);
+}
+
+int
+main(int argc, char *argv[])
+{   int argnum;
+
+    /* Prepare global state. */
+    init_default_global_state();
+    /* Prepare the Game_Header. */
+    init_game_header();
+    /* Prepare the tag lists for -t/-T matching. */
+    init_tag_lists();
+    /* Prepare the hash tables for transposition detection. */
+    init_hashtab();
+    /* Initialise the lexical analyser's tables. */
+    init_lex_tables();
+    /* Allow for some arguments. */
+    for(argnum = 1; argnum < argc; ){
+        const char *argument = argv[argnum];
+        if(argument[0] == '-'){
+            switch(argument[1]){
+                /* Arguments with no additional component. */
+                case SEVEN_TAG_ROSTER_ARGUMENT:
+                case DONT_KEEP_COMMENTS_ARGUMENT:
+                case DONT_KEEP_DUPLICATES_ARGUMENT:
+                case DONT_KEEP_VARIATIONS_ARGUMENT:
+                case DONT_KEEP_NAGS_ARGUMENT:
+                case DONT_MATCH_PERMUTATIONS_ARGUMENT:
+                case CHECK_ONLY_ARGUMENT:
+                case KEEP_SILENT_ARGUMENT:
+                case USE_SOUNDEX_ARGUMENT:
+                case MATCH_CHECKMATE_ARGUMENT:
+                case SUPPRESS_ORIGINALS_ARGUMENT:
+                case OUTPUT_FEN_STRING_ARGUMENT:
+                case USE_VIRTUAL_HASH_TABLE_ARGUMENT:
+                    process_argument(argument[1], "");
+                    argnum++;
+                    break;
+
+                /* Argument rewritten as a different one. */
+                case ALTERNATIVE_HELP_ARGUMENT:
+                    process_argument(HELP_ARGUMENT, "");
+                    argnum++;
+                    break;
+
+                /* Arguments where an additional component is required.
+                 * It must be adjacent to the argument and not separated from it.
+                 */
+                case TAG_EXTRACTION_ARGUMENT:
+                    process_argument(argument[1], &(argument[2]));
+                    argnum++;
+                    break;
+
+                /* Arguments where an additional component is optional.
+                 * If it is present, it must be adjacent to the argument
+                 * letter and not separated from it.
+                 */
+                case USE_ECO_FILE_ARGUMENT:
+                case OUTPUT_FORMAT_ARGUMENT:
+                case HELP_ARGUMENT:
+                    process_argument(argument[1], &(argument[2]));
+                    argnum++;
+                    break;
+
+                /* Long form arguments. */
+                case LONG_FORM_ARGUMENT:
+                    {  
+                      /* How many args (1 or 2) are processed. */
+                      int args_processed;
+                      /* This argument might need the following argument
+                       * as an associated value.
+                       */
+                      const char *possible_associated_value = "";
+                      if(argnum + 1 < argc) {
+                          possible_associated_value = argv[argnum+1];
+                      }
+                      /* Find out how many arguments were consumed
+                       * (1 or 2).
+                       */
+                      args_processed =
+                          process_long_form_argument(&argument[2],
+                                                     possible_associated_value);
+                      argnum += args_processed;
+                    }
+                    break;
+
+                /* Arguments with a required filename component. */
+                case FILE_OF_ARGUMENTS_ARGUMENT:
+                case APPEND_TO_OUTPUT_FILE_ARGUMENT:
+                case CHECK_FILE_ARGUMENT:
+                case DUPLICATES_FILE_ARGUMENT:
+                case FILE_OF_FILES_ARGUMENT:
+                case WRITE_TO_LOG_FILE_ARGUMENT:
+                case APPEND_TO_LOG_FILE_ARGUMENT:
+                case NON_MATCHING_GAMES_ARGUMENT:
+                case WRITE_TO_OUTPUT_FILE_ARGUMENT:
+                case TAG_ROSTER_ARGUMENT:
+                    {   /* We require an associated file argument. */
+                        const char argument_letter = argument[1];
+                        const char *filename = &(argument[2]);
+                        if(*filename == '\0'){
+                             /* Try to pick it up from the next argument. */
+                             argnum++;
+                             if(argnum < argc){
+                                 filename = argv[argnum];
+                                 argnum++;
+                             }
+                            /* Make sure the associated_value does not look
+                             * like the next argument.
+                             */
+                            if((*filename == '\0') || (*filename == '-')){
+                                fprintf(GlobalState.logfile,
+                                        "Usage: -%c filename\n",
+                                        argument_letter);
+                                exit(1);
+                            }
+                        }
+                        else {
+                            argnum++;
+                        }
+                        process_argument(argument[1], filename);
+                    }
+                    break;
+
+                /* Arguments with a required following value. */
+                case BOUNDS_ARGUMENT:
+                case ECO_OUTPUT_LEVEL_ARGUMENT:
+                case LINE_WIDTH_ARGUMENT:
+                case GAMES_PER_FILE_ARGUMENT:
+                    {   /* We require an associated file argument. */
+                        const char argument_letter = argument[1];
+                        const char *associated_value = &(argument[2]);
+                        if(*associated_value == '\0'){
+                             /* Try to pick it up from the next argument. */
+                             argnum++;
+                             if(argnum < argc){
+                                 associated_value = argv[argnum];
+                                 argnum++;
+                             }
+                            /* Make sure the associated_value does not look
+                             * like the next argument.
+                             */
+                            if((*associated_value == '\0') ||
+                                       (*associated_value == '-')){
+                                fprintf(GlobalState.logfile,
+                                        "Usage: -%c value\n",
+                                        argument_letter);
+                                exit(1);
+                            }
+                        }
+                        else {
+                            argnum++;
+                        }
+                        process_argument(argument[1], associated_value);
+                    }
+                    break;
+
+                /* Argument that require different treatment because they
+                 * are present on the command line rather than an argsfile.
+                 */
+                case TAGS_ARGUMENT:
+                case MOVES_ARGUMENT:
+                case POSITIONS_ARGUMENT:
+                case ENDINGS_ARGUMENT:
+                    {   /* From the command line, we require an
+                         * associated file argument.
+                         * Check this here, as it is not the case
+                         * when reading arguments from an argument file.
+                         */
+                        const char *filename =  &(argument[2]);
+                        const char argument_letter = argument[1];
+                        if(*filename == '\0'){
+                             /* Try to pick it up from the next argument. */
+                             argnum++;
+                             if(argnum < argc){
+                                 filename = argv[argnum];
+                                 argnum++;
+                             }
+                            /* Make sure the filename does not look
+                             * like the next argument.
+                             */
+                            if((*filename == '\0') || (*filename == '-')){
+                                fprintf(GlobalState.logfile,
+                                        "Usage: -%cfilename or -%c filename\n",
+                                        argument_letter,argument_letter);
+                                exit(1);
+                            }
+                        }
+                        else{
+                            argnum++;
+                        }
+                        process_argument(argument_letter,filename);
+                    }
+                    break;
+                default:
+                    fprintf(GlobalState.logfile,
+                            "Unknown flag %s. Use -%c for usage details.\n",
+                            argument,HELP_ARGUMENT);
+                    exit(1);
+                    break;
+            }
+        }
+        else{
+            /* Should be a file name containing games. */
+            add_filename_to_source_list(argument,NORMALFILE);
+            argnum++;
+        }
+    }
+    /* Prepare the hash tables for duplicate detection. */
+    init_duplicate_hash_table();
+
+    if(GlobalState.add_ECO){
+        /* Read in a list of ECO lines in order to classify the games. */
+        if(open_eco_file(GlobalState.eco_file)){
+            /* Indicate that the ECO file is currently being parsed. */
+            GlobalState.parsing_ECO_file = TRUE;
+            yyparse(ECOFILE);
+            reset_line_number();
+            GlobalState.parsing_ECO_file = FALSE;
+        }
+        else{
+            fprintf(GlobalState.logfile,"Unable to open the ECO file %s.\n",
+                        GlobalState.eco_file);
+            exit(1);
+        }
+    }
+
+    /* Open up the first file to act as Lex's source of input. */
+    if(!open_first_file()){
+        exit(1);
+    }
+    yyparse(GlobalState.current_file_type);
+    /* Remove any temporary files. */
+    clear_duplicate_hash_table();
+    if(GlobalState.verbose){
+        fprintf(GlobalState.logfile,"%lu game%s matched out of %lu.\n",
+                        GlobalState.num_games_matched,
+                        GlobalState.num_games_matched == 1?"":"s",
+                        GlobalState.num_games_processed);
+    }
+    if((GlobalState.logfile != stderr) && (GlobalState.logfile != NULL)){
+        (void) fclose(GlobalState.logfile);
+    }
+    return 0;
+}
diff --git a/map.c b/map.c
new file mode 100644 (file)
index 0000000..2af4c38
--- /dev/null
+++ b/map.c
@@ -0,0 +1,1938 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "defs.h"
+#include "typedef.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "lex.h"
+#include "map.h"
+#include "decode.h"
+#include "apply.h"
+
+        /* Structures to hold the x,y displacements of the various
+         * piece movements.
+         */
+
+/* Define a list of possible Knight moves. */
+#define NUM_KNIGHT_MOVES 8
+static short Knight_moves[2*NUM_KNIGHT_MOVES] =
+        {  1, 2,
+           1,-2,
+           2, 1,
+           2,-1,
+          -1, 2,
+          -1,-2,
+          -2, 1,
+          -2,-1,
+        };
+
+/* Define a list of possible Bishop moves. */
+#define NUM_BISHOP_MOVES 4
+static short Bishop_moves[2*NUM_BISHOP_MOVES] =
+    {  1, 1,
+       1,-1,
+      -1, 1,
+      -1,-1
+    };
+
+/* Define a list of possible Rook moves. */
+#define NUM_ROOK_MOVES 4
+static short Rook_moves[2*NUM_ROOK_MOVES] =
+    {  1, 0,
+       0, 1,
+      -1, 0,
+       0,-1
+    };
+
+/* Define a list of possible King moves. */
+#define NUM_KING_MOVES 8
+static short King_moves[2*NUM_KING_MOVES] =
+    {  1, 0,
+       1, 1,
+       1,-1,
+       0, 1,
+       0,-1,
+      -1, 0,
+      -1, 1,
+      -1,-1,
+    };
+
+/* Define a list of possible Queen moves. */
+#define NUM_QUEEN_MOVES 8
+static short Queen_moves[2*NUM_QUEEN_MOVES] =
+    {  1, 0,
+       1, 1,
+       1,-1,
+       0, 1,
+       0,-1,
+      -1, 0,
+      -1, 1,
+      -1,-1,
+    };
+
+
+        /* A table of hash values for square/piece/colour combinations.
+         * When a piece is moved, the hash value is xor-ed into a
+         * running description of the current board state.
+         */
+#define NUMBER_OF_PIECES 6
+static HashCode HashTab[BOARDSIZE][BOARDSIZE][NUMBER_OF_PIECES][2];
+
+        /* Prototypes for functions in this file. */
+
+        /* Code to allocate and free MovePair structures.  New moves are
+         * allocated from the move_pool, if it isn't empty.  Old moves
+         * are freed to this pool.
+         * This is used to avoid too much fragmentation of the heap.
+         * Since the program will spend a lot of its life allocating and
+         * deallocating move structures, we might as well hang on to them.
+         */
+/* Keep a pool of free move structures. */
+static MovePair *move_pool = NULL;
+
+static MovePair *
+malloc_move(void)
+{   MovePair *move;
+
+    if(move_pool != NULL){
+        move = move_pool;
+        move_pool = move_pool->next;
+    }
+    else{
+        move = (MovePair *)MallocOrDie(sizeof(MovePair));
+    }
+    move->next = NULL;
+    return move;
+}
+
+        /* Append another move pair onto moves, and return the new list. */
+static MovePair *
+append_move_pair(Col from_col, Rank from_rank, Col to_col, Rank to_rank,MovePair *moves)
+{   MovePair *move = malloc_move();
+
+    move->from_rank = from_rank;
+    move->from_col = from_col;
+    move->to_rank = to_rank;
+    move->to_col = to_col;
+    move->next = moves;
+    return move;
+}
+
+        /* Simply add the move to the free move pool. */
+static void
+free_move_pair(MovePair *move)
+{
+    move->next = move_pool;
+    move_pool = move;
+}
+
+        /* Free a whole list of moves to the move pool. */
+void
+free_move_pair_list(MovePair *move_list)
+{
+    if(move_list != NULL){
+        free_move_pair_list(move_list->next);
+        free_move_pair(move_list);
+    }
+}
+
+        /* Produce a hash value for each piece, square, colour combination.
+         * This code is a modified version of that to be found in
+         * Steven J. Edwards' SAN kit.
+         */
+#define SHIFT_LENGTH 7
+void
+init_hashtab(void)
+{   Piece piece;
+    Colour colour;
+    Rank rank;
+    Col col;
+    static HashCode seed = 0;
+
+    for(col = FIRSTCOL; col <= LASTCOL; col++){
+      for(rank = FIRSTRANK; rank <= LASTRANK; rank++){
+        for(piece = PAWN; piece <= KING; piece++){
+          for(colour = BLACK; colour <= WHITE; colour++){
+            HashCode code;
+
+#if 1
+            /* Try to use a wider range of the available values
+             * in an attempt to avoid spurious hash matches.
+             */
+            seed = (seed * 1103515245L) + 123456789L;
+#else
+            /* This is the version used up to and including version 13.8. */
+            seed = (seed * 1103515245L) + 12345L;
+#endif
+            code = (seed >> SHIFT_LENGTH);
+            HashTab[col-FIRSTCOL][rank-FIRSTRANK][piece-PAWN][colour-BLACK] = code;
+          }
+        }
+      }
+    }
+}
+
+        /* Look up the hash value for this combination. */
+HashCode
+HashLookup(Col col, Rank rank, Piece piece, Colour colour)
+{
+    return HashTab[col-FIRSTCOL][rank-FIRSTRANK][piece-PAWN][colour-BLACK];
+}
+
+        /* Is the given piece of the named colour? */
+static Boolean
+piece_is_colour(Piece coloured_piece, Colour colour)
+{   
+    return EXTRACT_COLOUR(coloured_piece) == colour;
+}
+
+        /* Make the given move.  This is assumed to have been thoroughly
+         * checked beforehand, and the from_ and to_ information to be
+         * complete.  Update the board structure to reflect
+         * the full set of changes implied by it.
+         */
+void
+make_move(MoveClass class, Col from_col, Rank from_rank, Col to_col, Rank to_rank,
+          Piece piece, Colour colour,Board *board)
+{   short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    short from_r = RankConvert(from_rank);
+    short from_c = ColConvert(from_col);
+    /* Does this move involve a capture? */
+    Boolean capture = FALSE;
+
+    /* If a KING or ROOK is moved, this might affect castling rights. */
+    if(piece == KING){
+        if(colour == WHITE){
+            board->WKingCol = to_col;
+            board->WKingRank = to_rank;
+            board->WKingCastle =
+                    board->WQueenCastle = FALSE;
+        }
+        else{
+            board->BKingCol = to_col;
+            board->BKingRank = to_rank;
+            board->BKingCastle =
+                    board->BQueenCastle = FALSE;
+        }
+    }
+    else if(piece == ROOK){
+        /* Some castling rights may need disallowing. */
+        if(colour == WHITE){
+            if(from_rank == FIRSTRANK){
+                if(from_col == FIRSTCOL){
+                    board->WQueenCastle = FALSE;
+                }
+                else if(from_col == LASTCOL){
+                    board->WKingCastle = FALSE;
+                }
+                else{
+                    /* No change. */
+                }
+            }
+        }
+        else{
+            if(from_rank == LASTRANK){
+                if(from_col == FIRSTCOL){
+                    board->BQueenCastle = FALSE;
+                }
+                else if(from_col == LASTCOL){
+                    board->BKingCastle = FALSE;
+                }
+                else{
+                    /* No change. */
+                }
+            }
+        }
+    }
+    else{
+        /* Castling not in question from the piece being moved,
+         * but see below for checks on any captured piece.
+         */
+    }
+    /* Check for en-passant rights resulting from this move. */
+    if(piece != PAWN){
+        /* The move cannot result in en-passant rights. */
+        board->EnPassant = FALSE;
+    }
+    else{
+        if(colour == WHITE){
+            if((from_rank == '2') && (to_rank == '4')){
+                /* This move permits an en-passant capture on the following move. */
+                board->EnPassant = TRUE;
+                board->ep_rank = to_rank-1;
+                board->ep_col = to_col;
+            }
+            else if((board->EnPassant) && (board->ep_rank == to_rank) &&
+                        (board->ep_col == to_col)){
+                /* This is an ep capture. Remove the intermediate pawn. */
+                board->board[RankConvert(to_rank)-1][ColConvert(to_col)] = EMPTY;
+                board->hash_value ^= HashLookup(to_col,to_rank-1,PAWN,BLACK);
+                board->EnPassant = FALSE;
+            }
+            else{
+                board->EnPassant = FALSE;
+            }
+        }
+        else{
+            if((from_rank == '7') && (to_rank == '5')){
+                board->EnPassant = TRUE;
+                board->ep_rank = to_rank+1;
+                board->ep_col = to_col;
+            }
+            else if((board->EnPassant) && (board->ep_rank == to_rank) &&
+                        (board->ep_col == to_col)){
+                /* This is an ep capture. Remove the intermediate pawn. */
+                board->board[RankConvert(to_rank)+1][ColConvert(to_col)] = EMPTY;
+                board->hash_value ^= HashLookup(to_col,to_rank+1,PAWN,WHITE);
+                board->EnPassant = FALSE;
+            }
+            else{
+                board->EnPassant = FALSE;
+            }
+        }
+    }
+    /* Clear the source square. */
+    /* NB: Up to v17-18 there was an error here in the calculation of the hash
+     * when the move class is PAWN_MOVE_WITH_PROMOTION.
+     * The value of the promoted piece was removed, rather than the value
+     * of the pawn because piece is the promoted piece rather than PAWN.
+     */
+    if(class == PAWN_MOVE_WITH_PROMOTION && piece != PAWN) {
+       /* Remove the promoted pawn. */
+       board->hash_value ^= HashLookup(from_col,from_rank,PAWN,colour);
+    }
+    else {
+       board->hash_value ^= HashLookup(from_col,from_rank,piece,colour);
+    }
+    board->board[from_r][from_c] = EMPTY;
+    if(board->board[to_r][to_c] != EMPTY){
+        /* Delete the captured piece from the hash value. */
+        Piece coloured_piece = board->board[to_r][to_c];
+        Piece removed_piece;
+        Colour removed_colour;
+
+        removed_piece = EXTRACT_PIECE(coloured_piece);
+        removed_colour = EXTRACT_COLOUR(coloured_piece);
+        board->hash_value ^= HashLookup(to_col,to_rank,removed_piece,removed_colour);
+        /* See whether the removed piece is a Rook, as this could
+         * affect castling rights.
+         */
+        if(removed_piece == ROOK){
+            if(removed_colour == WHITE){
+                if(to_rank == FIRSTRANK){
+                    if(to_col == FIRSTCOL){
+                        board->WQueenCastle = FALSE;
+                    }
+                    else if(to_col == LASTCOL){
+                        board->WKingCastle = FALSE;
+                    }
+                    else{
+                        /* No change. */
+                    }
+                }
+            }
+            else{
+                if(to_rank == LASTRANK){
+                    if(to_col == FIRSTCOL){
+                        board->BQueenCastle = FALSE;
+                    }
+                    else if(to_col == LASTCOL){
+                        board->BKingCastle = FALSE;
+                    }
+                    else{
+                        /* No change. */
+                    }
+                }
+            }
+        }
+        capture = TRUE;
+    }
+    /* Deal with the half-move clock. */
+    if(capture || piece == PAWN) {
+        board->halfmove_clock = 0;
+    }
+    else {
+        board->halfmove_clock++;
+    }
+    /* Place the piece at its destination. */
+    board->board[to_r][to_c] = MAKE_COLOURED_PIECE(colour,piece);
+    /* Insert the moved piece into the hash value. */
+    board->hash_value ^= HashLookup(to_col,to_rank,piece,colour);
+}
+
+        /* Find pawn moves matching the to_ and from_ information.
+         * Depending on the input form of the move, some of this will be
+         * incomplete.  For instance: e4 supplies just the to_ information
+         * whereas cb supplies some from_ and some to_.
+         */
+MovePair *
+find_pawn_moves(Col from_col, Rank from_rank, Col to_col,Rank to_rank,
+                Colour colour, const Board *board)
+{   short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    short from_r = RankConvert(from_rank);
+    short from_c = ColConvert(from_col);
+    MovePair *move_list = NULL;
+    MovePair *move = NULL;
+    /* White pawn moves are offset by +1, Black by -1. */
+    short offset = COLOUR_OFFSET(colour);
+    Piece piece_to_move = MAKE_COLOURED_PIECE(colour,PAWN);
+
+    if((to_col != 0) && (to_rank != 0)){
+        /* We know the complete destination. */
+        if(board->board[to_r][to_c] == EMPTY){
+            /* Destination must be empty for this form. */
+            if(board->board[to_r-offset][to_c] == piece_to_move){
+                /* MovePair of one square. */
+                move = append_move_pair(ToCol(to_c),ToRank(to_r-offset),
+                                        to_col,to_rank,NULL);
+            }
+            else if((board->board[to_r-offset][to_c] == EMPTY) &&
+                            (to_rank == (colour == WHITE?'4':'5'))){
+                /* Special case of initial two square move. */
+                if(board->board[to_r-2*offset][to_c] == piece_to_move){
+                    move = append_move_pair(ToCol(to_c),ToRank(to_r-2*offset),
+                                        to_col,to_rank,NULL);
+                }
+            }
+            else if(board->EnPassant &&
+                        (board->ep_rank == to_rank) &&
+                        (board->ep_col == to_col)){
+                /* Make sure that there is a valid pawn in position. */
+                if(from_col != 0){
+                    from_r = to_r-offset;
+                    if(board->board[from_r][from_c] == piece_to_move){
+                        move = append_move_pair(ToCol(from_c),ToRank(from_r),
+                                        to_col,ToRank(to_r),NULL);
+                    }
+                }
+            }
+        }
+        else if(piece_is_colour(board->board[to_r][to_c],OPPOSITE_COLOUR(colour))){
+            /* Capture on the destination square. */
+            if(from_col != 0){
+                /* We know the from column. */
+                from_r = to_r-offset;
+                if(board->board[from_r][from_c] == piece_to_move){
+                    move = append_move_pair(ToCol(from_c),ToRank(from_r),
+                                        to_col,to_rank,NULL);
+                }
+            }
+        }
+        else{
+            /* We have no move. */
+            move = NULL;
+        }
+        move_list = move;
+    }
+    else if((from_col != 0) && (to_col != 0)){
+        /* Should be a diagonal capture. */
+        if(((from_col + 1) != to_col) && ((from_col - 1) != to_col)){
+            /* Inconsistent information. */
+        }
+        else{
+            if(from_rank != 0){
+                /* We have complete source information. Check its
+                 * veracity.
+                 */
+                to_r = from_r - offset;
+                if(board->board[from_r][from_c] == piece_to_move){
+                    Piece occupant = board->board[to_r][to_c];
+
+                    if((occupant != EMPTY) &&
+                            (piece_is_colour(occupant,OPPOSITE_COLOUR(colour)))){
+                        move = append_move_pair(ToCol(from_c),ToRank(from_r),
+                                        to_col,ToRank(to_r),NULL);
+                    }
+                    else if(board->EnPassant && (board->ep_rank == ToRank(to_r)) &&
+                                    (board->ep_col == ToCol(to_c))){
+                        move = append_move_pair(ToCol(from_c),ToRank(from_r),
+                                        to_col,ToRank(to_r),NULL);
+                    }
+                }
+            }
+            else{
+                /* We must search the from_col and to_col for appropriate
+                 * combinations.  There may be more than one.
+                 */
+                short start_rank, end_rank;
+
+                /* Work out from where to start and end. */
+                if(colour == WHITE){
+                    start_rank = RankConvert(FIRSTRANK+1);
+                    end_rank = RankConvert(LASTRANK);
+                }
+                else{
+                    start_rank = RankConvert(LASTRANK-1);
+                    end_rank = RankConvert(FIRSTRANK);
+                }
+                for(from_r = start_rank; from_r != end_rank; from_r += offset){
+                    to_r = from_r+offset;
+                    if(board->board[from_r][from_c] == piece_to_move){
+                        Piece occupant = board->board[to_r][to_c];
+
+                        if((occupant != EMPTY) &&
+                                (piece_is_colour(occupant,OPPOSITE_COLOUR(colour)))){
+                            move_list = append_move_pair(ToCol(from_c),ToRank(from_r),
+                                        to_col,ToRank(to_r),move_list);
+                        }
+                        else if(board->EnPassant && (board->ep_rank == ToRank(to_r)) &&
+                                        (board->ep_col == ToCol(to_c))){
+                            move_list = append_move_pair(ToCol(from_c),ToRank(from_r),
+                                        to_col,ToRank(to_r),move_list);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return move_list;
+}
+
+        /* Find knight moves to the given square. */
+MovePair *
+find_knight_moves(Col to_col,Rank to_rank, Colour colour, const Board *board)
+{   short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    unsigned ix;
+    MovePair *move_list = NULL;
+    Piece target_piece =  MAKE_COLOURED_PIECE(colour,KNIGHT);
+
+    /* Pick up pairs of offsets from to_r,to_c to look for a Knight of
+     * the right colour.
+     */
+    for(ix = 0; ix < 2*NUM_KNIGHT_MOVES; ix += 2){
+        short r = Knight_moves[ix]+to_r;
+        short c = Knight_moves[ix+1]+to_c;
+
+        if(board->board[r][c] == target_piece){
+            move_list = append_move_pair(ToCol(c),ToRank(r),to_col,to_rank,move_list);
+        }
+    }
+    return move_list;
+}
+
+        /* Find bishop moves to the given square. */
+MovePair *
+find_bishop_moves(Col to_col,Rank to_rank, Colour colour, const Board *board)
+{   short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    unsigned ix;
+    MovePair *move_list = NULL;
+    Piece target_piece =  MAKE_COLOURED_PIECE(colour,BISHOP);
+
+    /* Pick up pairs of offsets from to_r,to_c to look for a Bishop of
+     * the right colour.
+     */
+    for(ix = 0; ix < 2*NUM_BISHOP_MOVES; ix += 2){
+        short r = to_r, c = to_c;
+        
+        /* Work backwards from the destination to find a bishop of
+         * the right colour.
+         */
+        do{
+            r += Bishop_moves[ix];
+            c += Bishop_moves[ix+1];
+        } while(board->board[r][c] == EMPTY);
+
+        if(board->board[r][c] == target_piece){
+            move_list = append_move_pair(ToCol(c),ToRank(r),to_col,to_rank,move_list);
+        }
+    }
+    return move_list;
+}
+
+        /* Find rook moves to the given square. */
+MovePair *
+find_rook_moves(Col to_col,Rank to_rank, Colour colour, const Board *board)
+{   short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    unsigned ix;
+    MovePair *move_list = NULL;
+    Piece target_piece = MAKE_COLOURED_PIECE(colour,ROOK);
+
+    /* Pick up pairs of offsets from to_r,to_c to look for a Rook of
+     * the right colour.
+     */
+    for(ix = 0; ix < 2*NUM_ROOK_MOVES; ix += 2){
+        short r = to_r, c = to_c;
+        
+        /* Work backwards from the destination to find a rook of
+         * the right colour.
+         */
+        do{
+            r += Rook_moves[ix];
+            c += Rook_moves[ix+1];
+        } while(board->board[r][c] == EMPTY);
+
+        if(board->board[r][c] == target_piece){
+            move_list = append_move_pair(ToCol(c),ToRank(r),to_col,to_rank,move_list);
+        }
+    }
+    return move_list;
+}
+
+        /* Find queen moves to the given square. */
+MovePair *
+find_queen_moves(Col to_col,Rank to_rank, Colour colour, const Board *board)
+{   short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    unsigned ix;
+    MovePair *move_list = NULL;
+    Piece target_piece = MAKE_COLOURED_PIECE(colour,QUEEN);
+
+    /* Pick up pairs of offsets from to_r,to_c to look for a Knight of
+     * the right colour.
+     */
+    for(ix = 0; ix < 2*NUM_QUEEN_MOVES; ix += 2){
+        short r = to_r, c = to_c;
+        
+        /* Work backwards from the destination to find a queen of
+         * the right colour.
+         */
+        do{
+            r += Queen_moves[ix];
+            c += Queen_moves[ix+1];
+        } while(board->board[r][c] == EMPTY);
+
+        if(board->board[r][c] == target_piece){
+            move_list = append_move_pair(ToCol(c),ToRank(r),to_col,to_rank,move_list);
+        }
+    }
+    return move_list;
+}
+
+        /* Find King moves to the given square. */
+MovePair *
+find_king_moves(Col to_col,Rank to_rank, Colour colour, const Board *board)
+{   short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    unsigned ix;
+    MovePair *move_list = NULL;
+    Piece target_piece = MAKE_COLOURED_PIECE(colour,KING);
+
+    /* Pick up pairs of offsets from to_r,to_c to look for a King of
+     * the right colour.
+     */
+    for(ix = 0; ix < 2*NUM_KING_MOVES; ix += 2){
+        short r = King_moves[ix]+to_r;
+        short c = King_moves[ix+1]+to_c;
+        
+        if(board->board[r][c] == target_piece){
+            move_list = append_move_pair(ToCol(c),ToRank(r),to_col,to_rank,move_list);
+        }
+    }
+    return move_list;
+}
+
+        /* Return true if the king of the given colour is
+         * in check on the board, FALSE otherwise.
+         */
+CheckStatus
+king_is_in_check(const Board *board,Colour king_colour)
+{   MovePair *replies = NULL;
+    /* Assume that there is no check. */
+    CheckStatus in_check = NOCHECK;
+    Col king_col;
+    Rank king_rank;
+    Colour opponent_colour = OPPOSITE_COLOUR(king_colour);
+
+    /* Find out where the king is now. */
+    if(king_colour == WHITE){
+        king_col = board->WKingCol;
+        king_rank = board->WKingRank;
+    }
+    else{
+        king_col = board->BKingCol;
+        king_rank = board->BKingRank;
+    }
+    /* Try and find one move that leaves this king in check.
+     * There is probably an optimal order for these tests, but I haven't
+     * tried to find it.
+     */
+    if((king_col != LASTCOL) &&
+                ((replies = find_pawn_moves(king_col+1,0,king_col,king_rank,
+                                    opponent_colour,board)) != NULL)){
+        /* King is in check from a pawn to its right. */
+    }
+    else if((king_col != FIRSTCOL) &&
+                ((replies = find_pawn_moves(king_col-1,0,king_col,king_rank,
+                                    opponent_colour,board)) != NULL)){
+        /* King is in check from a pawn. to its left */
+    }
+
+    if(replies != NULL) {
+        /* Already found a pawn move. */
+    }
+    else if((replies =
+        find_knight_moves(king_col,king_rank,
+                                    opponent_colour,board)) != NULL){
+        /* King is in check from a knight. */
+    }
+    else if((replies =
+        find_bishop_moves(king_col,king_rank,
+                                    opponent_colour,board)) != NULL){
+        /* King is in check from a bishop. */
+    }
+    else if((replies =
+        find_rook_moves(king_col,king_rank,
+                                    opponent_colour,board)) != NULL){
+        /* King is in check from a rook. */
+    }
+    else if((replies =
+        find_queen_moves(king_col,king_rank,
+                                    opponent_colour,board)) != NULL){
+        /* King is in check from a queen. */
+    }
+    else if((replies =
+        find_king_moves(king_col,king_rank,
+                                    opponent_colour,board)) != NULL){
+        /* King is in check from a king. */
+    }
+    else{
+        /* King is safe. */
+    }
+    if(replies != NULL){
+       in_check = CHECK;
+       free_move_pair_list(replies);
+    }
+    return in_check;
+}
+
+        /* possibles contains a list of possible moves of piece.
+         * This function should exclude all of those moves of this piece
+         * which leave its own king in check.  The list of remaining legal
+         * moves is returned as result.
+         * This function operates by looking for at least one reply by the
+         * opponent that could capture the king of the given colour.
+         * Only one such move needs to be found to invalidate one of the
+         * possible moves.
+         */
+MovePair *
+exclude_checks(Piece piece, Colour colour,MovePair *possibles, const Board *board)
+{   /* As this function is not called recursively, it should be
+     * safe to retain a single copy of the board on the stack without risking
+     * overflow. This has been a problem in the past with the PC version.
+     */
+    Board copy_board;
+    MovePair *valid_move_list = NULL;
+    MovePair *move;
+
+    /* For each possible move, make the move and see if it leaves the king
+     * in check.
+     */
+    for(move = possibles; move != NULL; ){
+        /* Take a copy of the board before playing this next move. */
+        copy_board = *board;
+        make_move(UNKNOWN_MOVE, move->from_col,move->from_rank,
+                  move->to_col,move->to_rank,piece,colour,&copy_board);
+        if(king_is_in_check(&copy_board,colour) != NOCHECK){
+            MovePair *illegal_move = move;
+
+            move = move->next;
+            /* Free the illegal move. */
+            free_move_pair(illegal_move);
+        }
+        else{
+            /* King is safe and the move may be kept. */
+            MovePair *legal_move = move;
+
+            move = move->next;
+            legal_move->next = valid_move_list;
+            valid_move_list = legal_move;
+        }
+    }
+    return valid_move_list;
+}
+
+    /* We must exclude the possibility of the king passing
+     * through check, or castling out of it.
+     */
+static Boolean
+exclude_castling_across_checks(MoveClass class, Colour colour, const Board *board)
+{   Boolean Ok = TRUE;
+    MovePair *move = malloc_move();
+    Rank rank = (colour == WHITE)? FIRSTRANK : LASTRANK;
+    Col to_col;
+
+    if(class == KINGSIDE_CASTLE){
+        /* Start where we are, because you can't castle out of check. */
+        for(to_col = 'e'; (to_col <= 'g') && Ok; to_col++){
+            move->from_col = 'e';
+            move->from_rank = rank;
+            move->to_col = to_col;
+            move->to_rank = rank;
+            move = exclude_checks(KING,colour,move,board);
+            if(move == NULL){
+                Ok = FALSE;
+            }
+        }
+    }
+    else{
+        /* Start where we are, because you can't castle out of check. */
+        for(to_col = 'e'; (to_col <= 'c') && Ok; to_col--){
+            move->from_col = 'e';
+            move->from_rank = rank;
+            move->to_col = to_col;
+            move->to_rank = rank;
+            move = exclude_checks(KING,colour,move,board);
+            if(move == NULL){
+                Ok = FALSE;
+            }
+        }
+    }
+    if(move != NULL){
+        free_move_pair(move);
+    }
+    return Ok;
+}
+
+        /* Possibles is a list of possible moves of piece.
+         * Exclude all of those that either leave the king in check
+         * or those excluded by non-null information in from_col or from_rank.
+         */
+static MovePair *
+exclude_moves(Piece piece, Colour colour,Col from_col, Rank from_rank,
+        MovePair *possibles, const Board *board)
+{   MovePair *move_list = NULL;
+
+    /* See if we have disambiguating from_ information. */
+    if((from_col != 0) || (from_rank != 0)){
+        MovePair *move, *temp;
+
+        for(move = possibles; move != NULL; ){
+            Boolean excluded = FALSE;
+
+            if(from_col != 0){
+                /* The from_col is specified. */
+                if(move->from_col != from_col){
+                    excluded = TRUE;
+                }
+            }
+            if((from_rank != 0) && !excluded){
+                if(move->from_rank != from_rank){
+                    excluded = TRUE;
+                }
+            }
+            temp = move;
+            move = move->next;
+            if(!excluded){
+                /* Add it to the list of possibles. */
+                temp->next = move_list;
+                move_list = temp;
+            }
+            else{
+                /* Discard it. */
+                free_move_pair(temp);
+            }
+        }
+    }
+    else{
+        /* Everything is still possible. */
+        move_list = possibles;
+    }
+    if(move_list != NULL){
+        move_list = exclude_checks(piece,colour,move_list,board);
+    }
+    return move_list;
+}
+
+        /* Make a pawn move.
+         * En-passant information in the original move text is not currently used
+         * to disambiguate pawn moves.  E.g. with Black pawns on c4 and c5 after
+         * White move 1. d4 a reply 1... cdep will be rejected as ambiguous.
+         */
+static Boolean
+pawn_move(Move *move_details, Colour colour, Board *board)
+{   Col from_col = move_details->from_col;
+    Rank from_rank = move_details->from_rank;
+    Col to_col = move_details->to_col;
+    Rank to_rank = move_details->to_rank;
+    /* Find the basic set of moves that match the move_details criteria. */
+    MovePair *move_list;
+    Boolean Ok = TRUE;
+
+    /* Make sure that the col values are consistent with a pawn move. */
+    if((from_col != '\0') && (to_col != '\0') &&
+            /* Forward. */
+            (from_col != to_col) &&
+            /* Capture. */
+            (from_col != (to_col+1)) && (from_col != (to_col-1))){
+        /* Inconsistent. */
+        Ok = FALSE;
+    }
+    else if((move_list = find_pawn_moves(from_col,from_rank,to_col,to_rank,
+                colour,board)) == NULL){
+        Ok = FALSE;
+    }
+    else{
+        /* Exclude any moves that leave the king in check, or are disambiguate
+         * by from_information.
+         */
+        move_list = exclude_moves(PAWN,colour,from_col,from_rank,move_list,board);
+        if(move_list != NULL){
+            if(move_list->next == NULL){
+                /* Unambiguous move. Some pawn moves will have supplied
+                 * incomplete destinations (e.g. cd as opposed to cxd4)
+                 * so pick up both from_ and to_ information.
+                 */
+                move_details->from_col = move_list->from_col;
+                move_details->from_rank = move_list->from_rank;
+                move_details->to_col = move_list->to_col;
+                move_details->to_rank = move_list->to_rank;
+            }
+            else{
+                /* Ambiguous. */
+                Ok = FALSE;
+            }
+            free_move_pair_list(move_list);
+        }
+        else{
+            /* Excluded. */
+            Ok = FALSE;
+        }
+    }
+    return Ok;
+}
+
+        /* Make a pawn move that involves an explicit promotion to promoted_piece. */
+static Boolean
+promote(Move *move_details, Colour colour, Board *board)
+{   Col from_col = move_details->from_col;
+    Rank from_rank = move_details->from_rank;
+    Col to_col = move_details->to_col;
+    Rank to_rank = move_details->to_rank;
+    MovePair *move_list;
+    Boolean Ok = FALSE;
+
+    if(to_rank == '\0'){
+        /* We can fill this in. */
+        if(colour == WHITE){
+            to_rank = LASTRANK;
+        }
+        else{
+            to_rank = FIRSTRANK;
+        }
+    }
+    /* Now check that to_rank makes sense for the given colour. */
+    if(((colour == WHITE) && (to_rank != LASTRANK)) ||
+            ((colour == BLACK) && (to_rank != FIRSTRANK))){
+        fprintf(GlobalState.logfile,"Illegal pawn promotion to %c%c\n",to_col,to_rank);
+    }
+    else{
+        move_list = find_pawn_moves(from_col,from_rank,to_col,to_rank,colour,board);
+        if(move_list != NULL){
+            if(move_list->next == NULL){
+                /* Unambiguous move. Some pawn moves will have supplied
+                 * incomplete destinations (e.g. cd as opposed to cxd8)
+                 * so pick up both from_ and to_ information.
+                 */
+                move_details->from_col = move_list->from_col;
+                move_details->from_rank = move_list->from_rank;
+                move_details->to_col = move_list->to_col;
+                move_details->to_rank = move_list->to_rank;
+                Ok = TRUE;
+            }
+            else{
+                fprintf(GlobalState.logfile,"Ambiguous pawn move to %c%c\n",to_col,to_rank);
+            }
+            free_move_pair_list(move_list);
+        }
+        else{
+            fprintf(GlobalState.logfile,"Illegal pawn promotion to %c%c\n",to_col,to_rank);
+        }
+    }
+    return Ok;
+}
+
+        /* Make a knight move, indicated by move_details.
+         * This may result in further information being added to move_details.
+         */
+static Boolean
+knight_move(Move *move_details, Colour colour, Board *board)
+{   Col from_col = move_details->from_col;
+    Rank from_rank = move_details->from_rank;
+    Col to_col = move_details->to_col;
+    Rank to_rank = move_details->to_rank;
+    short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    MovePair *move_list = find_knight_moves(to_col,to_rank,colour,board);
+    /* Assume everything will be ok. */
+    Boolean Ok = TRUE;
+
+    move_list = exclude_moves(KNIGHT,colour,from_col,from_rank,move_list,board);
+
+    if(move_list == NULL){
+        fprintf(GlobalState.logfile,"No knight move possible to %c%c.\n",to_col,to_rank);
+        Ok = FALSE;
+    }
+    else if(move_list->next == NULL){
+        /* Only one possible.  Check for legality. */
+        Piece occupant = board->board[to_r][to_c];
+
+        if((occupant == EMPTY) || piece_is_colour(occupant,OPPOSITE_COLOUR(colour))){
+            move_details->from_col = move_list->from_col;
+            move_details->from_rank = move_list->from_rank;
+        }
+        else{
+            fprintf(GlobalState.logfile,"Knight destination square %c%c is illegal.\n",
+                                to_col,to_rank);
+            Ok = FALSE;
+        }
+        free_move_pair(move_list);
+    }
+    else{
+        fprintf(GlobalState.logfile,"Ambiguous knight move to %c%c.\n",to_col,to_rank);
+        free_move_pair_list(move_list);
+        Ok = FALSE;
+    }
+    return Ok;
+}
+
+        /* Make a bishop move, indicated by move_details.
+         * This may result in further information being added to move_details.
+         */
+static Boolean
+bishop_move(Move *move_details, Colour colour, Board *board)
+{   Col from_col = move_details->from_col;
+    Rank from_rank = move_details->from_rank;
+    Col to_col = move_details->to_col;
+    Rank to_rank = move_details->to_rank;
+    short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    MovePair *move_list = find_bishop_moves(to_col,to_rank,colour,board);
+    /* Assume that it is ok. */
+    Boolean Ok = TRUE;
+
+    move_list = exclude_moves(BISHOP,colour,from_col,from_rank,move_list,board);
+
+    if(move_list == NULL){
+        fprintf(GlobalState.logfile,"No bishop move possible to %c%c.\n",to_col,to_rank);
+        Ok = FALSE;
+    }
+    else if(move_list->next == NULL){
+        /* Only one possible.  Check for legality. */
+        Piece occupant = board->board[to_r][to_c];
+
+        if((occupant == EMPTY) || piece_is_colour(occupant,OPPOSITE_COLOUR(colour))){
+            move_details->from_col = move_list->from_col;
+            move_details->from_rank = move_list->from_rank;
+        }
+        else{
+            fprintf(GlobalState.logfile,"Bishop's destination square %c%c is illegal.\n",
+                                to_col,to_rank);
+            Ok = FALSE;
+        }
+        free_move_pair(move_list);
+    }
+    else{
+        fprintf(GlobalState.logfile,"Ambiguous bishop move to %c%c.\n",to_col,to_rank);
+        free_move_pair_list(move_list);
+        Ok = FALSE;
+    }
+    return Ok;
+}
+
+        /* Make a rook move, indicated by move_details.
+         * This may result in further information being added to move_details.
+         */
+static Boolean
+rook_move(Move *move_details, Colour colour, Board *board)
+{   Col from_col = move_details->from_col;
+    Rank from_rank = move_details->from_rank;
+    Col to_col = move_details->to_col;
+    Rank to_rank = move_details->to_rank;
+    short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    MovePair *move_list = find_rook_moves(to_col,to_rank,colour,board);
+    /* Assume that it is ok. */
+    Boolean Ok = TRUE;
+
+    if(move_list == NULL){
+        fprintf(GlobalState.logfile,"No rook move possible to %c%c.\n",to_col,to_rank);
+        Ok = FALSE;
+    }
+    else{
+        move_list = exclude_moves(ROOK,colour,from_col,from_rank,move_list,board);
+
+        if(move_list == NULL){
+            fprintf(GlobalState.logfile,"Indicated rook move is excluded.\n");
+            Ok = FALSE;
+        }
+        else if(move_list->next == NULL){
+            /* Only one possible.  Check for legality. */
+            Piece occupant = board->board[to_r][to_c];
+
+            if((occupant == EMPTY) || piece_is_colour(occupant,OPPOSITE_COLOUR(colour))){
+                move_details->from_col = move_list->from_col;
+                move_details->from_rank = move_list->from_rank;
+            }
+            else{
+                fprintf(GlobalState.logfile,
+                                    "Rook's destination square %c%c is illegal.\n",
+                                    to_col,to_rank);
+                Ok = FALSE;
+            }
+            free_move_pair(move_list);
+        }
+        else{
+            fprintf(GlobalState.logfile,"Ambiguous rook move to %c%c.\n",to_col,to_rank);
+            free_move_pair_list(move_list);
+            Ok = FALSE;
+        }
+    }
+    return Ok;
+}
+
+        /* Find a queen move indicated by move_details.
+         * This may result in further information being added to move_details.
+         */
+static Boolean
+queen_move(Move *move_details, Colour colour, Board *board)
+{   Col from_col = move_details->from_col;
+    Rank from_rank = move_details->from_rank;
+    Col to_col = move_details->to_col;
+    Rank to_rank = move_details->to_rank;
+    short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    MovePair *move_list = find_queen_moves(to_col,to_rank,colour,board);
+    /* Assume that it is ok. */
+    Boolean Ok = TRUE;
+
+    move_list = exclude_moves(QUEEN,colour,from_col,from_rank,move_list,board);
+
+    if(move_list == NULL){
+        fprintf(GlobalState.logfile,"No queen move possible to %c%c.\n",to_col,to_rank);
+        Ok = FALSE;
+    }
+    else if(move_list->next == NULL){
+        /* Only one possible.  Check for legality. */
+        Piece occupant = board->board[to_r][to_c];
+
+        if((occupant == EMPTY) || piece_is_colour(occupant,OPPOSITE_COLOUR(colour))){
+            move_details->from_col = move_list->from_col;
+            move_details->from_rank = move_list->from_rank;
+        }
+        else{
+            fprintf(GlobalState.logfile,"Queen's destination square %c%c is illegal.\n",
+                                        to_col,to_rank);
+            Ok = FALSE;
+        }
+        free_move_pair(move_list);
+    }
+    else{
+        fprintf(GlobalState.logfile,"Ambiguous queen move to %c%c.\n",to_col,to_rank);
+        free_move_pair_list(move_list);
+        Ok = FALSE;
+    }
+    return Ok;
+}
+
+        /* Can colour castle kingside? */
+static Boolean
+can_castle_kingside(Colour colour, const Board *board)
+{   /* Assume failure. */
+    Boolean Ok = FALSE;
+    Rank king_rank;
+
+    if(colour == WHITE){
+        king_rank = FIRSTRANK;
+        Ok = board->WKingCastle;
+    }
+    else{
+        king_rank = LASTRANK;
+        Ok = board->BKingCastle;
+    }
+
+    if(Ok){
+        /* It is permitted. */
+        short king_c = ColConvert('e');
+        short king_r = RankConvert(king_rank);
+        Piece coloured_king = MAKE_COLOURED_PIECE(colour,KING);
+        Piece coloured_rook = MAKE_COLOURED_PIECE(colour,ROOK);
+
+        if((board->board[king_r][king_c] == coloured_king) &&
+                (board->board[king_r][king_c+1] == EMPTY) &&
+                (board->board[king_r][king_c+2] == EMPTY) &&
+                (board->board[king_r][king_c+3] == coloured_rook)){
+            if(exclude_castling_across_checks(KINGSIDE_CASTLE,colour,board)){
+                Ok = TRUE;
+            }
+            else{
+                /* Can't castle across check. */
+                Ok = FALSE;
+            }
+                
+        }
+        else{
+            /* Kingside castling is blocked. */
+            Ok = FALSE;
+        }
+    }
+    else{
+        /* Kingside castling is forbidden. */
+    }
+    return Ok;
+}
+
+        /* Can colour castle queenside? */
+static Boolean
+can_castle_queenside(Colour colour, const Board *board)
+{   /* Assume failure. */
+    Boolean Ok = FALSE;
+    Rank king_rank;
+
+    if(colour == WHITE){
+        king_rank = FIRSTRANK;
+        Ok = board->WQueenCastle;
+    }
+    else{
+        king_rank = LASTRANK;
+        Ok = board->BQueenCastle;
+    }
+
+    if(Ok){
+        /* It is permitted. */
+        short king_c = ColConvert('e');
+        short king_r = RankConvert(king_rank);
+        Piece coloured_king = MAKE_COLOURED_PIECE(colour,KING);
+        Piece coloured_rook = MAKE_COLOURED_PIECE(colour,ROOK);
+
+        if((board->board[king_r][king_c] == coloured_king) &&
+                (board->board[king_r][king_c-1] == EMPTY) &&
+                (board->board[king_r][king_c-2] == EMPTY) &&
+                (board->board[king_r][king_c-3] == EMPTY) &&
+                (board->board[king_r][king_c-4] == coloured_rook)){
+            if(exclude_castling_across_checks(QUEENSIDE_CASTLE,colour,board)){
+                Ok = TRUE;
+            }
+            else{
+                /* Can't castle across check. */
+                Ok = FALSE;
+            }
+                
+        }
+        else{
+            /* Queenside castling is blocked. */
+            Ok = FALSE;
+        }
+    }
+    else{
+        /* Queenside castling is forbidden. */
+    }
+    return Ok;
+}
+
+        /* Castle king side. */
+static Boolean
+kingside_castle(Move *move_details,Colour colour, Board *board)
+{   Boolean Ok;
+
+    if(can_castle_kingside(colour,board)){
+        Rank rank = colour == WHITE?FIRSTRANK:LASTRANK;
+
+        move_details->from_col = 'e';
+        move_details->from_rank = rank;
+        move_details->to_col = 'g';
+        move_details->to_rank = rank;
+        Ok = TRUE;
+    }
+    else{
+        fprintf(GlobalState.logfile,"Kingside castling is forbidden to %s.\n",
+                        colour == WHITE?"White":"Black");
+        Ok = FALSE;
+    }
+    return Ok;
+}
+
+static Boolean
+queenside_castle(Move *move_details, Colour colour, Board *board)
+{   Boolean Ok;
+
+    if(can_castle_queenside(colour,board)){
+        Rank rank = colour == WHITE?FIRSTRANK:LASTRANK;
+
+        move_details->from_col = 'e';
+        move_details->from_rank = rank;
+        move_details->to_col = 'c';
+        move_details->to_rank = rank;
+        Ok = TRUE;
+    }
+    else{
+        fprintf(GlobalState.logfile,"Queenside castling is forbidden to %s.\n",
+                        colour == WHITE?"White":"Black");
+        Ok = FALSE;
+    }
+    return Ok;
+}
+
+        /* Move the king according to move_details.
+         * This may result in further information being added to move_details.
+         */
+static Boolean
+king_move(Move *move_details, Colour colour, Board *board)
+{   Col from_col = move_details->from_col;
+    Rank from_rank = move_details->from_rank;
+    Col to_col = move_details->to_col;
+    Rank to_rank = move_details->to_rank;
+    short to_r = RankConvert(to_rank);
+    short to_c = ColConvert(to_col);
+    /* Find all possible king moves to the destination squares. */
+    MovePair *move_list = find_king_moves(to_col,to_rank,colour,board);
+    /* Assume that it is ok. */
+    Boolean Ok = TRUE;
+
+    /* Exclude disambiguated and illegal moves. */
+    move_list = exclude_moves(KING,colour,from_col,from_rank,move_list,board);
+
+    if(move_list == NULL){
+        fprintf(GlobalState.logfile,"No king move possible to %c%c.\n",to_col,to_rank);
+        Ok = FALSE;
+    }
+    else if(move_list->next == NULL){
+        /* Only one possible.  Check for legality. */
+        Piece occupant = board->board[to_r][to_c];
+
+        if((occupant == EMPTY) || piece_is_colour(occupant,OPPOSITE_COLOUR(colour))){
+            move_details->from_col = move_list->from_col;
+            move_details->from_rank = move_list->from_rank;
+        }
+        else{
+            fprintf(GlobalState.logfile,"King's destination square %c%c is illegal.\n",
+                                to_col,to_rank);
+            Ok = FALSE;
+        }
+        free_move_pair(move_list);
+    }
+    else{
+        fprintf(GlobalState.logfile,
+                        "Ambiguous king move possible to %c%c.\n",to_col,to_rank);
+        fprintf(GlobalState.logfile,"Multiple kings?!\n");
+        free_move_pair_list(move_list);
+        Ok = FALSE;
+    }
+    return Ok;
+}
+
+        /* Try to complete the full set of move information for
+         * move details.
+         * In the process, several fields of move_details are modified
+         * as accurate information is determined about the effect of the move.
+         * The from_ and to_ fields are completed, class may be refined, and
+         * captured_piece is filled in.  The purpose of this is to make it
+         * possible to call apply_move with a full set of information on the
+         * move.  In addition, once determine_move_details has done its job,
+         * it should be possible to use the information to reconstruct the effect
+         * of a move in reverse, if necessary.  This would be required by a display
+         * program, for instance.
+         * NB: this function does not determine whether or not the move gives check.
+         */
+Boolean
+determine_move_details(Colour colour,Move *move_details, Board *board)
+{   Boolean Ok = FALSE;
+
+    if(move_details == NULL){
+        /* Shouldn't happen. */
+        fprintf(GlobalState.logfile,
+                "Internal error: Empty move details in apply_move.\n");
+    }
+    else if(move_details->move[0] == '\0'){
+        /* Shouldn't happen. */
+        fprintf(GlobalState.logfile,
+                "Internal error: Null move string in apply_move.\n");
+    }
+    else if(move_details->class == NULL_MOVE) {
+        /* Non-standard PGN.
+        * Nothing more to be done.
+        */
+       Ok = TRUE;
+    }
+    else{
+        /* We have something -- normal case. */
+        const unsigned char *move = move_details->move;
+        MoveClass class = move_details->class;
+        Boolean move_handled = FALSE;
+
+        /* A new piece on promotion. */
+        move_details->promoted_piece = EMPTY;
+
+        /* Because the decoding process did not have the current board
+         * position available, trap apparent pawn moves that maybe something
+         * else.
+         * At the moment, only do this when full positional information is
+         * available.
+         */
+        if((class == PAWN_MOVE) &&
+                (move_details->from_col != 0) &&
+                       (move_details->from_rank != 0) &&
+                       (move_details->to_col != 0) &&
+                       (move_details->to_rank != 0)){
+            /* Try to work out its details and handle it below. */
+            move_details = decode_algebraic(move_details,board);
+            /* Pick up the new class. */
+            class = move_details->class;
+        }
+
+        /* Deal with apparent pawn moves first. */
+        if((class == PAWN_MOVE) || (class == ENPASSANT_PAWN_MOVE) ||
+                        (class == PAWN_MOVE_WITH_PROMOTION)){
+            move_details->piece_to_move = PAWN;
+            /* Fill in any promotional details. */
+            if(class == PAWN_MOVE){
+                /* Check for implicit promotion. */
+                if(((move_details->to_rank == LASTRANK) && (colour == WHITE)) ||
+                        ((move_details->to_rank == FIRSTRANK) && (colour == BLACK))){
+                    /* Don't modify move_details->class as we are not
+                     * adding the new piece to the move string.
+                     */
+                    class = PAWN_MOVE_WITH_PROMOTION;
+                    /* Since the move string doesn't tell us, we have to
+                     * assume a queen.
+                     */
+                    move_details->promoted_piece = QUEEN;
+                }
+            }
+            else if(class == ENPASSANT_PAWN_MOVE){
+                /* No promotion possible. */
+            }
+            else{
+                /* Pick up the promoted_piece from the move string. */
+                size_t last_char = strlen((const char *)move)-1;
+
+                /* Skip any check character. */
+                while(is_check(move[last_char])){
+                    last_char--;
+                }
+                /* Pick up what kind of piece it is. */
+                move_details->promoted_piece = is_piece(&move[last_char]);
+                switch(move_details->promoted_piece){
+                    case QUEEN: case ROOK: case BISHOP: case KNIGHT:
+                        /* Ok. */
+                        break;
+                    default:
+                        fprintf(GlobalState.logfile,
+                                    "Unknown piece in promotion %s\n",move);
+                        move_details->promoted_piece = EMPTY;
+                        break;
+                }
+            }
+            if((class == PAWN_MOVE) || (class == ENPASSANT_PAWN_MOVE)){
+                /* Check out the details and confirm the move's class. */
+                Ok = pawn_move(move_details,colour,board);
+                /* See if we are dealing with and En Passant move. */
+                if(Ok){
+                    if((board->EnPassant) &&
+                            (board->ep_rank == move_details->to_rank) &&
+                            (board->ep_col == move_details->to_col)){
+                        move_details->class = class = ENPASSANT_PAWN_MOVE;
+                    }
+                    else{
+                        /* Just in case the original designation was incorrect. */
+                        move_details->class = class = PAWN_MOVE;
+                    }
+                    move_handled = TRUE;
+                }
+            }
+            else if (class == PAWN_MOVE_WITH_PROMOTION){
+                /* Handle a move involving promotion. */
+                Ok = promote(move_details,colour,board);
+                move_handled = TRUE;
+            }
+            else{
+                /* Shouldn't get here. */
+            }
+            if(!move_handled){
+                /* We failed to find the move, for some reason. */
+                /* See if it might be a Bishop move with a lower case 'b'. */
+                if(move_details->move[0] == 'b'){
+                    /* See if we can find an valid Bishop alternative for it. */
+                    unsigned char alternative_move[MAX_MOVE_LEN+1];
+                    Move *alternative;
+
+                    strcpy((char *) alternative_move,
+                           (const char *)move_details->move);
+                    *alternative_move = 'B';
+                    alternative = decode_move((unsigned char *) alternative_move);
+                    if(alternative != NULL){
+                        Ok = bishop_move(alternative,colour,board);
+                        if(Ok){
+                            /* Copy the relevant details. */
+                            move_details->class = alternative->class;
+                            move_details->from_col = alternative->from_col;
+                            move_details->from_rank = alternative->from_rank;
+                            move_details->to_col = alternative->to_col;
+                            move_details->to_rank = alternative->to_rank;
+                            move_details->piece_to_move =
+                                        alternative->piece_to_move;
+                            free_move_list(alternative);
+                            move_handled = TRUE;
+                        }
+                    }
+                }
+            }
+        }
+        if(!move_handled){
+          /* Pick up any moves not handled as pawn moves.
+           * This includes algebraic moves that were originally assumed to
+           * be pawn moves.
+           */
+          switch(class){
+            case PAWN_MOVE:
+            case ENPASSANT_PAWN_MOVE:
+            case PAWN_MOVE_WITH_PROMOTION:
+                /* No more tries left. */
+                break;
+            case PIECE_MOVE:
+                switch(move_details->piece_to_move){
+                    case KING:
+                        Ok = king_move(move_details,colour,board);
+                        break;
+                    case QUEEN:
+                        Ok = queen_move(move_details,colour,board);
+                        break;
+                    case ROOK:
+                        Ok = rook_move(move_details,colour,board);
+                        break;
+                    case KNIGHT:
+                        Ok = knight_move(move_details,colour,board);
+                        break;
+                    case BISHOP:
+                        Ok = bishop_move(move_details,colour,board);
+                        break;
+                    default:
+                        Ok = FALSE;
+                        fprintf(GlobalState.logfile,"Unknown piece move %s\n",move);
+                        break;
+                }
+                break;
+            case KINGSIDE_CASTLE:
+                move_details->piece_to_move = KING;
+                Ok = kingside_castle(move_details,colour,board);
+                break;
+            case QUEENSIDE_CASTLE:
+                move_details->piece_to_move = KING;
+                Ok = queenside_castle(move_details,colour,board);
+                break;
+            case UNKNOWN_MOVE:
+                Ok = FALSE;
+                break;
+            default:
+                fprintf(GlobalState.logfile,
+                        "Unknown move class in determine_move_details(%d).\n",
+                                move_details->class);
+                break;
+          }
+        }
+        if(Ok){
+            /* Fill in the remaining items in move_details. */
+            short to_r = RankConvert(move_details->to_rank);
+            short to_c = ColConvert(move_details->to_col);
+
+            /* Keep track of any capture. */
+            if(board->board[to_r][to_c] != EMPTY){
+                move_details->captured_piece =
+                                EXTRACT_PIECE(board->board[to_r][to_c]);
+            }
+            else if(move_details->class == ENPASSANT_PAWN_MOVE){
+                move_details->captured_piece = PAWN;
+            }
+            else{
+                move_details->captured_piece = EMPTY;
+            }
+        }
+    }
+    return Ok;
+}
+
+    /* Generate a list of moves of a king or knight from from_col,from_rank.
+     * This does not include castling for the king, because it is used
+     * by the code that looks for ways to escape from check for which
+     * castling is illegal, of course.
+     */
+static MovePair *
+GenerateSingleMoves(Colour colour,Piece piece,
+                    const Board *board,Col from_col, Rank from_rank)
+{   short from_r = RankConvert(from_rank);
+    short from_c = ColConvert(from_col);
+    unsigned ix;
+    MovePair *moves = NULL;
+    Colour target_colour = OPPOSITE_COLOUR(colour);
+    unsigned num_directions = piece == KING?NUM_KING_MOVES:NUM_KNIGHT_MOVES;
+    const short *Piece_moves = piece == KING?King_moves:Knight_moves;
+
+    /* Pick up pairs of offsets from from_r,from_c to look for an
+     * EMPTY square, or one containing a piece of OPPOSITE_COLOUR(colour).
+     */
+    for(ix = 0; ix < 2*num_directions; ix += 2){
+        short r = Piece_moves[ix]+from_r;
+        short c = Piece_moves[ix+1]+from_c;
+        Piece occupant = board->board[r][c];
+        Boolean Ok = FALSE;
+
+        if(occupant == OFF){
+            /* Not a valid move. */
+        }
+        else if(board->board[r][c] == EMPTY){
+            Ok = TRUE;
+        }
+        else if(EXTRACT_COLOUR(occupant) == target_colour){
+            Ok = TRUE;
+        }
+        else{
+        }
+        if(Ok){
+            /* Fill in the details, and add it to the list. */
+            moves = append_move_pair(from_col,from_rank,ToCol(c),ToRank(r),moves);
+        }
+    }
+    if(moves != NULL){
+        moves = exclude_checks(piece,colour,moves,board);
+    }
+    return moves;
+}
+
+        /* Generate a list of moves of a queen, rook or bishop from
+         * from_col,from_rank.
+         */
+static MovePair *
+GenerateMultipleMoves(Colour colour,Piece piece,
+                const Board *board,Col from_col, Rank from_rank)
+{   short from_r = RankConvert(from_rank);
+    short from_c = ColConvert(from_col);
+    unsigned ix;
+    MovePair *moves = NULL;
+    Colour target_colour = OPPOSITE_COLOUR(colour);
+    unsigned num_directions = piece == QUEEN?NUM_QUEEN_MOVES:
+                                piece == ROOK?NUM_ROOK_MOVES:NUM_BISHOP_MOVES;
+    const short *Piece_moves = piece == QUEEN?Queen_moves:
+                                piece == ROOK?Rook_moves:Bishop_moves;
+
+    /* Pick up pairs of offsets from from_r,from_c to look for an
+     * EMPTY square, or one containing a piece of OPPOSITE_COLOUR(colour).
+     */
+    for(ix = 0; ix < 2*num_directions; ix += 2){
+        short r = Piece_moves[ix]+from_r;
+        short c = Piece_moves[ix+1]+from_c;
+        Piece occupant = board->board[r][c];
+
+        /* Include EMPTY squares as possible moves. */
+        while(occupant == EMPTY){
+            /* Fill in the details, and add it to the list. */
+            moves = append_move_pair(from_col,from_rank,ToCol(c),ToRank(r),moves);
+            /* Move on to the next square in this direction. */
+            r += Piece_moves[ix];
+            c += Piece_moves[ix+1];
+            occupant = board->board[r][c];
+        }
+        /* We have come up against an obstruction. */
+        if(occupant == OFF){
+            /* Not a valid move. */
+        }
+        else if(EXTRACT_COLOUR(occupant) == target_colour){
+            moves = append_move_pair(from_col,from_rank,ToCol(c),ToRank(r),moves);
+        }
+        else{
+            /* Should be a piece of our own colour. */
+        }
+    }
+    if(moves != NULL){
+        moves = exclude_checks(piece,colour,moves,board);
+    }
+    return moves;
+}
+
+        /* Generate a list of moves of a pawn from from_col,from_rank. */
+static MovePair *
+GeneratePawnMoves(Colour colour,const Board *board,Col from_col, Rank from_rank)
+{   MovePair *moves = NULL;
+    Piece piece = PAWN;
+    Colour target_colour = OPPOSITE_COLOUR(colour);
+    /* Determine the direction in which a pawn can move. */
+    short offset = colour == WHITE? 1 : -1;
+    short to_r, to_c = ColConvert(from_col);
+
+    /* Try single step ahead. */
+    to_r = RankConvert(from_rank)+offset;
+    if(board->board[to_r][to_c] == EMPTY){
+        /* Fill in the details, and add it to the list. */
+        moves = append_move_pair(from_col,from_rank,ToCol(to_c),ToRank(to_r),moves);
+        if(((colour == WHITE) && (from_rank == FIRSTRANK+1)) ||
+               ((colour == BLACK) && (from_rank == LASTRANK-1))){
+           /* Try two steps. */
+           to_r = RankConvert(from_rank)+2*offset;
+            if(board->board[to_r][to_c] == EMPTY){
+                moves = append_move_pair(from_col,from_rank,ToCol(to_c),ToRank(to_r),moves);
+            }
+        }
+    }
+    /* Try to left. */
+    to_r = RankConvert(from_rank)+offset;
+    to_c = ColConvert(from_col)-1;
+    if(board->board[to_r][to_c] == OFF){
+    }
+    else if(board->board[to_r][to_c] == EMPTY){
+        if(board->EnPassant && (ToRank(to_r) == board->ep_rank) &&
+                        (ToCol(to_c) == board->ep_col)){
+            moves = append_move_pair(from_col,from_rank,ToCol(to_c),ToRank(to_r),moves);
+        }
+    }
+    else if(EXTRACT_COLOUR(board->board[to_r][to_c]) == target_colour){
+        moves = append_move_pair(from_col,from_rank,ToCol(to_c),ToRank(to_r),moves);
+    }
+    else{
+    }
+
+    /* Try to right. */
+    to_r = RankConvert(from_rank)+offset;
+    to_c = ColConvert(from_col)+1;
+    if(board->board[to_r][to_c] == OFF){
+    }
+    else if(board->board[to_r][to_c] == EMPTY){
+        if(board->EnPassant && (ToRank(to_r) == board->ep_rank) &&
+                        (ToCol(to_c) == board->ep_col)){
+            moves = append_move_pair(from_col,from_rank,ToCol(to_c),ToRank(to_r),moves);
+        }
+    }
+    else if(EXTRACT_COLOUR(board->board[to_r][to_c]) == target_colour){
+        moves = append_move_pair(from_col,from_rank,ToCol(to_c),ToRank(to_r),moves);
+    }
+    else{
+    }
+
+    if(moves != NULL){
+        moves = exclude_checks(piece,colour,moves,board);
+    }
+    return moves;
+}
+
+        /* See whether the king of the given colour is in checkmate.
+         * Assuming that the king is in check, generate all possible moves
+         * for colour on board until at least one saving move is found.
+         * Excepted from this are the castling moves (not legal whilst in check)
+         * and underpromotions (inadequate in thwarting a check).
+         */
+Boolean
+king_is_in_checkmate(Colour colour,Board *board)
+{  Rank rank;
+   Col col;
+   MovePair *moves = NULL;
+   Boolean in_checkmate = FALSE;
+
+   /* Search the board for pieces of the right colour.
+    * Keep going until we have exhausted all pieces, or until
+    * we have found a saving move.
+    */
+   for(rank = LASTRANK; (rank >= FIRSTRANK) && (moves == NULL); rank--){
+       for(col = FIRSTCOL; (col <= LASTCOL) && (moves == NULL); col++){
+           short r = RankConvert(rank);
+           short c = ColConvert(col);
+           Piece occupant = board->board[r][c];
+
+           if((occupant != EMPTY) && (colour == EXTRACT_COLOUR(occupant))){
+               /* This square is occupied by a piece of the required colour. */
+               Piece piece = EXTRACT_PIECE(occupant);
+
+               switch(piece){
+                   case KING:
+                   case KNIGHT:
+                       moves = GenerateSingleMoves(colour,piece,board,col,rank);
+                       break;
+                   case QUEEN:
+                   case ROOK:
+                   case BISHOP:
+                       moves = GenerateMultipleMoves(colour,piece,board,col,rank);
+                       break;
+                   case PAWN:
+                       moves = GeneratePawnMoves(colour,board,col,rank);
+                       break;
+                   default:
+                       fprintf(GlobalState.logfile,
+                           "Internal error: unknown piece %d in king_is_in_checmate().\n",
+                               piece);
+                }
+           }
+       }
+   }
+   if(moves != NULL){
+        /* No checkmate.  Free the move list. */
+        free_move_pair_list(moves);
+   }
+   else{
+       in_checkmate = TRUE;
+   }
+   return in_checkmate;
+}
+
+#if INCLUDE_UNUSED_FUNCTIONS
+
+        /* Return an approximation of how many moves there are for
+         * board->to_move on board.
+         * This may be exact, but I haven't checked.
+         * This is not currently used, but I found it useful at one
+         * point for generating game statistics.
+         */
+static unsigned
+approx_how_many_moves(Board *board)
+{  Rank rank;
+   Col col;
+   Colour colour = board->to_move;
+   unsigned num_moves = 0;
+
+   /* Search the board for pieces of the right colour.
+    * Keep going until we have exhausted all pieces, or until
+    * we have found a saving move.
+    */
+   for(rank = LASTRANK; rank >= FIRSTRANK; rank--){
+       for(col = FIRSTCOL; col <= LASTCOL; col++){
+           short r = RankConvert(rank);
+           short c = ColConvert(col);
+           Piece occupant = board->board[r][c];
+           MovePair *moves = NULL;
+
+           if((occupant != EMPTY) && (colour == EXTRACT_COLOUR(occupant))){
+               /* This square is occupied by a piece of the required colour. */
+               Piece piece = EXTRACT_PIECE(occupant);
+
+               switch(piece){
+                   case KING:
+                   case KNIGHT:
+                       moves = GenerateSingleMoves(colour,piece,board,col,rank);
+                       break;
+                   case QUEEN:
+                   case ROOK:
+                   case BISHOP:
+                       moves = GenerateMultipleMoves(colour,piece,board,col,rank);
+                       break;
+                   case PAWN:
+                       moves = GeneratePawnMoves(colour,board,col,rank);
+                       break;
+                   default:
+                       fprintf(GlobalState.logfile,
+                           "Internal error: unknown piece %d in king_is_in_checmate().\n",
+                               piece);
+                }
+               if(moves != NULL){
+                    /* At least one move. */
+                    MovePair *m;
+                    for(m = moves; m != NULL; m = m->next){
+                        num_moves++;
+                    }
+                    /* Free the move list. */
+                    free_move_pair_list(moves);
+               }
+           }
+       }
+   }
+   return num_moves;
+}
+#endif
+
+        /* Find all moves for colour board. */
+MovePair *
+find_all_moves(const Board *board, Colour colour)
+{  Rank rank;
+   Col col;
+   /* All moves for colour. */
+   MovePair *all_moves = NULL;
+
+   /* Pick up each piece of the required colour. */
+   for(rank = LASTRANK; rank >= FIRSTRANK; rank--){
+       short r = RankConvert(rank);
+       for(col = FIRSTCOL; col <= LASTCOL; col++){
+           short c = ColConvert(col);
+           Piece occupant = board->board[r][c];
+
+           if((occupant != EMPTY) && (colour == EXTRACT_COLOUR(occupant))){
+               /* This square is occupied by a piece of the required colour. */
+               Piece piece = EXTRACT_PIECE(occupant);
+                   /* List of moves for this piece. */
+                   MovePair *moves = NULL;
+
+               switch(piece){
+                   case KING:
+                       moves = GenerateSingleMoves(colour,piece,board,col,rank);
+                       /* Add any castling, as this is not covered
+                        * by GenerateSingleMoves.
+                        */
+                       if(can_castle_kingside(colour,board)){
+                           MovePair *m = (MovePair *)
+                                   MallocOrDie(sizeof(MovePair));
+                           m->from_col = 'e';
+                           m->from_rank = rank;
+                           m->to_col = 'g';
+                           m->to_rank = rank;
+                           /* Prepend. */
+                           m->next = moves;
+                           moves = m;
+                       }
+                       if(can_castle_queenside(colour,board)){
+                           MovePair *m = (MovePair *)
+                                   MallocOrDie(sizeof(MovePair));
+                           m->from_col = 'e';
+                           m->from_rank = rank;
+                           m->to_col = 'c';
+                           m->to_rank = rank;
+                           /* Prepend. */
+                           m->next = moves;
+                           moves = m;
+                       }
+                       break;
+                   case KNIGHT:
+                       moves = GenerateSingleMoves(colour,piece,board,col,rank);
+                       break;
+                   case QUEEN:
+                   case ROOK:
+                   case BISHOP:
+                       moves = GenerateMultipleMoves(colour,piece,board,col,rank);
+                       break;
+                   case PAWN:
+                       moves = GeneratePawnMoves(colour,board,col,rank);
+                       break;
+                   default:
+                       fprintf(GlobalState.logfile,
+                           "Internal error: unknown piece %d in king_is_in_checmate().\n",
+                               piece);
+                }
+               if(moves != NULL){
+                    /* At least one move.
+                     * Append what we have so far to this list.
+                     * Find the last one.
+                     */
+                    MovePair *m;
+                    for(m = moves; m->next != NULL; m = m->next){
+                    }
+                    m->next = all_moves;
+                    all_moves = moves;
+               }
+           }
+       }
+   }
+   return all_moves;
+}
+
diff --git a/map.h b/map.h
new file mode 100644 (file)
index 0000000..8b1d00f
--- /dev/null
+++ b/map.h
@@ -0,0 +1,40 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+void init_hashtab(void);
+Boolean determine_move_details(Colour colour,Move *move_details, Board *board);
+HashCode HashLookup(Col col, Rank rank, Piece piece, Colour colour);
+void make_move(MoveClass class, Col from_col, Rank from_rank, Col to_col, Rank to_rank,
+                Piece piece, Colour colour,Board *board);
+CheckStatus king_is_in_check(const Board *board,Colour king_colour);
+MovePair *find_pawn_moves(Col from_col, Rank from_rank, Col to_col,Rank to_rank,
+                Colour colour, const Board *board);
+MovePair *find_knight_moves(Col to_col,Rank to_rank, Colour colour, const Board *board);
+MovePair *find_bishop_moves(Col to_col,Rank to_rank, Colour colour, const Board *board);
+MovePair *find_rook_moves(Col to_col,Rank to_rank, Colour colour, const Board *board);
+MovePair *find_queen_moves(Col to_col,Rank to_rank, Colour colour, const Board *board);
+MovePair *find_king_moves(Col to_col,Rank to_rank, Colour colour, const Board *board);
+MovePair *exclude_checks(Piece piece, Colour colour,MovePair *possibles,
+                                const Board *board);
+void free_move_pair_list(MovePair *move_list);
+Boolean king_is_in_checkmate(Colour colour,Board *board);
+MovePair *find_all_moves(const Board *board, Colour colour);
diff --git a/moves.c b/moves.c
new file mode 100644 (file)
index 0000000..58dd2b2
--- /dev/null
+++ b/moves.c
@@ -0,0 +1,779 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+        /***
+         * These routines are concerned with gathering moves of
+         * the various sorts of variations specified by the -v
+         * and -x flags.  In the former case, there are also functions
+         * for checking the moves of a game against the variation
+         * lists that are wanted.  Checking of the variations specified
+         * by the -x flag is handled elsewhere by apply_move_list().
+         */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "bool.h"
+#include "mymalloc.h"
+#include "lines.h"
+#include "defs.h"
+#include "typedef.h"
+#include "map.h"
+#include "lists.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "lex.h"
+#include "moves.h"
+#include "apply.h"
+#include "decode.h"
+#include "fenmatcher.h"
+
+/* Define a character that can be used in the variations file to
+ * mean that we don't mind what move was played at this point.
+ * So: 
+ *        * b6
+ * means look for all games in which Black playes 1...b6, regardless
+ * of White's first move.
+ */
+#define ANY_MOVE '*'
+/* Define a character that can be used in the variations file to
+ * mean that we do not wish to match a particular move.
+ * So:
+ *        e4 c5 !Nf3
+ * means look for games in which Black does not play 2. Nf3 against
+ * the Sicilian defence.
+ */
+#define DISALLOWED_MOVE '!'
+
+    /* Hold details of a single move within a variation. */
+typedef struct{
+    /* Characters of the move.
+     * Alternative notations for the same move are separated by
+     * a non-move character, e.g.:
+     *        cxd|cxd4|c5xd4
+     * could all be alternatives for the same basic pawn capture.
+     */
+    char *move;
+    /* If we are interested in matching the moves in any order,
+     * then we need to record whether or not the current move has
+     * been matched or not.
+     */
+    Boolean matched;
+} variant_move;
+
+    /* Hold details of a single variation, with a pointer to
+     * an alternative variation.
+     */
+typedef struct variation_list {
+    /* The list of moves. */
+    variant_move *moves;
+    /* Keep a count of how many ANY_MOVE moves there are in the move
+     * list for each colour.  If these are non-zero then one is used
+     * when a match fails when looking for permutations.
+     */
+    unsigned num_white_any_moves;
+    unsigned num_black_any_moves;
+    /* Keep a count of how many DISALLOWED_MOVE moves there are in the move
+     * list for each colour.  If these are non-zero then the game
+     * must be searched for them when looking for permutations before
+     * the full search is made.
+     */
+    unsigned num_white_disallowed_moves;
+    unsigned num_black_disallowed_moves;
+    /* How many half-moves in the variation? */
+    unsigned length;
+    struct variation_list *next;
+} variation_list;
+
+    /* The head of the variations-of-interest list. */
+static variation_list *games_to_keep = NULL;
+
+static Boolean textual_variation_match(const char *variation_move,
+                                        const unsigned char *actual_move);
+
+        /*** Functions concerned with reading details of the variations
+         *** of interest.
+         ***/
+
+        /* Remove any move number prefix from str.
+         * Return NULL if there is no move (only number)
+         * otherwise return the head of the move portion.
+         */
+static char *
+strip_move_number(char *str)
+{
+    while(isdigit((int) *str)){
+      str++;
+    }
+    while(*str == '.'){
+      str++;
+    }
+    if(*str != '\0'){
+        return str;
+    }
+    else{
+        return (char *)NULL;
+    }
+}
+
+
+
+/* Define values for malloc/realloc allocation. */
+#define INIT_MOVE_NUMBER 10
+#define MOVE_INCREMENT 5
+
+        /* Break up a single line of moves into a list of moves
+         * comprising a variation.
+         */
+static variation_list *
+compose_variation(char *line)
+{   variation_list *variation;
+    variant_move *move_list;
+    /* Keep track of the number of moves extracted from line. */
+    unsigned num_moves = 0;
+    unsigned max_moves = 0;
+    char *move;
+
+    variation = (variation_list *)MallocOrDie(sizeof(variation_list));
+    /* We don't yet know how many ANY_MOVEs or DISALLOWED_MOVES there
+     * will be in this variation.
+     */
+    variation->num_white_any_moves = 0;
+    variation->num_black_any_moves = 0;
+    variation->num_white_disallowed_moves = 0;
+    variation->num_black_disallowed_moves = 0;
+    /* Allocate an initial number of pointers for the moves of the variation. */
+    move_list = (variant_move *) MallocOrDie(INIT_MOVE_NUMBER *
+                                             sizeof(*move_list));
+    max_moves = INIT_MOVE_NUMBER;
+    /* Find the first move. */
+    move = strtok(line," ");
+    while(move != NULL){
+        if((move = strip_move_number(move)) == NULL){
+            /* Only a move number. */
+        }
+        else{
+            /* See if we need some more space. */
+            if(num_moves == max_moves){
+                 move_list = (variant_move *)realloc((void *)move_list,
+                            (max_moves+MOVE_INCREMENT) * sizeof(*move_list));
+                 if(move_list == NULL){
+                     /* Catastrophic failure. */
+                     free((void *)variation);
+                     return NULL;
+                 }
+                 else{
+                     max_moves += MOVE_INCREMENT;
+                 }
+            }
+            /* Keep the move and initialise the matched field for
+             * when we start matching games.
+             */
+            move_list[num_moves].move = move;
+            move_list[num_moves].matched = FALSE;
+            /* Keep track of moves that will match anything. */
+            if(*move == ANY_MOVE){
+                /* Odd numbered half-moves in the variant list are Black. */
+                if(num_moves & 0x01){
+                    variation->num_black_any_moves++;
+                }
+                else{
+                    variation->num_white_any_moves++;
+                }
+                /* Beware of the potential for false matches. */
+                if(strlen(move) > 1){
+                    fprintf(GlobalState.logfile,
+                        "Warning: %c in %s should not be followed by additional move text.\n",
+                            *move,move);
+                    fprintf(GlobalState.logfile,"It could give false matches.\n");
+                }
+            }
+            else if(*move == DISALLOWED_MOVE){
+                /* Odd numbered half-moves in the variant list are Black. */
+                if(num_moves & 0x01){
+                    variation->num_black_disallowed_moves++;
+                }
+                else{
+                    variation->num_white_disallowed_moves++;
+                }
+            }
+            else{
+                /* Unadorned move. */
+            }
+            num_moves++;
+        }
+        move = strtok((char *)NULL," ");
+    }
+    variation->moves = move_list;
+    variation->length = num_moves;
+    variation->next = NULL;
+    return variation;
+}
+
+        /* Read each line of input and decompose it into a variation
+         * to be placed in the games_to_keep list.
+         */
+void
+add_textual_variations_from_file(FILE *fpin)
+{   char *line;
+
+    while((line = read_line(fpin)) != NULL){
+        add_textual_variation_from_line(line);
+    }
+}
+
+        /* Add the text of the given line to the list of games_to_keep.
+         */
+void
+add_textual_variation_from_line(char *line)
+{
+    if(non_blank_line(line)){
+        variation_list *next_variation = compose_variation(line);
+        if(next_variation != NULL){
+            next_variation->next = games_to_keep;
+            games_to_keep = next_variation;
+        }
+    }
+}
+
+        /*** Functions concerned with reading details of the positional
+         *** variations of interest.
+         ***/
+
+        /* Break up a single line of moves into a list of moves
+         * comprising a positional variation.
+         * In doing so, set GlobalState.depth_of_positional_search
+         * if this variation is longer than the default.
+         */
+static Move *
+compose_positional_variation(char *line)
+{   char *move;
+    /* Build a linked list of the moves of the variation. */
+    Move *head = NULL, *tail = NULL;
+    Boolean Ok = TRUE;
+    /* Keep track of the depth. */
+    unsigned depth = 0;
+
+    move = strtok(line," ");
+    while(Ok && (move != NULL) && (*move != '*')){
+        if((move = strip_move_number(move)) == NULL){
+            /* Only a move number. */
+        }
+        else{
+            Move *next = decode_move((unsigned char *) move);
+
+            if(next == NULL){
+                fprintf(GlobalState.logfile,"Failed to identify %s\n",move);
+                Ok = FALSE;
+            }
+            else{
+                /* Chain it on to the list. */
+                if(tail == NULL){
+                    head = next;
+                    tail = next;
+                }
+                else{
+                    tail->next = next;
+                    tail = next;
+                }
+                next->next = NULL;
+            }
+            depth++;
+        }
+        /* Pick up the next likely move. */
+        move = strtok(NULL," ");
+    }
+    if(Ok){
+        /* Determine whether the depth of this variation exceeds
+         * the current default.
+         * Depth is counted in move pairs.
+         * Add some extras, in order to be surer of catching transpositions.
+         */
+        depth = ((depth+1) / 2) + 4;
+        if(depth > GlobalState.depth_of_positional_search){
+            GlobalState.depth_of_positional_search = depth;
+        }
+    }
+    else{
+        if(head != NULL){
+            free_move_list(head);
+        }
+        head = NULL;
+    }
+    return head;
+}
+
+        /* Read each line of input and decompose it into a positional variation
+         * to be placed in the list of required hash values.
+         */
+void
+add_positional_variations_from_file(FILE *fpin)
+{   char *line;
+
+    while((line = read_line(fpin)) != NULL){
+        add_positional_variation_from_line(line);
+    }
+}
+
+void
+add_positional_variation_from_line(char *line)
+{
+    if(non_blank_line(line)){
+        Move *next_variation = compose_positional_variation(line);
+        if(next_variation != NULL){
+            /* We need a NULL fen string, because this is from
+             * the initial position.
+             */
+            store_hash_value(next_variation,(const char *)NULL);
+            free_move_list(next_variation);
+            /* We need to know globally that positional variations
+             * are of interest.
+             */
+            GlobalState.positional_variations = TRUE;
+        }
+    }
+}
+
+        /* Treat fen_string as being a position to be matched.
+         */
+void
+add_fen_positional_match(const char *fen_string)
+{
+    store_hash_value((Move *)NULL,fen_string);
+    GlobalState.positional_variations = TRUE;
+}
+
+        /* Treat fen_pattern as being a position to be matched.
+         */
+void
+add_fen_pattern_match(const char *fen_pattern)
+{
+    add_fen_pattern(fen_pattern);
+    GlobalState.positional_variations = TRUE;
+}
+
+        /* Roughly define a move character for the purposes of textual
+         * matching.
+         */
+static Boolean
+move_char(char c)
+{
+    return (Boolean) isalpha((int) c) || isdigit((int) c) || (c == '-');
+}
+
+        /* Return TRUE if there is a match for actual_move in variation_move.
+         * A match means that the string in actual_move is found surrounded
+         * by non-move characters in variation_move. For instance,
+         *    variation_move == "Nc6|Nf3|f3" would match
+         *    actual_move == "f3" but not actual_move == "c6".
+         */
+static Boolean
+textual_variation_match(const char *variation_move,const unsigned char *actual_move)
+{   const char *match_point;
+    Boolean found = FALSE;
+
+    for(match_point = variation_move; !found && (match_point != NULL); ){
+        /* Try for a match from where we are. */
+        match_point = strstr(match_point,(const char *) actual_move);
+        if(match_point != NULL){
+            /* A possible match. Make sure that the match point
+             * is surrounded by non-move characters so as to be sure
+             * that we haven't picked up part way through a variation string.
+             * Assume success.
+             */
+            found = TRUE;
+            if(match_point != variation_move){
+                if(move_char(match_point[-1])){
+                    found = FALSE;
+                }
+            }
+            if(move_char(match_point[strlen((const char *) actual_move)])){
+                found = FALSE;
+            }
+            if(!found){
+                /* Move on the match point and try again. */
+                while(move_char(*match_point)){
+                    match_point++;
+                }
+            }
+        }
+    }
+    return found;
+                        
+}
+
+        /*** Functions concerned with matching the moves of the current game
+         *** against the variations of interest.
+         ***/
+
+        /* Do the moves of the current game match the given variation?
+         * Go for a straight 1-1 match in the ordering, without considering
+         * permutations.
+         * Return TRUE if so, FALSE otherwise.
+         */
+static Boolean
+straight_match(Move *current_game_head, variation_list variation)
+{
+    variant_move *moves_of_the_variation;
+    /* Which is the next move that we wish to match. */
+    Move *next_move;
+    unsigned move_index = 0;
+    /* Assume that it matches. */
+    Boolean matches = TRUE;
+
+    /* Access the head of the current game. */
+    next_move = current_game_head;
+    /* Go for a straight move-by-move match in the order in which
+     * the variation is listed.
+     * Point at the head of the moves list.
+     */
+    moves_of_the_variation = variation.moves;
+    move_index = 0;
+    while(matches && (next_move != NULL) && (move_index < variation.length)){
+        Boolean this_move_matches;
+
+        if(*(moves_of_the_variation[move_index].move) == ANY_MOVE){
+            /* Still matching as we don't care what the actual move is. */
+        }
+        else{
+            this_move_matches =
+                textual_variation_match(moves_of_the_variation[move_index].move,
+                                            next_move->move);
+            if(this_move_matches){
+                /* We found a match, check that it isn't disallowed. */
+                if(*moves_of_the_variation[move_index].move == DISALLOWED_MOVE){
+                    /* This move is disallowed and implies failure. */
+                    matches = FALSE;
+                }
+            }
+            else{
+                if(*moves_of_the_variation[move_index].move != DISALLOWED_MOVE){
+                    /* No match found for this move. */
+                    matches = FALSE;
+                }
+                else{
+                    /* This is ok, because we didn't want a match. */
+                }
+            }
+                
+        }
+        /* If we are still matching, go on to the next move. */
+        if(matches){
+            move_index++;
+            next_move = next_move->next;
+        }
+    }
+    /* The game could be shorter than the variation, so don't rely
+     * on the fact that matches is still true.
+     */
+    matches = (move_index == variation.length);
+    return matches;
+}
+
+    /* Do the moves of the current game match the given variation?
+     * Try all possible orderings for the moves, within the
+     * constraint of proper WHITE/BLACK moves.
+     * The parameter variation is passed as a copy because we modify
+     * the num_ fields within it.
+     * Note that there is a possibility of a false match in this
+     * function if a variant move is specified in a form such as:
+     *                *|c4
+     * This is because the num_ field is set from this on the basis of the
+     * ANY_MOVE character at the start.  However, this could also match a
+     * normal move with its c4 component.  If it is used for the latter
+     * purpose then it should not count as an any_ move.  There is a warning
+     * issued about this when variations are read in.
+     * Return TRUE if we match, FALSE otherwise.
+     *
+     * The DISALLOWED_MOVE presents some problems with permutation matches
+     * because an ANY_MOVE could match an otherwise disallowed move. The
+     * approach that has been taken is to cause matching of a single disallowed
+     * move to result in complete failure of the current match.
+     */
+static Boolean
+permutation_match(Move *current_game_head, variation_list variation)
+{   variant_move *moves_of_the_variation;
+    /* Which is the next move that we wish to match? */
+    Move *next_move;
+    unsigned variant_index = 0;
+    /* Assume that it matches. */
+    Boolean matches = TRUE;
+    /* How many moves have we matched?
+     * When this reaches variation.length we have a full match.
+     */
+    unsigned matched_moves = 0;
+    Boolean white_to_move = TRUE;
+
+    moves_of_the_variation = variation.moves;
+    /* Clear all of the matched fields of the variation. */
+    for(variant_index = 0; variant_index < variation.length; variant_index++){
+        moves_of_the_variation[variant_index].matched = FALSE;
+    }
+    /* Access the head of the current game. */
+    next_move = current_game_head;
+
+    /*** Stage One.
+     * The first task is to ensure that there are no DISALLOWED_MOVEs in
+     * the current game.
+     */
+    if((variation.num_white_disallowed_moves > 0) ||
+            (variation.num_black_disallowed_moves > 0)){
+        unsigned tested_moves = 0;
+        Boolean disallowed_move_found = FALSE;
+
+        /* Keep going as long as we still have not found a diallowed move,
+         * we haven't matched the whole variation, and we haven't reached the end of
+         * the game.
+         */
+        while((!disallowed_move_found) && (tested_moves < variation.length) &&
+                                        (next_move != NULL)){
+            /* We want to see if next_move is a disallowed move of the variation. */
+            if(white_to_move){
+                /* White; start with the first move. */
+                variant_index = 0;
+            }
+            else{
+                /* For a Black move, start at the second half-move in the list, if any. */
+                variant_index = 1;
+            }
+            /* Try each move of the variation in turn, until a match is found. */
+            while((!disallowed_move_found) && (variant_index < variation.length)){
+                if((*moves_of_the_variation[variant_index].move ==
+                            DISALLOWED_MOVE) &&
+                   (textual_variation_match(
+                      moves_of_the_variation[variant_index].move,next_move->move))){
+                    /* Found one. */
+                    disallowed_move_found = TRUE;
+                }
+                if(!disallowed_move_found){
+                    /* Move on to the next available move -- 2 half moves along. */
+                    variant_index += 2;
+                }
+            }
+            if(!disallowed_move_found){
+                /* Ok so far, so move on. */
+                tested_moves++;
+                white_to_move = !white_to_move;
+                next_move = next_move->next;
+            }
+        }
+        if(disallowed_move_found){
+            /* This rules out the whole match. */
+            matches = FALSE;
+        }
+        else{
+            /* In effect, each DISALLOWED_MOVE now becomes an ANY_MOVE. */
+            for(variant_index = 0; variant_index < variation.length; variant_index++){
+                if(*moves_of_the_variation[variant_index].move == DISALLOWED_MOVE){
+                    moves_of_the_variation[variant_index].matched = TRUE;
+                    if((variant_index & 1) == 0){
+                        variation.num_white_any_moves++;
+                    }
+                    else{
+                        variation.num_black_any_moves++;
+                    }
+                }
+            }
+        }
+    }
+
+    /*** Stage Two.
+     * Having eliminated moves which have been disallowed, try permutations
+     * of the variation against the moves of the current game.
+     */
+    /* Access the head of the current game. */
+    next_move = current_game_head;
+    white_to_move = TRUE;
+    /* Keep going as long as we still have matches, we haven't
+     * matched the whole variation, and we haven't reached the end of
+     * the game.
+     */
+    while(matches && (matched_moves < variation.length) && (next_move != NULL)){
+        /* Assume failure. */
+        matches = FALSE;
+        /* We want to find next_move in an unmatched move of the variation. */
+        if(white_to_move){
+            /* Start with the first move. */
+            variant_index = 0;
+        }
+        else{
+            /* For a Black move, start at the second half-move in the list, if any. */
+            variant_index = 1;
+        }
+        /* Try each move of the variation in turn, until a match is found. */
+        while((!matches) && (variant_index < variation.length)){
+            if(moves_of_the_variation[variant_index].matched){
+                /* We can't try this. */
+            }
+            else{
+                Boolean this_move_matches = textual_variation_match(
+                            moves_of_the_variation[variant_index].move,
+                                        next_move->move);
+                if(this_move_matches){
+                    /* Found it. */
+                    moves_of_the_variation[variant_index].matched = TRUE;
+                    matches = TRUE;
+                }
+            }
+            if(!matches){
+                /* Move on to the next available move -- 2 half moves along. */
+                variant_index += 2;
+            }
+        }
+        /* See if we made a straight match. */
+        if(!matches){
+            /* See if we have some ANY_MOVEs available. */
+            if(white_to_move && (variation.num_white_any_moves > 0)){
+                matches = TRUE;
+                variation.num_white_any_moves--;
+            }
+            else if(!white_to_move && (variation.num_black_any_moves > 0)){
+                matches = TRUE;
+                variation.num_black_any_moves--;
+            }
+            else{
+                /* No slack. */
+            }
+        }
+        /* We have tried everything, did we succeed? */
+        if(matches){
+            /* Yes, so move on. */
+            matched_moves++;
+            next_move = next_move->next;
+            white_to_move = !white_to_move;
+        }
+    }
+    if(matches){
+        /* Ensure that we completed the variation. */
+        matches = matched_moves == (variation.length);
+    }
+    return matches;
+}
+
+
+        /* Determine whether or not the current game is wanted.
+         * It will be if we are either not looking for checkmate-only
+         * games, or if we are and the games does end in checkmate.
+         */
+Boolean
+check_for_only_checkmate(const Move *moves)
+{
+    if(GlobalState.match_only_checkmate) {
+        /* Check that the final move is checkmate. */
+        while(moves != NULL && moves->check_status != CHECKMATE) {
+            moves = moves->next;
+        }
+        if(moves == NULL) {
+            return FALSE;
+        }
+        else {
+            return TRUE;
+        }
+    }
+    else {
+        /* No restriction to a checkmate game. */
+        return TRUE;
+    }
+}
+
+        /* Determine whether or not the current game is wanted.
+         * It will be if we are either not looking for stalemate-only
+         * games, or if we are and the games does end in stalemate.
+         */
+Boolean
+check_for_only_stalemate(const Board *board, const Move *moves)
+{
+    if(GlobalState.match_only_stalemate) {
+        const Move *move = moves;
+        if(move != NULL) {
+            MovePair *available_moves;
+
+            /* Check that the final move is not check or checkmate. */
+            while(move->next != NULL) {
+                move = move->next;
+            }
+            if(move->check_status != NOCHECK) {
+                /* Cannot be stalemate. */
+                return FALSE;
+            }
+            /* See if the player to move has any moves available. */
+            available_moves = find_all_moves(board, board->to_move);
+            if(available_moves == NULL) {
+                return TRUE;
+            }
+            else {
+                return FALSE;
+            }
+        }
+        else {
+            return TRUE;
+        }
+    }
+    else {
+        /* No restriction to a stalemate game. */
+        return TRUE;
+    }
+}
+        /* Determine whether or not the current game is wanted.
+         * It will be if it matches one of the current variations
+         * and its tag details match those that we are interested in.
+         */
+Boolean
+check_textual_variations(Game game_details)
+{   Boolean wanted = FALSE;
+    variation_list *variation;
+
+    if(games_to_keep != NULL){
+        for(variation = games_to_keep; (variation != NULL) && !wanted;
+                    variation = variation->next){
+            if(GlobalState.match_permutations){
+                wanted = permutation_match(game_details.moves,*variation);
+            }
+            else{
+                wanted = straight_match(game_details.moves,*variation);
+            }
+        }
+    }
+    else{
+        /* There are no variations, assume that selection is done
+         * on the basis of the Details.
+         */
+        wanted = TRUE;
+    }
+    return wanted;
+}
+
+        /* Determine whether the number of moves in this game
+         * is within the bounds of what we want.
+         */
+Boolean
+check_move_bounds(unsigned plycount)
+{   Boolean in_bounds = TRUE;
+
+    unsigned number_of_moves = (plycount + 1) / 2;
+    if(GlobalState.check_move_bounds){
+         in_bounds = (GlobalState.lower_move_bound <= number_of_moves) &&
+                         (number_of_moves <= GlobalState.upper_move_bound);
+    }
+    return in_bounds;
+}
diff --git a/moves.h b/moves.h
new file mode 100644 (file)
index 0000000..97b89a9
--- /dev/null
+++ b/moves.h
@@ -0,0 +1,32 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+void add_positional_variations_from_file(FILE *fpin);
+void add_positional_variation_from_line(char *line);
+void add_textual_variations_from_file(FILE *fpin);
+void add_textual_variation_from_line(char *line);
+Boolean check_textual_variations(Game game_details);
+Boolean check_move_bounds(unsigned plycount);
+void add_fen_positional_match(const char *fen_string);
+void add_fen_pattern_match(const char *fen_pattern);
+Boolean check_for_only_checkmate(const Move *moves);
+Boolean check_for_only_stalemate(const Board *board, const Move *moves);
diff --git a/mymalloc.c b/mymalloc.c
new file mode 100644 (file)
index 0000000..a23d156
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "mymalloc.h"
+
+void *
+MallocOrDie(size_t nbytes)
+{   void *result;
+
+    result = malloc(nbytes);
+    if(result == NULL){
+        perror("Malloc Or Die");
+        abort();
+    }
+    return result;
+}
+
+void *
+ReallocOrDie(void *space,size_t nbytes)
+{   void *result;
+
+    result = realloc(space,nbytes);
+    if(result == NULL){
+        perror("Realloc Or Die");
+        abort();
+    }
+    return result;
+}
diff --git a/mymalloc.h b/mymalloc.h
new file mode 100644 (file)
index 0000000..8ea796d
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+void *MallocOrDie(size_t nbytes);
+void *ReallocOrDie(void *space,size_t nbytes);
diff --git a/output.c b/output.c
new file mode 100644 (file)
index 0000000..2878b00
--- /dev/null
+++ b/output.c
@@ -0,0 +1,1279 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "bool.h"
+#include "defs.h"
+#include "typedef.h"
+#include "taglist.h"
+#include "tokens.h"
+#include "lex.h"
+#include "grammar.h"
+#include "apply.h"
+#include "output.h"
+#include "mymalloc.h"
+
+
+            /* Functions for outputting games in the required format. */
+
+/* Define the width in which to print a CM move and move number. */
+#define MOVE_NUMBER_WIDTH 3
+#define MOVE_WIDTH 15
+#define CM_COMMENT_CHAR ';'
+/* Define the width of the moves area before a comment. */
+#define COMMENT_INDENT (MOVE_NUMBER_WIDTH+2+2*MOVE_WIDTH)
+
+/* Define a macro to calculate an array's size. */
+#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(*arr))
+
+/* How much text we have output on the current line. */
+static size_t line_length = 0;
+/* The buffer in which each output line of a game is built. */
+static char *output_line = NULL;
+
+static Boolean print_move(FILE *outputfile, unsigned move_number,
+                          unsigned print_move_number, Boolean white_to_move,
+                          const Move *move_details);
+static void output_STR(FILE *outfp,char **Tags);
+static void show_tags(FILE *outfp,char **Tags,int tags_length);
+static char promoted_piece_letter(Piece piece);
+static void print_algebraic_game(Game current_game,FILE *outputfile,
+                           unsigned move_number,Boolean white_to_move,
+                           Board *final_board);
+static void print_epd_game(Game current_game,FILE *outputfile,
+                           unsigned move_number,Boolean white_to_move,
+                           Board *final_board);
+static void print_epd_move_list(Game current_game,FILE *outputfile,
+                                unsigned move_number, Boolean white_to_move,
+                                Board *final_board);
+static const char *build_FEN_comment(const Board *board);
+static void add_total_plycount(const Game *game, Boolean count_variations);
+static void add_hashcode_tag(const Game *game);
+static unsigned count_single_move_ply(const Move *move_details, Boolean count_variations);
+static unsigned count_move_list_ply(Move *move_list, Boolean count_variations);
+
+        /* List, the order in which the tags should be output.
+         * The first seven should be the Seven Tag Roster that should
+         * be present in every game.
+         * The order of the remainder is, I believe, a matter of taste.
+         * any PSEUDO_*_TAGs should not appear in this list.
+         */
+
+    /* Give the array an int type, because a negative value is
+     * used as a terminator.
+     */
+static int DefaultTagOrder[] = {
+    EVENT_TAG, SITE_TAG, DATE_TAG, ROUND_TAG, WHITE_TAG, BLACK_TAG, RESULT_TAG,
+#if 1
+    /* @@@ Consider omitting some of these from the default ordering,
+     * and allow the output order to be determined from the
+     * input order.
+     */
+    WHITE_TITLE_TAG, BLACK_TITLE_TAG, WHITE_ELO_TAG, BLACK_ELO_TAG,
+    WHITE_USCF_TAG, BLACK_USCF_TAG,
+    WHITE_TYPE_TAG, BLACK_TYPE_TAG,
+    WHITE_NA_TAG, BLACK_NA_TAG,
+    ECO_TAG, NIC_TAG, OPENING_TAG, VARIATION_TAG, SUB_VARIATION_TAG, 
+    LONG_ECO_TAG,
+    TIME_CONTROL_TAG,
+    ANNOTATOR_TAG,
+    EVENT_DATE_TAG, EVENT_SPONSOR_TAG, SECTION_TAG, STAGE_TAG, BOARD_TAG,
+    TIME_TAG, UTC_DATE_TAG, UTC_TIME_TAG,
+    SETUP_TAG,
+    FEN_TAG,
+    TERMINATION_TAG, MODE_TAG, PLY_COUNT_TAG,
+#endif
+    /* The final value should be negative. */
+    -1
+};
+
+        /* Provision for a user-defined tag ordering.
+         * See add_to_output_tag_order().
+         * Once allocated, the end of the list must be negative.
+         */
+static int *TagOrder = NULL;
+static int tag_order_space = 0;
+
+void
+set_output_line_length(unsigned length)
+{
+    if(output_line != NULL) {
+        (void) free((void *) output_line);
+    }
+    output_line = (char *) MallocOrDie(length + 1);
+    GlobalState.max_line_length = length;
+}
+
+    /* Which output format does the user require, based upon the
+     * given command line argument?
+     */
+OutputFormat
+which_output_format(const char *arg)
+{   int i;
+    struct {
+        const char *arg;
+        OutputFormat format;
+    } formats[] = {
+        { "san", SAN },
+        { "SAN", SAN },
+        { "epd", EPD },
+        { "EPD", EPD },
+        { "lalg", LALG },
+        { "halg", HALG },
+        { "CM", CM },
+        { "LALG", LALG },
+        { "HALG", HALG },
+        { "ELALG", ELALG },
+        { "elalg", ELALG },
+        { "uci", UCI },
+        { "cm", CM },
+        { "", SOURCE },
+        /* Add others before the terminating NULL. */
+        { (const char *) NULL, SAN }
+    };
+
+    for(i = 0; formats[i].arg != NULL; i++){
+      const char *format_prefix = formats[i].arg;
+      const size_t format_prefix_len = strlen(format_prefix);
+      if(strncmp(arg,format_prefix,format_prefix_len) == 0){
+            OutputFormat format = formats[i].format;
+            /* Sanity check. */
+            if(*format_prefix == '\0' && *arg != '\0') {
+                fprintf(GlobalState.logfile,
+                        "Unknown output format %s.\n", arg);
+                exit(1);
+            }
+            /* If the format is SAN, it is possible to supply
+             * a 6-piece suffix listing language-specific
+             * letters to use in the output.
+             */
+            if((format == SAN || format == ELALG) &&
+                   (strlen(arg) > format_prefix_len)){
+                set_output_piece_characters(&arg[format_prefix_len]);
+            }
+            return format;
+      }
+  }
+  fprintf(GlobalState.logfile,"Unknown output format %s.\n",arg);
+  return SAN;
+}
+
+        /* Which file suffix should be used for this output format. */
+const char *
+output_file_suffix(OutputFormat format)
+{
+    /* Define a suffix for the output files. */
+    static const char PGN_suffix[] = ".pgn";
+    static const char EPD_suffix[] = ".epd";
+    static const char CM_suffix[] = ".cm";
+
+    switch(format){
+        case SOURCE:
+        case SAN:
+        case LALG:
+        case HALG:
+        case ELALG:
+            return PGN_suffix;
+        case EPD:
+            return EPD_suffix;
+        case CM:
+            return CM_suffix;
+        default:
+            return PGN_suffix;
+    }
+}
+
+static const char *
+select_tag_string(TagName tag)
+{   const char *tag_string;
+
+    if((tag == PSEUDO_PLAYER_TAG) || (tag == PSEUDO_ELO_TAG) || (tag == PSEUDO_FEN_PATTERN_TAG)){
+        tag_string = NULL;
+    }
+    else{
+        tag_string = tag_header_string(tag);
+    }
+    return tag_string;
+}
+
+static Boolean
+is_STR(TagName tag)
+{
+    switch(tag){
+        case EVENT_TAG:
+        case SITE_TAG:
+        case DATE_TAG:
+        case ROUND_TAG:
+        case WHITE_TAG:
+        case BLACK_TAG:
+        case RESULT_TAG:
+            return TRUE;
+        default:
+            return FALSE;
+    }
+}
+
+        /* Output the tags held in the Tags structure.
+         * At least the full Seven Tag Roster is printed.
+         */
+static void
+output_tag(TagName tag, char **Tags, FILE *outfp)
+{   const char *tag_string;
+
+    /* Must print STR elements and other non-NULL tags. */
+    if((is_STR(tag)) || (Tags[tag] != NULL)){
+        tag_string = select_tag_string(tag);
+
+        if(tag_string != NULL){
+            fprintf(outfp,"[%s \"",tag_string);
+            if(Tags[tag] != NULL){
+                fwrite(Tags[tag],sizeof(char),strlen(Tags[tag]),outfp);
+            }
+            else{
+                if(tag == DATE_TAG){
+                    fprintf(outfp,"????.??.??");
+                }
+                else{
+                    fprintf(outfp,"?");
+                }
+            }
+            fprintf(outfp,"\"]\n");
+        }
+    }
+}
+
+        /* Output the Seven Tag Roster. */
+static void
+output_STR(FILE *outfp,char **Tags)
+{   unsigned tag_index;
+
+    /* Use the default ordering to ensure that STR is output
+     * in the way it should be.
+     */
+    for(tag_index = 0; tag_index < 7; tag_index++){
+        output_tag(DefaultTagOrder[tag_index],Tags,outfp);
+    }
+}
+
+        /* Print out on outfp the current details.
+         * These can be used in the case of an error.
+         */
+static void
+show_tags(FILE *outfp,char **Tags,int tags_length)
+{   int tag_index;
+    /* Take a copy of the Tags data, so that we can keep
+     * track of what has been printed. This will make
+     * it possible to print tags that were identified
+     * in the source but are not defined with _TAG values.
+     * See lex.c for how these extra tags are handled.
+     */
+    char **copy_of_tags =
+            (char **) MallocOrDie(tags_length*sizeof(*copy_of_tags));
+    int i;
+    for(i = 0; i < tags_length; i++){
+        copy_of_tags[i] = Tags[i];
+    }
+
+    /* Ensure that a tag ordering is available. */
+    if(TagOrder == NULL){
+        /* None set by the user - use the default. */
+        /* Handle the standard tags.
+         * The end of the list is marked with a negative value.
+         */
+        for(tag_index = 0; DefaultTagOrder[tag_index] >= 0; tag_index++){
+            TagName tag = DefaultTagOrder[tag_index];
+            output_tag(tag,copy_of_tags,outfp);
+            copy_of_tags[tag] = (char *)NULL;
+        }
+        /* Handle the extra tags. */
+        for(tag_index = 0; tag_index < tags_length; tag_index++){
+            if(copy_of_tags[tag_index] != NULL){
+                output_tag(tag_index,copy_of_tags,outfp);
+            }
+        }
+    }
+    else{
+        for(tag_index = 0; TagOrder[tag_index] >= 0; tag_index++){
+            TagName tag = TagOrder[tag_index];
+            output_tag(tag,copy_of_tags,outfp);
+            copy_of_tags[tag] = (char *)NULL;
+        }
+    }
+    (void) free(copy_of_tags);
+    putc('\n',outfp);
+}
+
+        /* Ensure that there is room for len more characters on the
+         * current line.
+         */
+static void
+check_line_length(FILE *fp,size_t len)
+{
+    if((line_length + len) > GlobalState.max_line_length){
+        terminate_line(fp);
+    }
+}
+
+        /* Print ch to fp and update how much of the line
+         * has been printed on.
+         */
+static void
+single_char(FILE *fp, char ch)
+{
+    check_line_length(fp,1);
+    output_line[line_length] = ch;
+    line_length++;
+}
+
+        /* Print a space, unless at the beginning of a line. */
+static void
+print_separator(FILE *fp)
+{
+    /* Lines shouldn't have trailing spaces, so ensure that there
+     * will be room for at least one more character after the space.
+     */
+    check_line_length(fp,2);
+    if(line_length != 0){
+        output_line[line_length] = ' ';
+        line_length++;
+    }
+}
+
+        /* Ensure that what comes next starts on a fresh line. */
+void
+terminate_line(FILE *fp)
+{
+    /* Delete any trailing space(s). */
+    while(line_length >= 1 && output_line[line_length - 1] == ' ') {
+        line_length--;
+    }
+    if(line_length > 0) {
+        output_line[line_length] = '\0';
+        fprintf(fp, "%s\n", output_line);
+        line_length = 0;
+    }
+}
+
+        /* Print str to fp and update how much of the line
+         * has been printed on.
+         */
+void
+print_str(FILE *fp, const char *str)
+{   size_t len = strlen(str);
+
+    check_line_length(fp,len);
+    if(len > GlobalState.max_line_length) {
+        fprintf(GlobalState.logfile, "String length %lu is too long for the line length of %lu:\n",
+               (unsigned long) len,
+               (unsigned long) GlobalState.max_line_length);
+        fprintf(GlobalState.logfile, "%s\n", str);
+       report_details(GlobalState.logfile);
+       fprintf(fp, "%s\n", str);
+    }
+    else {
+       sprintf(&(output_line[line_length]),"%s",str);
+       line_length += len;
+    }
+}
+
+static void
+print_comment_list(FILE *fp, CommentList *comment_list)
+{   CommentList *next_comment;
+
+    for(next_comment = comment_list ; next_comment != NULL;
+                next_comment = next_comment->next){
+        StringList *comment = next_comment->Comment;
+
+        if(comment != NULL){
+            /* We will use strtok to break up the comment string,
+             * with chunk to point to each bit in turn.
+             */
+            char *chunk;
+            
+            single_char(fp,'{');
+            for( ; comment != NULL; comment = comment->next){
+               /* Make a copy because the string is altered. */
+               char *str = copy_string(comment->str);
+                chunk = strtok(str," ");
+                while(chunk != NULL){
+                    print_separator(fp);
+                    print_str(fp,chunk);
+                    chunk = strtok((char *)NULL," ");
+                }
+               (void) free((void *) str);
+            }
+            print_separator(fp);
+            single_char(fp,'}');
+            if(next_comment->next != NULL){
+                print_separator(fp);
+            }
+        }
+    }
+}
+
+static void
+print_move_list(FILE *outputfile, unsigned move_number, Boolean white_to_move,
+                const Move *move_details,const Board *final_board)
+{   unsigned print_move_number = 1;
+    const Move *move = move_details;
+    Boolean keepPrinting;
+    int plies;
+
+    /* Work out the ply depth. */
+    plies = 2*(move_number) - 1;
+    if(!white_to_move) {
+        plies++;
+    }
+    if(GlobalState.output_ply_limit >= 0 &&
+            plies > GlobalState.output_ply_limit) {
+        keepPrinting = FALSE;
+    }
+    else {
+        keepPrinting = TRUE;
+    }
+
+    while(move != NULL && keepPrinting){
+        /* Reset print_move number if a variation was printed. */
+        print_move_number = print_move(outputfile,move_number,
+                                       print_move_number,
+                                       white_to_move,move);
+
+        /* See if there is a result attached.  This may be attached either
+         * to a move or a comment.
+         */
+        if(!GlobalState.check_only && (move != NULL) &&
+                                (move->terminating_result != NULL)){
+            if(GlobalState.output_FEN_string && final_board != NULL){
+                print_separator(outputfile);
+                print_str(outputfile,build_FEN_comment(final_board));
+            }
+            if(GlobalState.keep_results) {
+                print_separator(outputfile);
+                print_str(outputfile,move->terminating_result);
+            }
+        }
+        if(move->move[0] != '\0'){
+            /* A genuine move was just printed, rather than a comment. */
+            if(white_to_move){
+              white_to_move = FALSE;
+            }
+            else{
+               move_number++;
+               white_to_move = TRUE;
+            }
+            plies++;
+            if(GlobalState.output_ply_limit >= 0 &&
+                    plies > GlobalState.output_ply_limit) {
+                keepPrinting = FALSE;
+            }
+        }
+        move = move->next;
+        /* The following is slightly inaccurate.
+         * If the previous value of move was a comment and
+         * we aren't printing comments, then this results in two
+         * separators being printed after the move preceding the comment.
+         * Not sure how to cleanly fix it, because there might have
+         * been nags attached to the comment that were printed, for instance!
+         */
+        if(move != NULL && keepPrinting){
+            print_separator(outputfile);
+        }
+    }
+
+    if(move != NULL && !keepPrinting) {
+        /* We ended printing the game prematurely. */
+
+       /*
+         * Decide whether to print a result indicator.
+         */
+        if(GlobalState.keep_results) {
+            /* Find the final move to see if there was a result there. */
+            while(move->next != NULL) {
+                move = move->next;
+            }
+            if(move->terminating_result != NULL) {
+                print_separator(outputfile);
+                print_str(outputfile, "*");
+            }
+        }
+    }
+}
+
+        /* Output the current move along with associated information.
+         * Return TRUE if either a variation or comment was printed,
+         * FALSE otherwise.
+         * This is needed to determine whether a new move number
+         * is to be printed after a variation.
+         */
+static Boolean
+print_move(FILE *outputfile, unsigned move_number, unsigned print_move_number,
+                Boolean white_to_move, const Move *move_details)
+{   Boolean something_printed = FALSE;
+
+    if(move_details == NULL){
+        /* Shouldn't happen. */
+        fprintf(GlobalState.logfile,
+                "Internal error: NULL move in print_move.\n");
+        report_details(GlobalState.logfile);
+    }
+    else{
+        if(GlobalState.check_only){
+            /* Nothing to be output. */
+        }
+        else{
+            StringList *nags = move_details->Nags;
+            Variation *variants = move_details->Variants;
+            const unsigned char *move_text = move_details->move;
+
+            if(*move_text != '\0'){
+                if(GlobalState.keep_move_numbers &&
+                        (white_to_move || print_move_number)){
+                    static char small_number[] = "99999...";
+
+                    /* @@@ Should 1... be written as 1. ... ? */
+                    sprintf(small_number,"%u.%s",move_number, white_to_move?"":"..");
+                    print_str(outputfile,small_number);
+                    print_separator(outputfile);
+                }
+                switch(GlobalState.output_format){
+                    case SAN:
+                    case SOURCE:
+                        /* @@@ move_text should be handled as unsigned
+                         * char text, as the source may be 8-bit rather
+                         * than 7-bit.
+                         */
+                       if(GlobalState.keep_checks) {
+                           print_str(outputfile, (const char *) move_text);
+                       }
+                       else {
+                           /* Look for a check or mate symbol. */
+                           char *check = strchr((const char *) move_text, '+');
+                           if(check == NULL) {
+                               check = strchr((const char *) move_text, '#');
+                           }
+                           if(check != NULL) {
+                               /* We need to drop it from move_text. */
+                               int len = check - ((char *) move_text);
+                               char *just_move = (char *) MallocOrDie(len + 1);
+                               strncpy(just_move, (const char *) move_text, len);
+                               just_move[len] = '\0';
+                               print_str(outputfile, just_move);
+                               (void) free(just_move);
+                           }
+                           else {
+                               print_str(outputfile, (const char *) move_text);
+                           }
+                       }
+                        break;
+                    case HALG:
+                        {  char algebraic[MAX_MOVE_LEN+1];
+
+                           *algebraic = '\0';
+                           switch(move_details->class){
+                               case PAWN_MOVE:
+                               case ENPASSANT_PAWN_MOVE:
+                               case KINGSIDE_CASTLE:
+                               case QUEENSIDE_CASTLE:
+                               case PIECE_MOVE:
+                                   sprintf(algebraic,"%c%c-%c%c",
+                                       move_details->from_col,
+                                       move_details->from_rank,
+                                       move_details->to_col,
+                                       move_details->to_rank);
+                                   break;
+                               case PAWN_MOVE_WITH_PROMOTION:
+                                   sprintf(algebraic,"%c%c-%c%c%c",
+                                       move_details->from_col,
+                                       move_details->from_rank,
+                                       move_details->to_col,
+                                       move_details->to_rank,
+                                       promoted_piece_letter(move_details->promoted_piece));
+                                   break;
+                              case NULL_MOVE:
+                                  strcpy(algebraic, NULL_MOVE_STRING);
+                                  break;
+                               case UNKNOWN_MOVE:
+                                   strcpy(algebraic,"???");
+                                   break;
+                           }
+                           if(GlobalState.keep_checks) {
+                               switch(move_details->check_status){
+                                   case NOCHECK:
+                                     break;
+                                   case CHECK:
+                                     strcat(algebraic,"+");
+                                     break;
+                                   case CHECKMATE:
+                                     strcat(algebraic,"#");
+                                     break;
+                               }
+                           }
+                           print_str(outputfile,algebraic);
+                        }
+                        break;
+                    case LALG:
+                    case ELALG:
+                        {  char algebraic[MAX_MOVE_LEN+1];
+                           size_t ind = 0;
+
+                           /* Prefix with a piece name if ELALG. */
+                           if(GlobalState.output_format == ELALG &&
+                                        move_details->class == PIECE_MOVE){
+                               strcpy(algebraic,
+                                      piece_str(move_details->piece_to_move));
+                               ind = strlen(algebraic);
+                           }
+                           /* Format the basics. */
+                          if(move_details->class != NULL_MOVE) {
+                              sprintf(&algebraic[ind],"%c%c%c%c",
+                                          move_details->from_col,
+                                          move_details->from_rank,
+                                          move_details->to_col,
+                                          move_details->to_rank);
+                              ind += 4;
+                          }
+                          else {
+                              strcpy(algebraic, NULL_MOVE_STRING);
+                              ind += strlen(NULL_MOVE_STRING);
+                          }
+                           switch(move_details->class){
+                               case PAWN_MOVE:
+                               case KINGSIDE_CASTLE:
+                               case QUEENSIDE_CASTLE:
+                               case PIECE_MOVE:
+                              case NULL_MOVE:
+                                   /* Nothing more to do at this stage. */
+                                   break;
+                               case ENPASSANT_PAWN_MOVE:
+                                   if(GlobalState.output_format == ELALG){
+                                       strcat(algebraic,"ep");
+                                       ind += 2;
+                                   }
+                                   break;
+                               case PAWN_MOVE_WITH_PROMOTION:
+                                   sprintf(&algebraic[ind],"%s",
+                                           piece_str(move_details->promoted_piece));
+                                   ind = strlen(algebraic);
+                                   break;
+                               case UNKNOWN_MOVE:
+                                   strcpy(algebraic,"???");
+                                   ind += 3;
+                                   break;
+                           }
+                           if(GlobalState.keep_checks) {
+                               switch(move_details->check_status){
+                                   case NOCHECK:
+                                     break;
+                                   case CHECK:
+                                       strcat(algebraic,"+");
+                                       ind++;
+                                       break;
+                                   case CHECKMATE:
+                                       strcat(algebraic,"#");
+                                       ind++;
+                                       break;
+                               }
+                           }
+                           print_str(outputfile,algebraic);
+                        }
+                        break;
+                    default:
+                        fprintf(GlobalState.logfile,
+                                "Unknown output format %d in print_move()\n",
+                                GlobalState.output_format);
+                                exit(1);
+                        break;
+                }
+            }
+            else{
+                /* An empty move. */
+                fprintf(GlobalState.logfile,
+                                "Internal error: Empty move in print_move.\n");
+                report_details(GlobalState.logfile);
+            }
+            /* Print further information, that may be attached to moves
+             * and comments.
+             */
+            if(GlobalState.keep_NAGs){
+                while(nags != NULL){
+                    print_separator(outputfile);
+                    print_str(outputfile,nags->str);
+                    nags = nags->next;
+                }
+                /* We don't need to output move numbers after just
+                 * NAGs, so don't set something_printed.
+                 */
+            }
+            if(GlobalState.keep_comments){
+                if(move_details->Comment != NULL){
+                    print_separator(outputfile);
+                    print_comment_list(outputfile,move_details->Comment);
+                    something_printed = TRUE;
+                }
+            }
+            if((GlobalState.keep_variations) && (variants != NULL)){
+                while(variants != NULL){
+                    print_separator(outputfile);
+                    single_char(outputfile,'(');
+                    if(GlobalState.keep_comments &&
+                            (variants->prefix_comment != NULL)){
+                        print_comment_list(outputfile,variants->prefix_comment);
+                        print_separator(outputfile);
+                    }
+                    /* Always start with a move number.
+                     * The final board position is not needed.
+                     */
+                    print_move_list(outputfile,move_number,
+                                    white_to_move,variants->moves,
+                                    (const Board *)NULL);
+                    single_char(outputfile,')');
+                    if(GlobalState.keep_comments &&
+                            (variants->suffix_comment != NULL)){
+                        print_separator(outputfile);
+                        print_comment_list(outputfile,variants->suffix_comment);
+                    }
+                    variants = variants->next;
+                }
+                something_printed = TRUE;
+            }
+        }
+    }
+    return something_printed;
+}
+
+        /* Return the letter associated with the given piece. */
+static char
+promoted_piece_letter(Piece piece)
+{
+    switch(piece){
+        case QUEEN:
+            return 'Q';
+        case ROOK:
+            return 'R';
+        case BISHOP:
+            return 'B';
+        case KNIGHT:
+            return 'N';
+        default:
+            return '?';
+    }
+}
+
+        /* Output a comment in CM format. */
+static void
+output_cm_comment(CommentList *comment,FILE *outputfile,unsigned indent)
+{   /* Don't indent for the first comment line, because
+     * we should already be positioned at the correct spot.
+     */
+    unsigned indent_for_this_line = 0;
+
+    putc(CM_COMMENT_CHAR,outputfile);
+    line_length++;
+    while(comment != NULL){
+        /* We will use strtok to break up the comment string,
+         * with chunk to point to each bit in turn.
+         */
+        char *chunk;
+        StringList *comment_str = comment->Comment;
+        
+        for( ; comment_str != NULL; comment_str = comment_str->next){
+           char *str = copy_string(comment_str->str);
+            chunk = strtok(str," ");
+            while(chunk != NULL){
+                size_t len = strlen(chunk);
+
+                if((line_length+1+len) > GlobalState.max_line_length){
+                    /* Start a new line. */
+                    indent_for_this_line = indent;
+                    fprintf(outputfile,"\n%*s%c ",indent_for_this_line,"",
+                                        CM_COMMENT_CHAR);
+                    line_length = indent_for_this_line+2;
+                }
+                else{
+                    putc(' ',outputfile);
+                    line_length++;
+                }
+                fprintf(outputfile,"%s",chunk);
+                line_length += len;
+                chunk = strtok((char *)NULL," ");
+            }
+           (void) free((void *) str);
+        }
+        comment = comment->next;
+    }
+    putc('\n',outputfile);
+    line_length = 0;
+}
+
+static void
+output_cm_result(const char *result,FILE *outputfile)
+{
+    fprintf(outputfile,"%c ",CM_COMMENT_CHAR);
+    if(strcmp(result,"1-0") == 0){
+      fprintf(outputfile,"and black resigns");
+    }
+    else if(strcmp(result,"0-1") == 0){
+      fprintf(outputfile,"and white resigns");
+    }
+    else if(strncmp(result,"1/2",3) == 0){
+      fprintf(outputfile,"draw");
+    }
+    else{
+      fprintf(outputfile,"incomplete result");
+    }
+}
+
+
+        /* Output the game in Chess Master format. */
+static void
+output_cm_game(FILE *outputfile,unsigned move_number,
+                Boolean white_to_move,const Game game)
+{   const Move *move = game.moves;
+
+    if((move_number != 1) || (!white_to_move)){
+        fprintf(GlobalState.logfile,
+            "Unable to output CM games other than from the starting position.\n");
+        report_details(GlobalState.logfile);
+    }
+    fprintf(outputfile,"WHITE: %s\n",
+                game.tags[WHITE_TAG] != NULL? game.tags[WHITE_TAG] : "");
+    fprintf(outputfile,"BLACK: %s\n",
+                game.tags[BLACK_TAG] != NULL? game.tags[BLACK_TAG] : "");
+    putc('\n',outputfile);
+
+    if(game.prefix_comment != NULL){
+        line_length = 0;
+        output_cm_comment(game.prefix_comment,outputfile,0);
+    }
+    while(move != NULL){
+        if(move->move[0] != '\0'){
+            /* A genuine move. */
+            if(white_to_move){
+                fprintf(outputfile,"%*u. ",MOVE_NUMBER_WIDTH,move_number);
+                fprintf(outputfile,"%*s",-MOVE_WIDTH,move->move);
+                white_to_move = FALSE;
+            }
+            else{
+                fprintf(outputfile,"%*s",-MOVE_WIDTH,move->move);
+                move_number++;
+                white_to_move = TRUE;
+            }
+        }
+        if((move->Comment != NULL) && GlobalState.keep_comments){
+            const char *result = move->terminating_result;
+
+            if(!white_to_move){
+                fprintf(outputfile,"%*s",-MOVE_WIDTH,"...");
+            }
+            line_length = COMMENT_INDENT;
+            output_cm_comment(move->Comment,outputfile,COMMENT_INDENT);
+            if((result != NULL) && (move->check_status != CHECKMATE)){
+                /* Give some information on the nature of the finish. */
+                if(white_to_move){
+                    fprintf(outputfile,"%*s",COMMENT_INDENT,"");
+                }
+                else{
+                    /* Print out a string representing the result. */
+                    fprintf(outputfile,"%*s %*s%*s",
+                                    MOVE_NUMBER_WIDTH+1,"",-MOVE_WIDTH,"...",
+                                    MOVE_WIDTH,"");
+                }
+                output_cm_result(result,outputfile);
+                putc('\n',outputfile);
+            }
+            else{
+                if(!white_to_move){
+                    /* Indicate that the next move is Black's. */
+                    fprintf(outputfile,"%*s %*s",
+                                MOVE_NUMBER_WIDTH+1,"",-MOVE_WIDTH,"...");
+                }
+            }
+        }
+        else{
+            if((move->terminating_result != NULL) &&
+                        (move->check_status != CHECKMATE)){
+                /* Give some information on the nature of the finish. */
+                const char *result = move->terminating_result;
+
+                if(!white_to_move){
+                    fprintf(outputfile,"%*s",-MOVE_WIDTH,"...");
+                }
+                output_cm_result(result,outputfile);
+                if(!white_to_move){
+                    putc('\n',outputfile);
+                    fprintf(outputfile,"%*s %*s",
+                                    MOVE_NUMBER_WIDTH+1,"",-MOVE_WIDTH,"...");
+                }
+                putc('\n',outputfile);
+            }
+            else{
+                if(white_to_move){
+                    /* Terminate the move pair. */
+                    putc('\n',outputfile);
+                }
+            }
+        }
+        move = move->next;
+    }
+    putc('\n',outputfile);
+}
+
+        /* Output the current game according to the required output format. */
+void
+output_game(Game current_game,FILE *outputfile)
+{   Boolean white_to_move = TRUE;
+    unsigned move_number = 1;
+    /* The final board position, if available. */
+    Board *final_board = NULL;
+
+    /* If we aren't starting from the initial setup, then we
+     * need to know the current move number and whose
+     * move it is.
+     */
+    if(current_game.tags[FEN_TAG] != NULL){
+        Board *board = new_fen_board(current_game.tags[FEN_TAG]);
+
+        if(board != NULL){
+            move_number = board->move_number;
+            white_to_move = board->to_move == WHITE;
+            (void) free((void *)board);
+        }
+    }
+
+    /* Start at the beginning of a line. */
+    line_length = 0;
+    /* See if the moves should be rewritten into
+     * standard form.
+     */
+    if(GlobalState.output_format != SOURCE){
+        /* Rewrite the moves of the game into
+         * SAN (Standard Algebraic Notation).
+         */
+        final_board = rewrite_game(&current_game);
+    }
+    if(final_board != NULL) {
+       if(GlobalState.output_total_plycount) {
+           add_total_plycount(&current_game, GlobalState.keep_variations);
+       }
+       if(GlobalState.add_hashcode_tag || current_game.tags[HASHCODE_TAG] != NULL) {
+           add_hashcode_tag(&current_game);
+       }
+       switch(GlobalState.output_format){
+           case SAN:
+           case SOURCE:
+           case LALG:
+           case HALG:
+           case ELALG:
+               print_algebraic_game(current_game,outputfile,move_number,white_to_move,
+                                    final_board);
+               break;
+           case EPD:
+               print_epd_game(current_game,outputfile,move_number,white_to_move,
+                              final_board);
+               break;
+           case CM:
+               output_cm_game(outputfile,move_number,white_to_move,current_game);
+               break;
+           default:
+               fprintf(GlobalState.logfile,
+                           "Internal error: unknown output type %d in output_game().\n",
+                           GlobalState.output_format);
+               break;
+       }
+       fflush(outputfile);
+        (void) free((void *) final_board);
+    }
+}
+
+        /* Add the given tag to the output ordering. */
+void
+add_to_output_tag_order(TagName tag)
+{   int tag_index;
+
+    if(TagOrder == NULL){
+        tag_order_space = ARRAY_SIZE(DefaultTagOrder);
+        TagOrder = (int *) MallocOrDie(tag_order_space*sizeof(*TagOrder));
+        /* Always ensure that there is a negative value at the end. */
+        TagOrder[0] = -1;
+    }
+    /* Check to ensure a position has not already been indicated
+     * for this tag.
+     */
+    for(tag_index = 0; (TagOrder[tag_index] != -1) && 
+                       (TagOrder[tag_index] != (int) tag); tag_index++){
+    }
+
+    if(TagOrder[tag_index] == -1){
+        /* Make sure there is enough space for another. */
+        if(tag_index >= tag_order_space){
+            /* Allocate some more. */
+            tag_order_space += 10;
+            TagOrder = (int *) ReallocOrDie((void *)TagOrder,
+                                            tag_order_space*sizeof(*TagOrder));
+        }
+        TagOrder[tag_index] = tag;
+        TagOrder[tag_index+1] = -1;
+    }
+    else{
+        fprintf(GlobalState.logfile,"Duplicate position for tag: %s\n",
+                select_tag_string(tag));
+    }
+}
+
+static const char *format_epd_game_comment(char **Tags)
+{   
+    static char comment_prefix[] = "c0 ";
+    static char player_separator[] = "-";
+    static size_t prefix_and_separator_len =
+                sizeof(comment_prefix)+sizeof(player_separator);
+    size_t space_needed = prefix_and_separator_len;
+    char *comment;
+
+    if(Tags[WHITE_TAG] != NULL){
+      space_needed += strlen(Tags[WHITE_TAG]);
+    }
+    if(Tags[BLACK_TAG] != NULL){
+      space_needed += strlen(Tags[BLACK_TAG]);
+    }
+    /* Allow a space character before each of the remaining tags. */
+    if(Tags[EVENT_TAG] != NULL){
+      space_needed += 1+strlen(Tags[EVENT_TAG]);
+    }
+    if(Tags[SITE_TAG] != NULL){
+      space_needed += 1+strlen(Tags[SITE_TAG]);
+    }
+    if(Tags[DATE_TAG] != NULL){
+      space_needed += 1+strlen(Tags[DATE_TAG]);
+    }
+    /* Allow for a terminating semicolon. */
+    space_needed++;
+
+    comment = (char *) MallocOrDie(space_needed+1);
+
+    strcpy(comment,comment_prefix);
+    if(Tags[WHITE_TAG] != NULL){
+      strcat(comment,Tags[WHITE_TAG]);
+    }
+    strcat(comment,player_separator);
+    if(Tags[BLACK_TAG] != NULL){
+      strcat(comment,Tags[BLACK_TAG]);
+    }
+    if(Tags[EVENT_TAG] != NULL){
+      strcat(comment," ");
+      strcat(comment,Tags[EVENT_TAG]);
+    }
+    if(Tags[SITE_TAG] != NULL){
+      strcat(comment," ");
+      strcat(comment,Tags[SITE_TAG]);
+    }
+    if(Tags[DATE_TAG] != NULL){
+      strcat(comment," ");
+      strcat(comment,Tags[DATE_TAG]);
+    }
+    strcat(comment,";");
+    if(strlen(comment) >= space_needed){
+        fprintf(GlobalState.logfile,
+                "Internal error: overflow in format_epd_game_comment\n");
+    }
+    return comment;
+}
+
+static void
+print_algebraic_game(Game current_game,FILE *outputfile,
+                     unsigned move_number,Boolean white_to_move,
+                     Board *final_board)
+{
+    /* Report details on the output. */
+    if(GlobalState.tag_output_format == ALL_TAGS) {
+      show_tags(outputfile,current_game.tags,current_game.tags_length);
+    }
+    else if(GlobalState.tag_output_format == SEVEN_TAG_ROSTER){
+      output_STR(outputfile,current_game.tags);
+      if(GlobalState.add_ECO && !GlobalState.parsing_ECO_file){
+                  /* If ECO classification has been requested, then assume
+                   * that ECO tags are also required.
+                   */
+                  output_tag(ECO_TAG,current_game.tags,outputfile);
+                  output_tag(OPENING_TAG,current_game.tags,outputfile);
+                  output_tag(VARIATION_TAG,current_game.tags,outputfile);
+                  output_tag(SUB_VARIATION_TAG,current_game.tags,outputfile);
+      }
+
+      /* Output any FEN that there might be. */
+      output_tag(FEN_TAG,current_game.tags,outputfile);
+      putc('\n',outputfile);
+    }
+    else if(GlobalState.tag_output_format == NO_TAGS) {
+    }
+    else {
+        fprintf(GlobalState.logfile,
+                "Unknown output form for tags: %d\n",
+                GlobalState.tag_output_format);
+        exit(1);
+    }
+    if((GlobalState.keep_comments) &&
+                    (current_game.prefix_comment != NULL)){
+      print_comment_list(outputfile,
+                         current_game.prefix_comment);
+      terminate_line(outputfile);
+      putc('\n',outputfile);
+    }
+    print_move_list(outputfile,move_number,white_to_move,
+                    current_game.moves,final_board);
+    /* Take account of a possible zero move game. */
+    if(current_game.moves == NULL) {
+        if(current_game.tags[RESULT_TAG] != NULL) {
+            print_str(outputfile,current_game.tags[RESULT_TAG]);
+        }
+        else{
+            fprintf(GlobalState.logfile,
+                    "Internal error: Zero move game with no result\n");
+        }
+    }
+    terminate_line(outputfile);
+    putc('\n',outputfile);
+}
+
+static void
+print_epd_move_list(Game current_game,FILE *outputfile,
+                    unsigned move_number, Boolean white_to_move,
+                    Board *final_board)
+{   const Move *move = current_game.moves;
+    const char *game_comment = format_epd_game_comment(current_game.tags);
+    static char epd[FEN_SPACE];
+
+    while(move != NULL){
+        if(move->epd != NULL){
+            fprintf(outputfile,"%s",move->epd);
+        }
+        else{
+            fprintf(GlobalState.logfile,"Internal error: Missing EPD\n");
+        }
+        fprintf(outputfile," %s",game_comment);
+        putc('\n',outputfile);
+        move = move->next;
+    }
+    if(final_board != NULL) {
+        build_basic_EPD_string(final_board,epd);
+        fprintf(outputfile,"%s %s",epd,game_comment);
+        putc('\n',outputfile);
+    }
+    (void) free((void *)game_comment);
+}
+
+static void
+print_epd_game(Game current_game,FILE *outputfile,
+               unsigned move_number,Boolean white_to_move,
+               Board *final_board)
+{
+    if(!GlobalState.check_only){
+        print_epd_move_list(current_game,outputfile,move_number,white_to_move,
+                            final_board);
+        putc('\n',outputfile);
+    }
+}
+
+/*
+ * Build a comment containing a FEN representation of the board.
+ * NB: This function re-uses static space each time it is called
+ * so a later call will overwrite an earlier call.
+ */
+static const char *
+build_FEN_comment(const Board *board)
+{
+    static char fen[FEN_SPACE];
+    strcpy(fen,"{ \"");
+    build_FEN_string(board,&fen[strlen(fen)]);
+    strcat(fen,"\" }");
+    /* A belated sanity check. */
+    if(strlen(fen) >= FEN_SPACE){
+        fprintf(GlobalState.logfile,
+                "Internal error: string overflow in build_FEN_comment.\n");
+    }
+    return fen;
+}
+
+/*
+ * Count how many ply recorded for the given move.
+ * Include variations if count_variations.
+ */
+static unsigned count_single_move_ply(const Move *move_details, Boolean count_variations)
+{
+    unsigned count = 1;
+    if(count_variations) {
+       Variation *variant = move_details->Variants;
+       while(variant != NULL) {
+           count += count_move_list_ply(variant->moves, count_variations);
+           variant = variant->next;
+       }
+    }
+    return count;
+}
+
+/*
+ * Count how many plies in the game in total.
+ * Include variations if count_variations.
+ */
+static unsigned count_move_list_ply(Move *move_list, Boolean count_variations)
+{
+    unsigned count = 0;
+    while(move_list != NULL) {
+        count += count_single_move_ply(move_list, count_variations);
+       move_list = move_list->next;
+    }
+    return count;
+}
+
+/*
+ * Count how many plies in the game in total.
+ * Include variations if count_variations.
+ */
+static void add_total_plycount(const Game *game, Boolean count_variations)
+{
+    unsigned count = count_move_list_ply(game->moves, count_variations);
+    char formatted_count[20];
+    sprintf(formatted_count, "%u", count);
+
+    if(game->tags[TOTAL_PLY_COUNT_TAG] != NULL) {
+        (void) free(game->tags[TOTAL_PLY_COUNT_TAG]);
+    }
+    game->tags[TOTAL_PLY_COUNT_TAG] = copy_string(formatted_count);
+}
+
+/*
+ * Include a tag containing a hashcode for the game.
+ * Use the cumulative hash value.
+ */
+static void add_hashcode_tag(const Game *game)
+{
+    HashCode hashcode = game->cumulative_hash_value;
+    char formatted_code[20];
+    sprintf(formatted_code, "%08x", (unsigned) hashcode);
+
+    if(game->tags[HASHCODE_TAG] != NULL) {
+        (void) free(game->tags[HASHCODE_TAG]);
+    }
+    game->tags[HASHCODE_TAG] = copy_string(formatted_code);
+}
diff --git a/output.h b/output.h
new file mode 100644 (file)
index 0000000..1b66d1b
--- /dev/null
+++ b/output.h
@@ -0,0 +1,32 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+void output_game(Game current_game,FILE *outputfile);
+void print_str(FILE *fp, const char *str);
+void terminate_line(FILE *fp);
+OutputFormat which_output_format(const char *arg);
+const char *output_file_suffix(OutputFormat format);
+void add_to_output_tag_order(TagName tag);
+void set_output_line_length(unsigned max);
+
+/* Provide enough static space to build FEN string. */
+#define FEN_SPACE 100
diff --git a/pgn-extract.xml b/pgn-extract.xml
new file mode 100644 (file)
index 0000000..0751fb3
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<rss version="2.0">
+
+<channel>
+  <title>Home Page for pgn-extract</title>
+  <link>http://www.cs.kent.ac.uk/~djb/pgn-extract/</link>
+  <description>A Portable Game Notation (PGN) manipulator</description>
+
+  <item>
+    <title>Version 17-14 (.exe version)</title>
+    <link>http://www.cs.kent.ac.uk/~djb/pgn-extract/pgn-extract.exe</link>
+    <description>Version of the 32-bit Windows executable added that
+    does not require cygwin.
+    <guid isPermaLink="false">pgn-extract-17-14-non-cygwin</guid>
+    <pubDate>29 Jun 2013 11:55:00 GMT</pubDate>
+  </item>
+
+  <item>
+    <title>Version 17-14</title>
+    <link>http://www.cs.kent.ac.uk/~djb/pgn-extract/pgn-extract-17-14.tgz</link>
+    <description>C source code for version 17-14.
+    Version 17-14 adds null-move (--) recognition in variations, 
+    corrects an error in the whole-move number in FEN output, and
+    corrects a minor inconsistency in variation naming in eco.pgn.</description>
+    <guid isPermaLink="false">pgn-extract-17-14-announce</guid>
+    <pubDate>19 Jun 2013 11:30:00 GMT</pubDate>
+  </item>
+
+  <item>
+    <title>Version 17-13</title>
+    <link>http://www.cs.kent.ac.uk/~djb/pgn-extract/pgn-extract-17-13.tgz</link>
+    <description>C source code for version 17-13.
+    Version 17-13 adds -Wuci for output in a form suitable for use as input to a UCI-compatible engine, and --fuzzydepth for ply-specific duplicates matching.</description>
+    <guid isPermaLink="false">pgn-extract-17-13-announce</guid>
+    <pubDate>19 Apr 2013 11:15:00 GMT</pubDate>
+  </item>
+
+  <item>
+    <title>Version 17-12</title>
+    <link>http://www.cs.kent.ac.uk/~djb/pgn-extract/pgn-extract-17-12.tgz</link>
+    <description>C source code for version 17-12.
+    Version 17-12 is a minor bug fix for version 17-11.</description>
+    <guid isPermaLink="false">pgn-extract-17-12-announce</guid>
+    <pubDate>29 Mar 2013 15:05:00 GMT</pubDate>
+  </item>
+
+  <item>
+    <title>New in version 17-11</title>
+    <description>1) Fuzzy board matches via a regular-expression like syntax.
+    2) A test suite of the basic functionality.
+    </description>
+    <guid isPermaLink="false">pgn-extract-17-11-announce</guid>
+    <pubDate>9 Feb 2013 15:05:00 GMT</pubDate>
+  </item>
+</channel>
+
+</rss>
diff --git a/style.css b/style.css
new file mode 100755 (executable)
index 0000000..6c28f50
--- /dev/null
+++ b/style.css
@@ -0,0 +1,512 @@
+\r
+/*\r
+Design by Free CSS Templates\r
+http://www.freecsstemplates.org\r
+Released for free under a Creative Commons Attribution 2.5 License\r
+*/\r
+\r
+body {\r
+       margin: 0px 0px 0px 0px;\r
+       padding: 0;\r
+       background: #FFFFFF;\r
+       font-family: Arial, Helvetica, sans-serif;\r
+       font-size: 12px;\r
+}\r
+\r
+h1, h2, h3 {\r
+       margin: 0;\r
+       padding: 0;\r
+       font-weight: 200;\r
+       color: #222222;\r
+}\r
+\r
+h1 {\r
+       font-size: 3em;\r
+}\r
+h2 {\r
+       font-size: 2em;\r
+}\r
+h3 {\r
+       font-size: 1.5em;\r
+}\r
+\r
+p, ol, ul, pre, td {\r
+       margin-top: 0px;\r
+       padding: 0px;\r
+       color: #070707;\r
+       /* color: #000000; */\r
+}\r
+\r
+p, ol {\r
+       /* line-height: 180%; */\r
+}\r
+\r
+p {\r
+}\r
+\r
+ul, table {\r
+    margin-left: 20px;\r
+}\r
+\r
+li {\r
+    margin-left: 20px;\r
+}\r
+\r
+pre {\r
+    margin-left: 2em;\r
+    font-family: "Courier New", "Lucida Console", monospace;\r
+}\r
+\r
+strong {\r
+}\r
+\r
+a {\r
+       color: #5C5539;\r
+}\r
+\r
+a:hover {\r
+       text-decoration: none;\r
+}\r
+\r
+a img {\r
+       border: none;\r
+}\r
+\r
+img.border {\r
+}\r
+\r
+img.alignleft {\r
+       float: left;\r
+}\r
+\r
+img.alignright {\r
+       float: right;\r
+}\r
+\r
+img.aligncenter {\r
+       margin: 0px auto;\r
+}\r
+\r
+hr {\r
+       display: none;\r
+}\r
+\r
+/** WRAPPER */\r
+\r
+#wrapper {\r
+       overflow: hidden;\r
+       background: #FFFFFF;\r
+}\r
+\r
+.container {\r
+       /* width: 1200px; */\r
+       margin: 0px auto;\r
+}\r
+\r
+.clearfix {\r
+       clear: both;\r
+}\r
+\r
+/* Header */\r
+\r
+#header-wrapper {\r
+       overflow: hidden;\r
+       height: 150px;\r
+}\r
+\r
+#header {\r
+       /* width: 1200px; */\r
+       height: 150px;\r
+       margin: 0 auto;\r
+       padding: 0px 0px;\r
+}\r
+\r
+/* Logo */\r
+\r
+#logo {\r
+       float: left;\r
+       width: 310px;\r
+       height: 150px;\r
+       padding: 0px 0px 0px 40px;\r
+}\r
+\r
+#logo h1 {\r
+       padding: 50px 0px 0px 0px;\r
+       text-transform: lowercase;\r
+       letter-spacing: -2px;\r
+       font-size: 3.6em;\r
+}\r
+\r
+#logo h1 a {\r
+       text-decoration: none;\r
+       color: #FFFFFF;\r
+}\r
+\r
+\r
+/* Menu */\r
+\r
+#menu {\r
+       float: right;\r
+       width: 810px;\r
+       height: 80px;\r
+       padding: 20px 40px 0px 0px;\r
+}\r
+\r
+#menu ul {\r
+       float: right;\r
+       margin: 0;\r
+       padding: 40px 0px 0px 0px;\r
+       list-style: none;\r
+       line-height: normal;\r
+}\r
+\r
+#menu li {\r
+       float: left;\r
+}\r
+\r
+#menu a {\r
+       display: block;\r
+       margin-left: 1px;\r
+       padding: 7px 20px 7px 20px;\r
+       letter-spacing: 1px;\r
+       text-decoration: none;\r
+       text-align: center;\r
+       text-transform: uppercase;\r
+       font-family: 'Oswald', sans-serif;\r
+       font-size: 16px;\r
+       font-weight: 300;\r
+       color: #FFFFFF;\r
+}\r
+\r
+#menu a:hover, #menu .current_page_item a {\r
+       text-decoration: none;\r
+       background: #1B5902;\r
+       border-radius: 5px;\r
+       color: #FFFFFF;\r
+}\r
+\r
+/* Page */\r
+\r
+#page-wrapper {\r
+       overflow: hidden;\r
+}\r
+\r
+#page {\r
+       overflow: hidden;\r
+       /* width: 1120px; */\r
+       margin: 0px auto;\r
+       padding: 20px 40px;\r
+       color: #8F8F8F;\r
+       border-top: 3px solid #A1A1A1;\r
+}\r
+\r
+/** CONTENT */\r
+\r
+#wide-content {\r
+}\r
+\r
+#wide-content h2 {\r
+       padding: 0px 0px 20px 0px;\r
+       letter-spacing: -1px;\r
+       font-size: 36px;\r
+       color: #222222;\r
+}\r
+\r
+\r
+/** CONTENT */\r
+\r
+#content {\r
+       float: right;\r
+       width: 800px;\r
+       padding: 0px 0px 0px 0px;\r
+}\r
+\r
+#content h2 {\r
+       padding: 0px 0px 20px 0px;\r
+       letter-spacing: -1px;\r
+       font-size: 36px;\r
+       color: #222222;\r
+}\r
+\r
+#content .subtitle {\r
+       padding: 0px 0px 30px 0px;\r
+       text-transform: uppercase;\r
+       font-family: 'Oswald', sans-serif;\r
+       font-size: 18px;\r
+       color: #81AFC5;\r
+}\r
+\r
+/** SIDEBAR */\r
+\r
+#sidebar {\r
+       float: left;\r
+       width: 290px;\r
+       padding: 0px 0px 20px 0px;\r
+}\r
+\r
+#sidebar h2 {\r
+       padding: 0px 0px 30px 0px;\r
+       letter-spacing: -1px;\r
+       font-size: 2em;\r
+}\r
+\r
+/* Footer */\r
+\r
+#footer {\r
+       margin: 0 auto;\r
+}\r
+\r
+#footer p {\r
+       text-align: center;\r
+       font-size: 12px;\r
+       color: #757575;\r
+}\r
+\r
+#footer a {\r
+       color: #757575;\r
+}\r
+\r
+/* Three Column Footer Content */\r
+\r
+\r
+#footer-bg {\r
+       overflow: hidden;\r
+       padding: 40px 0px;\r
+       background:#E5E0DD url(images/main-bsg.png) repeat;\r
+}\r
+\r
+#footer-content {\r
+       color: #67C8E3;\r
+}\r
+\r
+#footer-content h2 {\r
+       margin: 0px;\r
+       padding: 0px 0px 30px 0px;\r
+       letter-spacing: -1px;\r
+       text-shadow: 1px 1px 0px #FFFFFF;\r
+       text-transform: uppercase;\r
+       font-size: 20px;\r
+       font-weight: 200;\r
+       color: #93776E;\r
+}\r
+\r
+#footer-content a {\r
+}\r
+\r
+#footer-content a:hover {\r
+       text-decoration: underline;\r
+}\r
+\r
+\r
+#column1 {\r
+       float: left;\r
+       width: 280px;\r
+       margin-right: 30px;\r
+}\r
+\r
+#column1 p {\r
+       line-height: 1;\r
+}\r
+\r
+#column2 {\r
+       float: left;\r
+       width: 280px;\r
+       margin-right: 30px;\r
+}\r
+\r
+#column3 {\r
+       float: left;\r
+       width: 280px;\r
+}\r
+\r
+#column4 {\r
+       float: right;\r
+       width: 260px;\r
+}\r
+\r
+\r
+/* Banner Style */\r
+\r
+#banner-wrapper {\r
+       background: #FFFFFF;\r
+}\r
+\r
+#banner {\r
+       overflow: hidden;\r
+       background: #FFFFFF;\r
+       /* width: 1160px; */\r
+       margin: 20px auto 50px auto;\r
+}\r
+\r
+#banner h1 {\r
+       text-align: center\r
+}\r
+\r
+#banner .img-border {\r
+       height: 500px;\r
+       border: 20px solid #FFFFFF;\r
+}\r
+\r
+/* Button Style */\r
+\r
+.button-style {\r
+       display: inline-block;\r
+       margin-top: 30px;\r
+       padding: 7px 30px;\r
+       background: #36332E;\r
+       border-radius: 5px;\r
+}\r
+\r
+.button-style a {\r
+       letter-spacing: 1px;\r
+       text-decoration: none;\r
+       text-transform: uppercase;\r
+       font-family: 'Oswald', sans-serif;\r
+       font-weight: 300;\r
+       font-size: 16px;\r
+       color: #FFFFFF;\r
+}\r
+\r
+/* List Style 1 */\r
+\r
+ul.style1 {\r
+       margin: 0px;\r
+       padding: 0px;\r
+       list-style: none;\r
+}\r
+\r
+ul.style1 li {\r
+       padding: 25px 0px 15px 0px;\r
+       border-top: 1px solid #A1A1A1;\r
+}\r
+\r
+ul.style1 a {\r
+       text-decoration: none;\r
+       color: #FFFFFF;\r
+}\r
+\r
+ul.style1 a:hover {\r
+       text-decoration: underline;\r
+       color: #6B6B6B;\r
+}\r
+\r
+ul.style1 .first {\r
+       padding-top: 0px;\r
+       border-top: none;\r
+}\r
+\r
+/** LIST STYLE 3 */\r
+\r
+ul.style3 {\r
+       margin: 0px;\r
+       padding: 0px;\r
+       list-style: none;\r
+}\r
+\r
+ul.style3 li {\r
+       padding: 10px 0px 10px 0px;\r
+       border-top: 1px solid #A1A1A1;\r
+}\r
+\r
+ul.style3 a {\r
+       text-decoration: none;\r
+       color: #949494;\r
+}\r
+\r
+ul.style3 a:hover {\r
+       text-decoration: underline;\r
+}\r
+\r
+ul.style3 .first {\r
+       padding-top: 0px;\r
+       border-top: none;\r
+       box-shadow: none;\r
+}\r
+\r
+ul.style3 .date {\r
+       width: 87px;\r
+       background-color: #36332E;\r
+       margin-top: 20px;\r
+       height: 24px;\r
+       line-height: 24px;\r
+       text-align: center;\r
+       font-size: 12px;\r
+       color: #FFFFFF;\r
+}\r
+\r
+ul.style3 .first .date\r
+{\r
+       margin-top: 0px;\r
+}\r
+\r
+\r
+/* Recent News */\r
+\r
+#recent-news {\r
+       overflow: hidden;\r
+       width: 1120px;\r
+       margin: 0px auto;\r
+       padding: 50px 40px;\r
+       background: #36332E;\r
+       color: #8C8C8C;\r
+}\r
+\r
+#recent-news h2 {\r
+       padding: 0px 0px 20px 0px;\r
+       font-family: Arial, Helvetica, sans-serif;\r
+       font-size: 2.5em;\r
+       color: #EDEDED;\r
+}\r
+\r
+#recent-news .date {\r
+       padding: 0px 0px 10px 0px;\r
+       font-weight: bold;\r
+       font-style: normal;\r
+       color: #E3E3E3;\r
+}\r
+\r
+#recent-news p {\r
+       font-style: italic;\r
+}\r
+\r
+#recent-news a {\r
+       font-style: normal;\r
+       color: #B8B8B8;\r
+}\r
+\r
+#recent-news #rbox1 {\r
+       float: left;\r
+       width: 250px;\r
+       margin-right: 40px;\r
+}\r
+\r
+#recent-news #rbox2 {\r
+       float: left;\r
+       width: 250px;\r
+       margin-right: 40px;\r
+}\r
+\r
+#recent-news #rbox3 {\r
+       float: left;\r
+       width: 250px;\r
+}\r
+\r
+#recent-news #rbox4 {\r
+       float: right;\r
+       width: 250px;\r
+}\r
+\r
+/* Button Style */\r
+\r
+.button-style1 {\r
+       margin-top: 30px;\r
+}\r
+\r
+.button-style1 a {\r
+       padding: 10px 25px;\r
+       background: #EBB462;\r
+       border-radius: 5px;\r
+       text-decoration: none;\r
+       text-shadow: 1px 1px 0px #FCE3BB;\r
+       color: #36332E !important;\r
+}\r
diff --git a/taglines.c b/taglines.c
new file mode 100644 (file)
index 0000000..9a4fa2d
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "bool.h"
+#include "defs.h"
+#include "typedef.h"
+#include "tokens.h"
+#include "taglist.h"
+#include "lex.h"
+#include "lines.h"
+#include "lists.h"
+#include "moves.h"
+#include "output.h"
+#include "taglines.h"
+
+static FILE *yyin = NULL;
+
+        /* Read the list of extraction criteria from TagFile.
+         * This doesn't use the normal lexical analyser before the
+         * PGN files are processed but circumvents next_token by
+         * calling get_tag() and get_string. This allows it to detect
+         * EOF before yywrap() is called.
+         * Be careful to leave lex in the right state.
+         */
+void
+read_tag_file(const char *TagFile)
+{   
+    yyin = fopen(TagFile,"r");
+    if(yyin != NULL){
+        Boolean keep_reading = TRUE;
+        
+        while(keep_reading){
+            char *line = next_input_line(yyin);
+            if(line != NULL){
+                keep_reading = process_tag_line(TagFile,line);
+            }
+            else{
+                keep_reading = FALSE;
+            }
+        }
+        (void) fclose(yyin);
+        /* Call yywrap in order to set up for the next (first) input file. */
+        (void) yywrap();
+       yyin = NULL;
+    }
+    else{
+        fprintf(GlobalState.logfile,
+                "Unable to open %s for reading.\n",TagFile);
+        exit(1);
+    }
+}
+
+        /* Read the contents of a file that lists the
+         * required output ordering for tags.
+         */
+void
+read_tag_roster_file(const char *RosterFile)
+{   Boolean keep_reading = TRUE;
+    yyin = must_open_file(RosterFile,"r");
+    
+    while(keep_reading){
+        char *line = next_input_line(yyin);
+        if(line != NULL){
+            keep_reading = process_roster_line(line);
+        }
+        else{
+            keep_reading = FALSE;
+        }
+    }
+    (void) fclose(yyin);
+    /* Call yywrap in order to set up for the next (first) input file. */
+    (void) yywrap();
+}
+
+        /* Extract a tag/value pair from the given line.
+         * Return TRUE if this was successful.
+         */
+Boolean
+process_tag_line(const char *TagFile,char *line)
+{
+    Boolean keep_reading = TRUE;
+    if(non_blank_line(line)){
+        unsigned char *linep = (unsigned char *) line;
+        /* We should find a tag. */
+        LinePair resulting_line = gather_tag(line,linep);
+        TokenType tag_token;
+
+        /* Pick up where we are now. */
+        line = resulting_line.line;
+        linep = resulting_line.linep;
+        tag_token = resulting_line.token;
+        if(tag_token != NO_TOKEN){
+            /* Pick up which tag it was. */
+            int tag_index = yylval.tag_index;
+            /* Allow for an optional operator. */
+            TagOperator operator = NONE;
+
+            /* Skip whitespace up to a double quote. */
+            while(is_character_class(*linep, WHITESPACE)){
+                linep++;
+            }
+            /* Allow for an optional operator. */
+            if(is_character_class(*linep, OPERATOR)){
+                switch(*linep){
+                  case '<':
+                    linep++;
+                    if(*linep == '='){
+                        linep++;
+                        operator = LESS_THAN_OR_EQUAL_TO;
+                    }
+                    else if(*linep == '>'){
+                        linep++;
+                        operator = NOT_EQUAL_TO;
+                    }
+                    else{
+                        operator = LESS_THAN;;
+                    }
+                    break;
+                  case '>':
+                    linep++;
+                    if(*linep == '='){
+                        linep++;
+                        operator = GREATER_THAN_OR_EQUAL_TO;
+                    }
+                    else{
+                        operator = GREATER_THAN;
+                    }
+                    break;
+                  case '=':
+                    linep++;
+                    operator = EQUAL_TO;
+                    break;
+                  default:
+                    fprintf(GlobalState.logfile,
+                        "Internal error: unknown operator in %s\n",line);
+                    linep++;
+                    break;
+                }
+                /* Skip whitespace up to a double quote. */
+                while(is_character_class(*linep, WHITESPACE)){
+                    linep++;
+                }
+            }
+
+            if(is_character_class(*linep, DOUBLE_QUOTE)){
+                /* A string, as expected. */
+                linep++;
+                resulting_line = gather_string(line,linep);
+                line = resulting_line.line;
+                linep = resulting_line.linep;
+                if(tag_token == TAG){
+                    /* Treat FEN* tags as a special case.
+                     * Use the position they represent to indicate
+                     * a positional match.
+                     */
+                    if(tag_index == FEN_TAG){
+                        add_fen_positional_match(yylval.token_string);
+                        (void) free((void *)yylval.token_string);
+                    }
+                    else if(tag_index == PSEUDO_FEN_PATTERN_TAG){
+                        add_fen_pattern_match(yylval.token_string);
+                        (void) free((void *)yylval.token_string);
+                    }
+                    else{
+                        add_tag_to_list(tag_index,yylval.token_string,operator);
+                        (void) free((void *)yylval.token_string);
+                    }
+                }
+                else{
+                    if(!GlobalState.skipping_current_game){
+                            fprintf(GlobalState.logfile,
+                                "File %s: unrecognised tag name %s\n",
+                                        TagFile,line);
+                    }
+                    (void) free((void *)yylval.token_string);
+                }
+            }
+            else{
+                if(!GlobalState.skipping_current_game){
+                    fprintf(GlobalState.logfile,
+                            "File %s: missing quoted tag string in %s at %s\n",
+                            TagFile,line,linep);
+                }
+            }
+        }
+        else{
+            /* Terminate the reading, as we have run out of tags. */
+            keep_reading = FALSE;
+        }
+    }
+    return keep_reading;
+}
+
+        /* Extract a tag name from the given line.
+         * Return TRUE if this was successful.
+         */
+Boolean
+process_roster_line(char *line)
+{
+    Boolean keep_reading = TRUE;
+    if(non_blank_line(line)){
+        unsigned char *linep = (unsigned char *) line;
+        /* We should find a tag. */
+        LinePair resulting_line = gather_tag(line,linep);
+        TokenType tag_token;
+
+        /* Pick up where we are now. */
+        line = resulting_line.line;
+        linep = resulting_line.linep;
+        tag_token = resulting_line.token;
+        if(tag_token != NO_TOKEN){
+            /* Pick up which tag it was. */
+            int tag_index = yylval.tag_index;
+            add_to_output_tag_order((TagName) tag_index);
+        }
+        else{
+            /* Terminate the reading, as we have run out of tags. */
+            keep_reading = FALSE;
+        }
+    }
+    return keep_reading;
+}
diff --git a/taglines.h b/taglines.h
new file mode 100644 (file)
index 0000000..67d202e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+void read_tag_file(const char *TagFile);
+void read_tag_roster_file(const char *RosterFile);
+Boolean process_tag_line(const char *TagFile,char *line);
+Boolean process_roster_line(char *line);
+
diff --git a/taglist.h b/taglist.h
new file mode 100644 (file)
index 0000000..5192b68
--- /dev/null
+++ b/taglist.h
@@ -0,0 +1,92 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+        /* Define indices for the set of pre-defined tags.
+         * Higher values are created dynamically as new
+         * tags are recognised in the source files.
+         */
+
+    /* List the tags so that the strings that they represent
+     * would be in alphabetical order. E.g. note that EVENT_TAG and
+     * EVENT_DATE_TAG should be in this order because the strings are
+     * "Event" and "EventDate".
+     */
+typedef enum {
+    ANNOTATOR_TAG,
+    BLACK_TAG,
+    BLACK_ELO_TAG,
+    BLACK_NA_TAG,
+    BLACK_TITLE_TAG,
+    BLACK_TYPE_TAG,
+    BLACK_USCF_TAG,
+    BOARD_TAG,
+    DATE_TAG,
+    ECO_TAG,
+    /* The PSEUDO_ELO_TAG is not a real PGN one.  It is used with the -t
+     * argument so that it becomes possible to indicate a rating of either colour.
+     */
+    PSEUDO_ELO_TAG,
+    EVENT_TAG,
+    EVENT_DATE_TAG,
+    EVENT_SPONSOR_TAG,
+    FEN_TAG,
+    /* The PSEUDO_FEN_PATTERN_TAG is not a real PGN one.  It is used with the -t
+     * argument so that it becomes possible to indicate a FEN-based board pattern.
+     */
+    PSEUDO_FEN_PATTERN_TAG,
+    HASHCODE_TAG,
+    LONG_ECO_TAG,
+    MODE_TAG,
+    NIC_TAG,
+    OPENING_TAG,
+    /* The PSEUDO_PLAYER_TAG is not a real PGN one.  It is used with the -t
+     * argument so that it becomes possible to indicate a player of either colour.
+     */
+    PSEUDO_PLAYER_TAG,
+    PLY_COUNT_TAG,
+    /* The TOTAL_PLY_COUNT_TAG is used with the --totalplycount argument
+     * so record the total number of plies in a game.
+     */
+    TOTAL_PLY_COUNT_TAG,
+    RESULT_TAG,
+    ROUND_TAG,
+    SECTION_TAG,
+    SETUP_TAG,
+    SITE_TAG,
+    STAGE_TAG,
+    SUB_VARIATION_TAG,
+    TERMINATION_TAG,
+    TIME_TAG,
+    TIME_CONTROL_TAG,
+    UTC_DATE_TAG,
+    UTC_TIME_TAG,
+    VARIATION_TAG,
+    WHITE_TAG,
+    WHITE_ELO_TAG,
+    WHITE_NA_TAG,
+    WHITE_TITLE_TAG,
+    WHITE_TYPE_TAG,
+    WHITE_USCF_TAG,
+    /* The following should always be last. It should not be used
+     * as a tag identification.
+     */
+    ORIGINAL_NUMBER_OF_TAGS
+} TagName;
diff --git a/test/Makefile b/test/Makefile
new file mode 100644 (file)
index 0000000..d8e532f
--- /dev/null
@@ -0,0 +1,656 @@
+# Makefile to run a battery of tests of the basic functionality of pgn-extract.
+# Copyright (C) David J. Barnes, 2013
+#
+# Each test is run and then, where relevant, a comparison is made between
+# the output files generated in the current directory and the 'oracle'
+# files that exist in $(OUTPUT).
+#
+# Beware of case-insensitive filenames when testing flags that
+# differ only in letter case. In general, double letters have been
+# used for output-files generated from using upper-case flag letters.
+
+PGN_EXTRACT=../pgn-extract
+# Use for memory checking if valgrind is installed.
+#PGN_EXTRACT=valgrind --dsymutil=yes ../pgn-extract
+
+# Location of the file of ECO classifications.
+ECO_FILE=../eco.pgn
+
+# Location of the input files
+INPUT=infiles
+# Location of the oracle output files
+OUTPUT=outfiles
+
+# Test everything.
+all: no-flags-1 no-flags-2 test-7 test-append test-AA test-bl45 \
+     test-bu45 test-bu30 test-checkfile test-nocomments test-duplicates \
+     test-noduplicates test-e test-EE test-f test-FF test-h test-l \
+     test-LL test-checkmate test-n test-NN test-output test-PP test-r \
+     test-RR test-s test-SS test-t test-TT test-nounique test-v \
+     test-VV test-linelength test-WW test-x test-ZZ test-z test-hash \
+     test-evaluation test-fencomments test-markmatches test-nochecks \
+     test-nomovenumbers test-noresults test-notags test-plylimit \
+     test-stalemate test-long-line test-totalplycount test-addhashcode \
+     test-selectonly
+
+# BEWARE: This removes all PGN files in the current directory.
+# The required test PGN files are assumed to be in $(INPUT).
+clean:
+       -rm *.pgn *og.txt
+
+# No flags:
+#     + No input file.
+#     - Input file(s): N/A
+#     - Example input:
+#       f3 e5 g4 Qh4 0-1
+#     - Resulting output should be that the game input on standard input is
+#       formatted as PGN on standard output.
+#     - Expected output: 
+#       Contents of fools-mate.pgn on standard output.
+no-flags-1:
+       echo "test: No input file."
+       $(PGN_EXTRACT) < $(INPUT)/fools-mate.txt
+
+# No flags:
+#     + Single input file
+#     - Input file(s): fools-mate.txt
+#     - Resulting output should be the input formatted as PGN on standard output.
+#     - Expected output: Contents of fools-mate.pgn should appear on standard output.
+no-flags-2:
+       echo "test: No flags."
+       $(PGN_EXTRACT) $(INPUT)/fools-mate.txt
+
+# -7 / --seven
+#     + Input file with games having tags additional to the seven tag roster.
+#     - Input file(s): test-7.pgn
+#     - Game output should have only the tags of the seven tag roster.
+#     - Expected output: test-7-out.pgn
+test-7:
+       echo "test-7:"
+       $(PGN_EXTRACT) -7 -otest-7-out.pgn $(INPUT)/test-7.pgn
+       -cmp test-7-out.pgn $(OUTPUT)/test-7-out.pgn
+
+# -a / --append
+#     + Input file containing games in any accepted format.
+#     - Input file(s): test-a.txt
+#     - Resulting output should contain two versions of the input game
+#       formatted in PGN. The --output command is run first to create
+#       a new file, then the -a version to append to that file.
+#     - Expected output: test-a-out.pgn
+test-append:
+       echo "test-append:"
+       $(PGN_EXTRACT) --output test-a-out.pgn $(INPUT)/test-a.txt
+       $(PGN_EXTRACT) -atest-a-out.pgn $(INPUT)/test-a.txt
+       -cmp test-a-out.pgn $(OUTPUT)/test-a-out.pgn
+
+       $(PGN_EXTRACT) --output test-a-out.pgn $(INPUT)/test-a.txt
+       $(PGN_EXTRACT) --append test-a-out.pgn $(INPUT)/test-a.txt
+       -cmp test-a-out.pgn $(OUTPUT)/test-a-out.pgn
+
+# -A
+#     + Input file containing games and a file of arguments.
+#     - Input file(s): fischer.pgn, petrosian.pgn, arglist.txt
+#     - Resulting output should be files separating the unique and
+#       duplicated games in the input files.
+#     - Expected output: test-AA-unique.pgn, test-AA-dupes.pgn
+test-AA:
+       echo "test-A:"
+       $(PGN_EXTRACT) -A$(INPUT)/argslist.txt
+       -cmp test-AA-dupes.pgn $(OUTPUT)/test-AA-dupes.pgn
+       -cmp test-AA-unique.pgn $(OUTPUT)/test-AA-unique.pgn
+
+# -b
+#     + Input file containing games of different length.
+#     - Input file(s): fischer.pgn
+#     - Resulting output: games whose number of moves is within
+#       the specified bounds.
+# 
+test-b: test-bl45 test-bu45 test-bu30
+
+#     - Expected output: 45 moves or more: test-bl45-out.pgn
+test-bl45:
+       echo "test-b:"
+       $(PGN_EXTRACT) -bl45 -s -otest-bl45-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-bl45-out.pgn $(OUTPUT)/test-bl45-out.pgn
+
+#     - Expected output: 45 moves or less: test-bu45-out.pgn
+test-bu45:
+       echo "test-b:"
+       $(PGN_EXTRACT) -bu45 -s -otest-bu45-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-bu45-out.pgn $(OUTPUT)/test-bu45-out.pgn
+
+#     - Expected output: exactly 30 moves: test-b30-out.pgn
+test-bu30:
+       echo "test-b:"
+       $(PGN_EXTRACT) -b30 -s -otest-b30-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-b30-out.pgn $(OUTPUT)/test-b30-out.pgn
+
+# 
+# -c / --checkfile
+#     + Input files containing games.
+#     - Input file(s): fischer.pgn, petrosian.pgn
+#     - Resulting output should contain matched games that do not already occur in
+#       the check file.
+#     - Expected output: test-c-out.pgn
+test-checkfile:
+       echo "test-checkfile:"
+       $(PGN_EXTRACT) -c$(INPUT)/petrosian.pgn -D -TpPetrosian -otest-c-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-c-out.pgn $(OUTPUT)/test-c-out.pgn
+       $(PGN_EXTRACT) -c$(INPUT)/clist.txt -D -TpPetrosian -otest-c-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-c-out.pgn $(OUTPUT)/test-c-out.pgn
+
+# -C / --nocomments
+#     + Input file containing games with comments
+#     - Input file(s): test-C.pgn
+#     - Resulting output should have all comments removed.
+#     - Expected output: test-CC-out.pgn
+test-nocomments:
+       echo "test-nocomments:"
+       $(PGN_EXTRACT) -C -otest-CC-out.pgn $(INPUT)/test-C.pgn
+       -cmp test-CC-out.pgn $(OUTPUT)/test-CC-out.pgn
+
+# -d / --duplicates
+#     + Input file containing games with duplicates and non-duplicates.
+#     - Input file(s): fischer.pgn, $(INPUT)/petrosian.pgn
+#     - Resulting output should be files separating the unique and
+#       duplicated games in the input files.
+#     - Expected output: test-d-unique.pgn, test-d-dupes.pgn
+test-duplicates:
+       echo "test-duplicates:"
+       $(PGN_EXTRACT) -dtest-d-dupes.pgn -s -otest-d-unique.pgn $(INPUT)/fischer.pgn $(INPUT)/petrosian.pgn
+       -cmp test-d-dupes.pgn $(OUTPUT)/test-d-dupes.pgn
+       -cmp test-d-unique.pgn $(OUTPUT)/test-d-unique.pgn
+
+# -D / --noduplicates
+#     + Input file containing games with duplicates and non-duplicates.
+#     - Input file(s): fischer.pgn, $(INPUT)/petrosian.pgn
+#     - Resulting output should be a file containing the combined input
+#       with duplicate games removed.
+#     - Expected output: test-DD-unique.pgn
+test-noduplicates:
+       echo "test-noduplicates:"
+       $(PGN_EXTRACT) -D -s -otest-DD-unique.pgn $(INPUT)/fischer.pgn $(INPUT)/petrosian.pgn
+       -cmp test-DD-unique.pgn $(OUTPUT)/test-DD-unique.pgn
+       $(PGN_EXTRACT) --noduplicates -s -otest-DD-unique.pgn $(INPUT)/fischer.pgn $(INPUT)/petrosian.pgn
+       -cmp test-DD-unique.pgn $(OUTPUT)/test-DD-unique.pgn
+
+# -e
+#     + Input file containing games without ECO classifications.
+#     - Input file(s): test-e.pgn and eco.pgn in the test folder.
+#     - Resulting output should have ECO classification added to the tags.
+#     - Expected output: test-e-out.pgn
+test-e:
+       echo "test-e:"
+       $(PGN_EXTRACT) -e$(ECO_FILE) -otest-e-out.pgn $(INPUT)/test-e.pgn
+       -cmp test-e-out.pgn $(OUTPUT)/test-e-out.pgn
+
+# -E
+#     + Input file containing games.
+#     - Input file(s): test-E.pgn and eco.pgn if -e flag is used.
+#     - Resulting output should be separate files for each ECO classification
+#       at the level of the initial letter (A-E).
+#     - Expected output: A.pgn, B.pgn, E.pgn
+test-EE:
+       echo "test-E:"
+       $(PGN_EXTRACT) -e$(ECO_FILE) -E1 $(INPUT)/test-E.pgn
+       -cmp A.pgn $(OUTPUT)/A.pgn
+       -cmp B.pgn $(OUTPUT)/B.pgn
+       -cmp E.pgn $(OUTPUT)/E.pgn
+
+# -f
+#     + Input files containing games.
+#     - Input file(s): test-f1.pgn, test-f2.pgn, files.txt
+#     - Resulting output should be the combination of the input files.
+#     - Expected output: test-f-out.pgn
+test-f:
+       echo "test-f:"
+       $(PGN_EXTRACT) -f$(INPUT)/files.txt -otest-f-out.pgn
+       -cmp test-f-out.pgn $(OUTPUT)/test-f-out.pgn
+
+# -F:
+#     + Input file containing games without a trailing FEN comment.
+#     - Input file(s): test-F.pgn
+#     - Resulting output should have a comment at the end containing
+#       the FEN description of the final position.
+#     - Expected output: test-FF-out.pgn
+test-FF:
+       echo "test-F:"
+       $(PGN_EXTRACT) -F -otest-FF-out.pgn $(INPUT)/test-F.pgn
+       -cmp test-FF-out.pgn $(OUTPUT)/test-FF-out.pgn
+
+# 
+# -h / -? / --help
+#     + No input required.
+#     - Input file(s): N/A
+#     - Resulting output should be a description of how to use pgn-extract
+#     - Expected output: N/A
+# Also:
+#      ../pgn-extract -?
+#      ../pgn-extract --help
+test-h:
+       echo "test-h:"
+       -$(PGN_EXTRACT) -h
+
+# -l
+#     + Input file containing games.
+#     - Input file(s): fischer.pgn
+#     - Resulting output: List of games parsed written to log.txt
+#     - Expected output: log.txt
+test-l:
+       echo "test-l:"
+       $(PGN_EXTRACT) -llog.txt -otest-l-out.pgn $(INPUT)/fischer.pgn
+       -cmp log.txt $(OUTPUT)/log.txt
+       -cmp test-l-out.pgn $(OUTPUT)/test-l-out.pgn
+
+# -L
+#     + Input file containing games.
+#     - Input file(s): test-L1.pgn, test-L2.pgn
+#     - Resulting output should be that log.txt contains the combined
+#       logs from two runs of pgn-extract.
+#     - Expected output: log.txt
+test-LL:
+       echo "test-L:"
+       $(PGN_EXTRACT) -lLLog.txt -r $(INPUT)/test-L1.pgn
+       $(PGN_EXTRACT) -LLLog.txt -r $(INPUT)/test-L2.pgn
+       -cmp LLog.txt $(OUTPUT)/LLog.txt
+
+# -M / --checkmate
+#     + Input file containing games.
+#     - Input file(s): test-checkmate.pgn
+#     - Resulting output should contain only those games that end in checkmate.
+#     - Expected output: test-checkmate-out.pgn
+test-checkmate:
+       echo "test-checkmate:"
+       $(PGN_EXTRACT) --checkmate -otest-checkmate-out.pgn $(INPUT)/test-checkmate.pgn
+       -cmp test-checkmate-out.pgn $(OUTPUT)/test-checkmate-out.pgn
+
+# -n
+#     + Input file containing games.
+#     - Input file(s): petrosian.pgn
+#     - Resulting output should be separate files containing matched
+#       and non-matched games.
+#     - Expected output: test-n-matched.pgn, test-n-unmatched.pgn
+test-n:
+       echo "test-n:"
+       $(PGN_EXTRACT) -TpFischer -otest-n-matched.pgn -ntest-n-unmatched.pgn $(INPUT)/petrosian.pgn
+       -cmp test-n-matched.pgn $(OUTPUT)/test-n-matched.pgn
+       -cmp test-n-unmatched.pgn $(OUTPUT)/test-n-unmatched.pgn
+
+# -N / --nonags
+#     + Input file containing games with NAGs.
+#     - Input file(s): test-N.pgn
+#     - Resulting output should have all NAGs removed.
+#     - Expected output: test-NN-out.pgn
+test-NN:
+       echo "test-N:"
+       $(PGN_EXTRACT) -N -otest-NN-out.pgn $(INPUT)/test-N.pgn
+       -cmp test-NN-out.pgn $(OUTPUT)/test-NN-out.pgn
+
+# 
+# -o / --output
+#     + Input file containing games in any accepted format.
+#     - Input file(s): test-o.txt
+#     - Resulting output should contain the input game formatted in PGN.
+#     - Expected output: test-o-out.pgn
+test-output:
+       echo "test-output:"
+       $(PGN_EXTRACT) -otest-o-out.pgn $(INPUT)/test-o.txt
+       -cmp test-o-out.pgn $(OUTPUT)/test-o-out.pgn
+       $(PGN_EXTRACT) --output test-o-out.pgn $(INPUT)/test-o.txt
+       -cmp test-o-out.pgn $(OUTPUT)/test-o-out.pgn
+
+# -P
+#     + Input file containing games with different sequences for the same
+#       opening.
+#     - Input file(s): test-P.pgn, Pvars.txt
+#     - Resulting output should be games whose opening move exactly match
+#       the sequence specified in Pvars.txt
+#     - Expected output: test-PP-out.pgn
+test-PP:
+       echo "test-P:"
+       $(PGN_EXTRACT) -P -v$(INPUT)/Pvars.txt -otest-PP-out.pgn $(INPUT)/test-P.pgn
+       -cmp test-PP-out.pgn $(OUTPUT)/test-PP-out.pgn
+
+# -r
+#     + Input file containing games in any accepted format.
+#     - Input file(s): test-r.text
+#     - Resulting output should contain tag summary lines for the games
+#       matched and a report of any errors.
+#     - Expected output: test-r-log.txt
+test-r:
+       echo "test-r:"
+       $(PGN_EXTRACT) -r -ltest-r-log.txt $(INPUT)/test-r.txt
+       -cmp test-r-log.txt $(OUTPUT)/test-r-log.txt
+
+# -R
+#     + Input file containing games.
+#     - Input file(s): test-R.pgn, roster.txt
+#     - Resulting output should contain games with their tag roster in
+#       the order specified in roster.txt
+#     - Expected output: test-R-out.pgn
+test-RR:
+       echo "test-R:"
+       $(PGN_EXTRACT) -R$(INPUT)/roster.txt --output test-RR-out.pgn $(INPUT)/test-R.pgn
+       -cmp test-RR-out.pgn $(OUTPUT)/test-RR-out.pgn
+
+# -s
+#     + Input file containing games.
+#     - Input file(s): test-s.pgn
+#     - Resulting output should be silent, with games written to the output file.
+#     - Expected output: test-s-out.pgn
+test-s:
+       echo "test-s:"
+       $(PGN_EXTRACT) -s -o test-s-out.pgn $(INPUT)/test-s.pgn
+       -cmp test-s-out.pgn $(OUTPUT)/test-s-out.pgn
+
+# -S
+#     + Input file containing games whose players' names have slight
+#       sound variations from anglesized versions.
+#     - Input file(s): test-S.pgn
+#     - Resulting output should be games that match by ignoring slight
+#       soundex differences.
+#     - Expected output: test-S-out.pgn
+test-SS:
+       echo "test-S:"
+       $(PGN_EXTRACT) -S -TpPetrosian -otest-SS-out.pgn $(INPUT)/test-S.pgn
+       -cmp test-SS-out.pgn $(OUTPUT)/test-SS-out.pgn
+
+# -t
+#     + Input file containing games and a file of tag criteria.
+#     - Input file(s): test-t.pgn, taglist.txt
+#     - Resulting output should be only those games whose tags match
+#       all of the criteria.
+#     - Expected output: test-t-out.pgn
+test-t:
+       echo "test-t:"
+       $(PGN_EXTRACT) -t$(INPUT)/taglist.txt -otest-t-out.pgn $(INPUT)/test-t.pgn
+       -cmp test-t-out.pgn $(OUTPUT)/test-t-out.pgn
+
+# -T
+#     + Input file containing games with tag information.
+#     - Input file(s): fischer.pgn, test-Ta.pgn (and eco.pgn for -Te test.)
+#     - Resulting output should contain only those games whose tag information
+#       matches that specified.
+#     - Expected output: test-Ta-out.pgn, test-Tb-out.pgn, test-Td-out.pgn,
+#                        test-Tdd-out.pgn test-Te-out.pgn, test-Tp-out.pgn,
+#                        test-Tw-out.pgn
+test-TT:
+       echo "test-T:"
+       $(PGN_EXTRACT) -Td1970 -s -otest-TTd-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-TTd-out.pgn $(OUTPUT)/test-TTd-out.pgn
+       $(PGN_EXTRACT) -Td1960 -Td1962 -s -otest-TTdd-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-TTdd-out.pgn $(OUTPUT)/test-TTdd-out.pgn
+       $(PGN_EXTRACT) -TbPetrosian -s -otest-TTb-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-TTb-out.pgn $(OUTPUT)/test-TTb-out.pgn
+       $(PGN_EXTRACT) -e$(ECO_FILE) -TeB14 -s -otest-Te-out.pgn $(INPUT)/fischer.pgn
+       $(PGN_EXTRACT) -TpPetrosian -s -otest-TTp-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-TTp-out.pgn $(OUTPUT)/test-TTp-out.pgn
+       $(PGN_EXTRACT) -Tr0-1 -s -otest-TTr-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-TTr-out.pgn $(OUTPUT)/test-TTr-out.pgn
+       $(PGN_EXTRACT) -TwFischer -s -otest-TTw-out.pgn $(INPUT)/fischer.pgn
+       -cmp test-TTw-out.pgn $(OUTPUT)/test-TTw-out.pgn
+       $(PGN_EXTRACT) -TaBarnes -s -otest-TTa-out.pgn $(INPUT)/test-Ta.pgn
+       -cmp test-TTa-out.pgn $(OUTPUT)/test-TTa-out.pgn
+
+# -U / --nounique
+#     + Input file containing games with duplicates and non-duplicates.
+#     - Input file(s): fischer.pgn, petrosian.pgn
+#     - Resulting output should be a file containing just the duplicate games.
+#     - Expected output: test-U-unique.pgn
+test-nounique:
+       echo "test-nounique:"
+       $(PGN_EXTRACT) -U -s -otest-UU-unique.pgn $(INPUT)/fischer.pgn $(INPUT)/petrosian.pgn
+       -cmp test-UU-unique.pgn $(OUTPUT)/test-UU-unique.pgn
+       $(PGN_EXTRACT) --nounique -s -otest-UU-unique.pgn $(INPUT)/fischer.pgn $(INPUT)/petrosian.pgn
+       -cmp test-UU-unique.pgn $(OUTPUT)/test-UU-unique.pgn
+
+# -v
+#     + Input file containing games.
+#     - Input file(s): najdorf.pgn, vvars.txt
+#     - Resulting output should be only those games whose opening moves
+#       textually match (in any order) the moves in vars.txt.
+#     - Expected output: test-v-out.pgn
+test-v:
+       echo "test-v:"
+       $(PGN_EXTRACT) -v$(INPUT)/vvars.txt -otest-v-out.pgn $(INPUT)/najdorf.pgn
+       -cmp test-v-out.pgn $(OUTPUT)/test-v-out.pgn
+
+# -V
+#     + Input file containing games with variations
+#     - Input file(s): test-V.pgn
+#     - Resulting output should have all variations removed.
+#     - Expected output: test-V-out.pgn
+test-VV:
+       echo "test-V:"
+       $(PGN_EXTRACT) -V -otest-VV-out.pgn $(INPUT)/test-V.pgn
+       -cmp test-VV-out.pgn $(OUTPUT)/test-VV-out.pgn
+
+# -w / --linelength
+#     + Input file containing games.
+#     - Input file(s): test-w.pgn
+#     - Resulting output Games formatted up to the specified line length.
+#       The default is 75.
+#     - Expected output: test-w60-out.pgn, test-w75-out.pgn, test-w1000-out.pgn
+test-linelength:
+       echo "test-linelength:"
+       $(PGN_EXTRACT) -w60 -otest-w60-out.pgn $(INPUT)/test-w.pgn
+       -cmp test-w60-out.pgn $(OUTPUT)/test-w60-out.pgn
+       $(PGN_EXTRACT) -w75 -otest-w75-out.pgn $(INPUT)/test-w.pgn
+       -cmp test-w75-out.pgn $(OUTPUT)/test-w75-out.pgn
+       $(PGN_EXTRACT) -w1000 -otest-w1000-out.pgn $(INPUT)/test-w.pgn
+       -cmp test-w1000-out.pgn $(OUTPUT)/test-w1000-out.pgn
+
+       $(PGN_EXTRACT) --linelength 60 -otest-w60-out.pgn $(INPUT)/test-w.pgn
+       -cmp test-w60-out.pgn $(OUTPUT)/test-w60-out.pgn
+       $(PGN_EXTRACT) --linelength 75 -otest-w75-out.pgn $(INPUT)/test-w.pgn
+       -cmp test-w75-out.pgn $(OUTPUT)/test-w75-out.pgn
+       $(PGN_EXTRACT) --linelength 1000 -otest-w1000-out.pgn $(INPUT)/test-w.pgn
+       -cmp test-w1000-out.pgn $(OUTPUT)/test-w1000-out.pgn
+
+# -W
+#     + Input file containing games.
+#     - Input file(s): test-W.pgn
+#     - Resulting output should be games formatted in the specified notation:
+#       halg (hyphenated long algebraic), lalg (non-hyphenated long algebraic),
+#       elalg (enhanced long algebraic), uci (UCI-compatible output),
+#      and alternative piece letters.
+#     - Expected output: test-WWhalg-out.pgn, test-WWlalg-out.pgn,
+#                        test-WWelalg-out.pgn, test-WWdeutsch-out.pgn,
+#                        test-WWuci-out.pgn
+test-WW:
+       echo "test-W:"
+       $(PGN_EXTRACT) -Whalg -otest-WWhalg-out.pgn $(INPUT)/test-W.pgn
+       -cmp test-WWhalg-out.pgn $(OUTPUT)/test-WWhalg-out.pgn
+       $(PGN_EXTRACT) -Wlalg -otest-WWlalg-out.pgn $(INPUT)/test-W.pgn
+       -cmp test-WWlalg-out.pgn $(OUTPUT)/test-WWlalg-out.pgn
+       $(PGN_EXTRACT) -Welalg -otest-WWelalg-out.pgn $(INPUT)/test-W.pgn
+       -cmp test-WWelalg-out.pgn $(OUTPUT)/test-WWelalg-out.pgn
+       $(PGN_EXTRACT) -WsanBSLTDK -otest-WWdeutsch-out.pgn $(INPUT)/test-W.pgn
+       -cmp test-WWdeutsch-out.pgn $(OUTPUT)/test-WWdeutsch-out.pgn
+       $(PGN_EXTRACT) -Wuci -otest-WWuci-out.pgn $(INPUT)/test-W.pgn
+       -cmp test-WWuci-out.pgn $(OUTPUT)/test-WWuci-out.pgn
+
+# -x
+#     + Input file containing games.
+#     - Input file(s): najdorf.pgn, xvars.txt
+#     - Resulting output should be only those games which match
+#       the result of reaching the opening sequence in vars.txt.
+#     - Expected output: test-x-out.pgn
+test-x:
+       echo "test-x:"
+       $(PGN_EXTRACT) -x$(INPUT)/xvars.txt -otest-x-out.pgn $(INPUT)/najdorf.pgn
+       -cmp test-x-out.pgn $(OUTPUT)/test-x-out.pgn
+
+# -z
+#     + Input file containing games.
+#     - Input file(s): petrosian.pgn, zmatch.txt
+#     - Resulting output should be games whose material balance matches that
+#       specified in zmatch.txt
+#     - Expected output: test-z-out.pgn
+test-z:
+       echo "test-z:"
+       $(PGN_EXTRACT) -z$(INPUT)/zmatch.txt -otest-z-out.pgn $(INPUT)/petrosian.pgn
+       -cmp test-z-out.pgn $(OUTPUT)/test-z-out.pgn
+
+# -Z
+#     + Input file containing games with duplicates and non-duplicates.
+#     - Input file(s): fischer.pgn, petrosian.pgn
+#     - Resulting output should be files separating the unique and
+#       duplicated games in the input files.
+#     - Expected output: test-ZZ-unique.pgn, test-ZZ-dupes.pgn
+test-ZZ:
+       echo "test-Z:"
+       $(PGN_EXTRACT) -Z -s -dtest-ZZ-dupes.pgn -otest-ZZ-unique.pgn $(INPUT)/fischer.pgn $(INPUT)/petrosian.pgn
+       -cmp test-ZZ-dupes.pgn $(OUTPUT)/test-ZZ-dupes.pgn
+       -cmp test-ZZ-unique.pgn $(OUTPUT)/test-ZZ-unique.pgn
+
+# -#
+#     + Input file containing games.
+#     - Input file(s): test-hash.pgn
+#     - Resulting output The input file split in to separate sub-files,
+#       each containing 10 games, except the last which may contain fewer.
+#     - Expected output: 1.pgn, 2.pgn
+test-hash:
+       echo "test-hash:"
+       $(PGN_EXTRACT) -#20 -s $(INPUT)/test-hash.pgn
+       -cmp 1.pgn $(OUTPUT)/1.pgn
+       -cmp 2.pgn $(OUTPUT)/2.pgn
+
+# --evaluation
+#     + Input file containing games.
+#     - Input file(s): test-evaluation.pgn
+#     - Resulting output should include an evaluation value in a comment
+#       after every move.
+#     - Expected output: test-evaluation-out.pgn
+test-evaluation:
+       echo "test-evaluation:"
+       $(PGN_EXTRACT) --evaluation -otest-evaluation-out.pgn $(INPUT)/test-evaluation.pgn
+       -cmp test-evaluation-out.pgn $(OUTPUT)/test-evaluation-out.pgn
+
+# --fencomments
+#     + Input file containing games.
+#     - Input file(s): test-fencomments.pgn
+#     - Resulting output should have a comment after every move containing a
+#       FEN description of the position after that move.
+#     - Expected output: test-fencomments-out.pgn
+test-fencomments:
+       echo "test-fencomments:"
+       $(PGN_EXTRACT) --fencomments -otest-fencomments-out.pgn $(INPUT)/test-fencomments.pgn
+       -cmp test-fencomments-out.pgn $(OUTPUT)/test-fencomments-out.pgn
+
+# --markmatches
+#     + Input file containing games.
+#     - Input file(s): najdorf.pgn, xvars.txt
+#     - Resulting output should be only those games which match
+#       the result of reaching the opening sequence in vars.txt.
+#       The point of each match is marked with the comment { MATCH }
+#     - Expected output: test-markmatches-out.pgn
+test-markmatches:
+       echo "test-markmatches:"
+       $(PGN_EXTRACT) --markmatches MATCH -x$(INPUT)/xvars.txt -otest-markmatches-out.pgn $(INPUT)/najdorf.pgn
+       -cmp test-markmatches-out.pgn $(OUTPUT)/test-markmatches-out.pgn
+
+# --nochecks
+#     + Input file containing games with moves involving moves that give check
+#       and/or mate.
+#     - Input file(s): test-nochecks.pgn
+#     - Resulting output should contain games with no check indicators after moves.
+#     - Expected output: test-nochecks-out.pgn
+test-nochecks:
+       echo "test-nochecks:"
+       $(PGN_EXTRACT) --nochecks -otest-nochecks-out.pgn $(INPUT)/test-nochecks.pgn
+       -cmp test-nochecks-out.pgn $(OUTPUT)/test-nochecks-out.pgn
+
+# --nomovenumbers
+#     + Input file containing games with move numbers.
+#     - Input file(s): test-nomovenumbers.pgn
+#     - Resulting output should contain games with no move numbers.
+#     - Expected output: test-nomovenumbers-out.pgn
+test-nomovenumbers:
+       echo "test-nomovenumbers:"
+       $(PGN_EXTRACT) -otest-nomovenumbers-out.pgn --nomovenumbers $(INPUT)/test-nomovenumbers.pgn
+       -cmp test-nomovenumbers-out.pgn $(OUTPUT)/test-nomovenumbers-out.pgn
+
+# --noresults
+#     + Input file containing games with results.
+#     - Input file(s): test-noresults.pgn
+#     - Resulting output should contain games with no results.
+#     - Expected output: test-noresults-out.pgn
+test-noresults:
+       echo "test-noresults:"
+       $(PGN_EXTRACT) -otest-noresults-out.pgn --noresults $(INPUT)/test-noresults.pgn
+       -cmp test-noresults-out.pgn $(OUTPUT)/test-noresults-out.pgn
+
+# --notags
+#     + Input file containing games with tag information.
+#     - Input file(s): test-notags.pgn
+#     - Resulting output should contain games with no tag information.
+#     - Expected output: test-notags-out.pgn
+test-notags:
+       echo "test-notags:"
+       $(PGN_EXTRACT) -otest-notags-out.pgn --notags $(INPUT)/test-notags.pgn
+       -cmp test-notags-out.pgn $(OUTPUT)/test-notags-out.pgn
+
+# --plylimit
+#     + Input file containing games.
+#     - Input file(s): test-plylimit.pgn
+#     - Resulting output should contain games whose number of moves (plies) are
+#       limited at the specified ply limit.
+#     - Expected output: test-plylimit-out.pgn
+test-plylimit:
+       echo "test-plylimit:"
+       $(PGN_EXTRACT) --plylimit 10 -otest-plylimit-out.pgn $(INPUT)/test-plylimit.pgn
+       -cmp test-plylimit-out.pgn $(OUTPUT)/test-plylimit-out.pgn
+
+# --selectonly
+#     + Input file containing games.
+#     - Input file(s): test-selectonly.pgn
+#     - Resulting output should contain a single matched game.
+#     - Expected output: test-selectonly-out.pgn
+test-selectonly:
+       echo "test-selectonly:"
+       $(PGN_EXTRACT) -TpPetrosian --selectonly 2 -otest-selectonly-out.pgn $(INPUT)/test-selectonly.pgn
+       -cmp test-selectonly-out.pgn $(OUTPUT)/test-selectonly-out.pgn
+
+# --stalemate
+#     + Input file containing games.
+#     - Input file(s): test-stalemate.pgn
+#     - Resulting output should contain only those games that end in stalemate.
+#     - Expected output: test-stalemate-out.pgn
+test-stalemate:
+       echo "test-stalemate:"
+       $(PGN_EXTRACT) --stalemate -otest-stalemate-out.pgn $(INPUT)/test-stalemate.pgn
+       -cmp test-stalemate-out.pgn $(OUTPUT)/test-stalemate-out.pgn
+
+# --totalplycount
+#     + Input file containing games.
+#     - Input file(s): test-totalplycount.pgn
+#     - Resulting output should contain games with a TotalPlyCount tag.
+#     - Expected output: test-totalplycount-out.pgn
+test-totalplycount:
+       echo "test-totalplycount:"
+       $(PGN_EXTRACT) --totalplycount -otest-totalplycount-out.pgn $(INPUT)/test-totalplycount.pgn
+       -cmp test-totalplycount-out.pgn $(OUTPUT)/test-totalplycount-out.pgn
+
+# --addhashcode
+#     + Input file containing games.
+#     - Input file(s): test-addhashcode.pgn
+#     - Resulting output should contain games with a HashCode tag.
+#     - Expected output: test-addhashcode-out.pgn
+test-addhashcode:
+       echo "test-addhashcode:"
+       $(PGN_EXTRACT) --addhashcode -otest-addhashcode-out.pgn $(INPUT)/test-addhashcode.pgn
+       -cmp test-addhashcode-out.pgn $(OUTPUT)/test-addhashcode-out.pgn
+
+# Test on a file with a string too long to be output within the
+# defined line length.
+#     + Input file containing a game with a very long comment.
+#     + Input file(s): test-long-line.pgn
+#     + Resulting output should contain the game properly formatted and
+#       the log file should contain an error message reporting the problem.
+#     + Expected output: test-long-line-out.pgn, test-long-line-log.txt
+test-long-line:
+       echo "test long line:"
+       $(PGN_EXTRACT) -otest-long-line-out.pgn -ltest-long-line-log.txt $(INPUT)/test-long-line.pgn
+       -cmp test-long-line-out.pgn $(OUTPUT)/test-long-line-out.pgn
+       -cmp test-long-line-log.txt $(OUTPUT)/test-long-line-log.txt
diff --git a/test/infiles/Pvars.txt b/test/infiles/Pvars.txt
new file mode 100644 (file)
index 0000000..c25a37f
--- /dev/null
@@ -0,0 +1 @@
+c4 Nf6 Nc3 e6 d4 Bb4
diff --git a/test/infiles/alg.txt b/test/infiles/alg.txt
new file mode 100644 (file)
index 0000000..740554d
--- /dev/null
@@ -0,0 +1,6 @@
+b2b3 e7e5 c1b2 d7d6 d2d4 e5d4 d1d4 b8c6 d4d2 g8f6 b1c3 c8e6 e2e4 d6d5 e4d5
+e6d5 d2e3+ f8e7 g1f3 e8g8 f1e2 f8e8 e1c1 e7b4 e3d3 b4c3 b2c3 d8e7 h1e1 f6e4
+c3b2 a8d8 d3e3 b7b6 e2b5 e7e6 f3d4 c6d4 d1d4 c7c5 d4e4 d5e4 b5e8 d8e8 f2f3
+e4d5 e3e6 e8e6 e1e6 d5e6 c1d2 g8f8 b2e5 b6b5 e5b8 a7a6 b8a7 c5c4 d2c3 f8e7
+c3d4 e7d6 a7c5+ d6d7 c5a7 d7d6 a7c5+ d6d7 d4c3 g7g6 c5d4 f7f5 1/2-1/2
+
diff --git a/test/infiles/argslist.txt b/test/infiles/argslist.txt
new file mode 100644 (file)
index 0000000..9d47f33
--- /dev/null
@@ -0,0 +1,15 @@
+% Strip variations.
+:--novars
+% Silent mode
+:-s
+% Duplicates file.
+:-dtest-AA-dupes.pgn
+% Unique file.
+:--output test-AA-unique.pgn
+% Tag criteria
+:-t
+White "Fischer"
+Black "Petrosian"
+% The game files.
+:infiles/fischer.pgn
+:infiles/petrosian.pgn
diff --git a/test/infiles/barnes-horton.pgn b/test/infiles/barnes-horton.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/clist.txt b/test/infiles/clist.txt
new file mode 100644 (file)
index 0000000..4b75039
--- /dev/null
@@ -0,0 +1 @@
+infiles/petrosian.pgn
diff --git a/test/infiles/files.txt b/test/infiles/files.txt
new file mode 100644 (file)
index 0000000..e9034cc
--- /dev/null
@@ -0,0 +1,2 @@
+infiles/test-f1.pgn
+infiles/test-f2.pgn
diff --git a/test/infiles/fischer.pgn b/test/infiles/fischer.pgn
new file mode 100644 (file)
index 0000000..aa39fb5
--- /dev/null
@@ -0,0 +1,581 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
+
diff --git a/test/infiles/fools-mate.pgn b/test/infiles/fools-mate.pgn
new file mode 100644 (file)
index 0000000..dddfed0
--- /dev/null
@@ -0,0 +1,9 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 Qh4# 0-1
diff --git a/test/infiles/fools-mate.txt b/test/infiles/fools-mate.txt
new file mode 100644 (file)
index 0000000..0a8c769
--- /dev/null
@@ -0,0 +1 @@
+f3 e5 g4 Qh4 0-1
diff --git a/test/infiles/najdorf.pgn b/test/infiles/najdorf.pgn
new file mode 100644 (file)
index 0000000..f17ebc5
--- /dev/null
@@ -0,0 +1,124 @@
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.15"]
+[Round "7"]
+[White "Arnason Jon L"]
+[Black "Kristensen Bjarke"]
+[Result "0-1"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. a4 Nc6 7. Bc4 Bd7 8.
+O-O Rc8 9. Kh1 g6 10. f4 Bg7 11. Nf3 O-O 12. Ba2 b5 13. axb5 axb5 14. Qe1
+Nb4 15. Bb3 Nxc2 16. Bxc2 b4 17. e5 dxe5 18. fxe5 Ng4 19. Bd2 bxc3 20. Bxc3
+Bb5 21. Rg1 Bc6 22. Bd1 Qc7 23. Ra5 Rcd8 24. Qg3 Ne3 25. Ba4 Bb7 26. Qf2
+Rd3 27. Rb1 Ba8 28. Qe2 Ng4 29. Rf1 Re3 30. Qd2 Qc4 31. Qd1 Rd3 32. Qa1
+Rxf3 33. Rxf3 Bxf3 34. gxf3 Qf4 35. Qg1 Qxf3+ 36. Qg2 Nf2+ 37. Kg1 Nh3+ 38.
+Kh1 Qe3 39. Bd2 Nf2+ 40. Kg1 Qxd2 41. Qxf2 Qc1+ 42. Qf1 Qe3+ 43. Qf2 Qg5+
+44. Qg3 Qc1+ 45. Kg2 Rd8 46. Qf3 Qg5+ 47. Qg3 Qf5 0-1
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Bjornsson, Tomas"]
+[Black "Gretarsson, Andri A"]
+[Result "1/2-1/2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 Nbd7 7. Bc4 b5
+8. Bd5 Nxd5 9. Nxd5 Bb7 10. Nf5 Nf6 11. Bxf6 gxf6 12. Qd4 Rg8 13. g3 Rg6
+14. Nh4 Rh6 15. Nf5 Rg6 16. Nh4 Rh6 17. Nf5 Rg6 18. Nh4 1/2-1/2
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Vidarsson, Jon G"]
+[Black "Gislason, Gudmundur"]
+[Result "1-0"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 b5 8.
+g4 h6 9. Rg1 b4 10. Nce2 e5 11. Nb3 d5 12. Ng3 Bb7 13. h4 d4 14. Bf2 Qc7
+15. Bd3 Nc6 16. g5 hxg5 17. hxg5 Nd7 18. g6 f6 19. Qe2 Nd8 20. Nf5 Ne6 21.
+Bc4 Nf4 22. Bf7+ Kd8 23. Qd2 Rh2 24. O-O-O d3 25. Bb6 Qxb6 26. Qxh2 Rc8 27.
+Rd2 a5 28. Kb1 a4 29. Nc1 dxc2+ 30. Rxc2 Rxc2 31. Kxc2 Nc5 32. Rd1+ Kc7 33.
+Qd2 Nfe6 34. Kb1 Kb8 35. Nd3 b3 36. Nxc5 Bxc5 37. Ka1 1-0
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Stefansson, Hannes"]
+[Black "Olafsson, Helgi"]
+[Result "1/2-1/2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 Nbd7 8.
+g4 h6 9. Qd2 b5 10. O-O-O b4 11. Nce2 d5 12. Nf4 dxe4 13. Ndxe6 fxe6 14.
+Bc4 Qc7 15. Bxe6 Ne5 16. Bb3 Bd7 17. fxe4 Bc5 18. Bxc5 Qxc5 19. Nd3 Nxd3+
+20. Qxd3 O-O-O 21. e5 Bb5 22. Qf5+ Nd7 23. Rd5 Qe3+ 24. Kb1 Rhf8 25. Qg6
+Nc5 26. Qxg7 Nxb3 27. axb3 Bc6 28. Rxd8+ Rxd8 29. Rf1 Be4 30. Qf6 Qe2 31.
+Qe6+ Rd7 32. Rc1 Kc7 33. h4 a5 34. g5 hxg5 35. hxg5 Rd1 36. Qe7+ Kb6 37.
+Qe6+ Kc7 38. Qe7+ Kb6 39. Qe6+ Bc6 40. Rxd1 Qxd1+ 41. Ka2 Qxc2 42. Qd6 Qc5
+43. Qb8+ Bb7 44. g6 a4 45. Qd8+ Ka7 46. Qd7 Kb6 47. Qd8+ Ka6 48. Qd3+ Ka5
+49. Qd8+ Ka6 50. Qd3+ Ka7 51. Qd7 Kb6 1/2-1/2
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.15"]
+[Round "7"]
+[White "Arnason Jon L"]
+[Black "Kristensen Bjarke"]
+[Result "0-1"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. a4 Nc6 7. Bc4 Bd7 8.
+O-O Rc8 9. Kh1 g6 10. f4 Bg7 11. Nf3 O-O 12. Ba2 b5 13. axb5 axb5 14. Qe1
+Nb4 15. Bb3 Nxc2 16. Bxc2 b4 17. e5 dxe5 18. fxe5 Ng4 19. Bd2 bxc3 20. Bxc3
+Bb5 21. Rg1 Bc6 22. Bd1 Qc7 23. Ra5 Rcd8 24. Qg3 Ne3 25. Ba4 Bb7 26. Qf2
+Rd3 27. Rb1 Ba8 28. Qe2 Ng4 29. Rf1 Re3 30. Qd2 Qc4 31. Qd1 Rd3 32. Qa1
+Rxf3 33. Rxf3 Bxf3 34. gxf3 Qf4 35. Qg1 Qxf3+ 36. Qg2 Nf2+ 37. Kg1 Nh3+ 38.
+Kh1 Qe3 39. Bd2 Nf2+ 40. Kg1 Qxd2 41. Qxf2 Qc1+ 42. Qf1 Qe3+ 43. Qf2 Qg5+
+44. Qg3 Qc1+ 45. Kg2 Rd8 46. Qf3 Qg5+ 47. Qg3 Qf5 0-1
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Bjornsson, Tomas"]
+[Black "Gretarsson, Andri A"]
+[Result "1/2-1/2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Bg5 Nbd7 7. Bc4 b5
+8. Bd5 Nxd5 9. Nxd5 Bb7 10. Nf5 Nf6 11. Bxf6 gxf6 12. Qd4 Rg8 13. g3 Rg6
+14. Nh4 Rh6 15. Nf5 Rg6 16. Nh4 Rh6 17. Nf5 Rg6 18. Nh4 1/2-1/2
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Vidarsson, Jon G"]
+[Black "Gislason, Gudmundur"]
+[Result "1-0"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 b5 8.
+g4 h6 9. Rg1 b4 10. Nce2 e5 11. Nb3 d5 12. Ng3 Bb7 13. h4 d4 14. Bf2 Qc7
+15. Bd3 Nc6 16. g5 hxg5 17. hxg5 Nd7 18. g6 f6 19. Qe2 Nd8 20. Nf5 Ne6 21.
+Bc4 Nf4 22. Bf7+ Kd8 23. Qd2 Rh2 24. O-O-O d3 25. Bb6 Qxb6 26. Qxh2 Rc8 27.
+Rd2 a5 28. Kb1 a4 29. Nc1 dxc2+ 30. Rxc2 Rxc2 31. Kxc2 Nc5 32. Rd1+ Kc7 33.
+Qd2 Nfe6 34. Kb1 Kb8 35. Nd3 b3 36. Nxc5 Bxc5 37. Ka1 1-0
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Stefansson, Hannes"]
+[Black "Olafsson, Helgi"]
+[Result "1/2-1/2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 Nbd7 8.
+g4 h6 9. Qd2 b5 10. O-O-O b4 11. Nce2 d5 12. Nf4 dxe4 13. Ndxe6 fxe6 14.
+Bc4 Qc7 15. Bxe6 Ne5 16. Bb3 Bd7 17. fxe4 Bc5 18. Bxc5 Qxc5 19. Nd3 Nxd3+
+20. Qxd3 O-O-O 21. e5 Bb5 22. Qf5+ Nd7 23. Rd5 Qe3+ 24. Kb1 Rhf8 25. Qg6
+Nc5 26. Qxg7 Nxb3 27. axb3 Bc6 28. Rxd8+ Rxd8 29. Rf1 Be4 30. Qf6 Qe2 31.
+Qe6+ Rd7 32. Rc1 Kc7 33. h4 a5 34. g5 hxg5 35. hxg5 Rd1 36. Qe7+ Kb6 37.
+Qe6+ Kc7 38. Qe7+ Kb6 39. Qe6+ Bc6 40. Rxd1 Qxd1+ 41. Ka2 Qxc2 42. Qd6 Qc5
+43. Qb8+ Bb7 44. g6 a4 45. Qd8+ Ka7 46. Qd7 Kb6 47. Qd8+ Ka6 48. Qd3+ Ka5
+49. Qd8+ Ka6 50. Qd3+ Ka7 51. Qd7 Kb6 1/2-1/2
+
diff --git a/test/infiles/petrosian.pgn b/test/infiles/petrosian.pgn
new file mode 100644 (file)
index 0000000..ee67567
--- /dev/null
@@ -0,0 +1,515 @@
+[Event "?"]
+[Site "Sarajevo"]
+[Date "1972"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Hort"]
+[Result "1-0"]
+
+1. Nf3 c5 2. b3 d5 3. e3 Nf6 4. Bb2 e6 5. c4 Nc6 6. cxd5 exd5 7. Be2 Be7 8.
+O-O O-O 9. d4 Bg4 10. dxc5 Bxc5 11. Nc3 Rc8 12. Rc1 Be7 13. Nd4 Bxe2 14.
+Ncxe2 Qd7 15. Nf4 Rfd8 16. Qd3 Ne4 17. Nxc6 bxc6 18. Rc2 Bf8 19. Rfc1 Qb7
+20. Qe2 Re8 21. Qg4 g6 22. Qd1 Bd6 23. Nxd5 Rcd8 24. Rxc6 Qb8 25. f4 Re6
+26. Qd4 1-0
+
+[Event "?"]
+[Site "Buenos Aires m"]
+[Date "1971"]
+[Round "6"]
+[White "Petrosian, Tigran V."]
+[Black "Fischer, Robert J."]
+[Result "0-1"]
+
+1. Nf3 c5 2. b3 d5 3. Bb2 f6 4. c4 d4 5. d3 e5 6. e3 Ne7 7. Be2 Nec6 8.
+Nbd2 Be7 9. O-O O-O 10. e4 a6 11. Ne1 b5 12. Bg4 Bxg4 13. Qxg4 Qc8 14. Qe2
+Nd7 15. Nc2 Rb8 16. Rfc1 Qe8 17. Ba3 Bd6 18. Ne1 g6 19. cxb5 axb5 20. Bb2
+Nb6 21. Nef3 Ra8 22. a3 Na5 23. Qd1 Qf7 24. a4 bxa4 25. bxa4 c4 26. dxc4
+Nbxc4 27. Nxc4 Nxc4 28. Qe2 Nxb2 29. Qxb2 Rfb8 30. Qa2 Bb4 31. Qxf7+ Kxf7
+32. Rc7+ Ke6 33. g4 Bc3 34. Ra2 Rc8 35. Rxc8 Rxc8 36. a5 Ra8 37. a6 Ra7 38.
+Kf1 g5 39. Ke2 Kd6 40. Kd3 Kc5 41. Ng1 Kb5 42. Ne2 Ba5 43. Rb2+ Kxa6 44.
+Rb1 Rc7 45. Rb2 Be1 46. f3 Ka5 47. Rc2 Rb7 48. Ra2+ Kb5 49. Rb2+ Bb4 50.
+Ra2 Rc7 51. Ra1 Rc8 52. Ra7 Ba5 53. Rd7 Bb6 54. Rd5+ Bc5 55. Nc1 Ka4 56.
+Rd7 Bb4 57. Ne2 Kb3 58. Rb7 Ra8 59. Rxh7 Ra1 60. Nxd4+ exd4 61. Kxd4 Rd1+
+62. Ke3 Bc5+ 63. Ke2 Rh1 64. h4 Kc4 65. h5 Rh2+ 66. Ke1 Kd3 0-1
+
+[Event "?"]
+[Site "USSR 26/2"]
+[Date "1978"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Balashov,Y"]
+[Result "1-0"]
+
+1. b3 e5 2. Bb2 Nc6 3. c4 Nf6 4. e3 d5 5. cxd5 Nxd5 6. a3 Bd6 7. Qc2 O-O 8.
+Nf3 Qe7 9. Bd3 Kh8 10. Be4 Nb6 11. Bxc6 bxc6 12. d3 Bd7 13. Nbd2 f5 14. e4
+fxe4 15. dxe4 Rf4 16. Qc3 Re8 17. O-O c5 18. Kh1 Bc6 19. Rae1 Nd7 20. Ng1
+Nf6 21. f3 Nh5 22. g4 1-0
+
+[Event "?"]
+[Site "Tilburg 32/3"]
+[Date "1981"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Sosonko,G"]
+[Result "1-0"]
+
+1. c4 e5 2. b3 Nf6 3. Bb2 Nc6 4. e3 Be7 5. a3 O-O 6. Qc2 d5 7. cxd5 Nxd5 8.
+Nf3 Bf6 9. d3 g6 10. Nbd2 Bg7 11. Rc1 g5 12. Nc4 Qe7 13. b4 a6 14. Nfd2 f5
+15. Be2 g4 16. Nb3 Kh8 17. Nca5 Nxa5 18. Nxa5 Qf7 19. O-O c6 20. Nc4 Qe7
+21. Rfe1 Bd7 22. Bf1 Nc7 23. Nb6 Rad8 24. Qc5 Qxc5 25. Rxc5 Ne6 26. Rxe5
+Bxe5 27. Bxe5+ Kg8 28. d4 Be8 29. Nc4 b5 30. Nd6 Bd7 31. Rc1 Ng5 32. Nb7
+Rc8 33. Bd3 Ra8 34. Kf1 Be6 35. Bf4 Nf7 36. Ke2 Bd5 37. Bxf5 Ne5 38. Bxe5
+Rxf5 39. Nd6 Rff8 40. e4 Bc4+ 41. Nxc4 bxc4 42. Rxc4 a5 43. Bd6 Rfe8 44. e5
+axb4 45. Bxb4 1-0
+
+[Event "Tilburg Grandmaster Tournament"]
+[Site "Tilburg, NED"]
+[Date "1982.09.??"]
+[Round "2"]
+[White "Karpov, Anatoly"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nd2 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a3 a4 10. Ba2 h6 11. N5f3 c5 12. c3 Bd7 13. Ne5 cxd4 14. cxd4
+Be7 15. Ngf3 O-O 16. O-O Be8 17. Bd2 Nbd5 18. Rfc1 Qb6 19. Bc4 Bc6 20. Re1
+Nc7 21. Nxc6 bxc6 22. Bf4 Ncd5 23. Be5 Rfd8 24. Rad1 Bd6 25. Rd2 Bxe5 26.
+dxe5 Nd7 27. g3 Nf8 28. Red1 Rd7 29. Qe4 Rb7 30. Rc2 Rab8 31. Rdd2 Ne7 32.
+Kg2 Qa5 33. h4 Rd7 34. Be2 Rd5 35. Rd4 Rxd4 36. Qxd4 Nd5 37. Rxc6 Qa8 38.
+Rc4 Qb7 39. Rc2 Nb6 40. Bb5 Ng6 41. Qd6 Qa8 42. Bc6 1-0
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "15"]
+[White "Tal,M"]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rdg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Tilburg"]
+[Date "1982.??.??"]
+[Round "7"]
+[White "Nunn,John"]
+[Black "Petrosian,Tigran"]
+[Result "1-0"]
+
+1. e4 c6 2. c4 d5 3. exd5 cxd5 4. cxd5 Nf6 5. Nc3 Nxd5 6. Nf3 Nxc3 7. bxc3
+g6 8. d4 Bg7 9. Bd3 Nc6 10. O-O O-O 11. Re1 Bg4 12. Be4 Rc8 13. Bg5 Re8 14.
+Rb1 Qd7 15. h3 Bxf3 16. Bxf3 b6 17. Bg4 f5 18. Be2 h6 19. Bc1 Kh7 20. d5
+1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "?"]
+[Site "Bled"]
+[Date "1961.??.??"]
+[Round "17"]
+[White "Keres, Paul"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. N1e2 e6 7. h4 h6 8.
+Nf4 Bh7 9. c3 Nf6 10. Bd3 Bxd3 11. Nxd3 Bd6 12. Qf3 Nbd7 13. Bf4 Bxf4 14.
+Qxf4 Qb8 15. Qf3 Qd6 16. O-O-O Qd5 17. Qxd5 cxd5 18. f4 Ne4 19. Nxe4 dxe4
+20. Ne5 Rd8 21. h5 1/2-1/2
+
+[Event "?"]
+[Site "Piatgorsky Cup"]
+[Date "1963.??.??"]
+[Round "1"]
+[White "Keres, Paul"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Bc4 e6 7. N1e2 Nf6
+8. Nf4 Bd6 9. Bb3 Nbd7 10. Qf3 Qc7 11. h4 O-O-O 12. h5 Bf5 13. Nxf5 Qa5+
+14. c3 Qxf5 15. Qd3 Qxd3 16. Nxd3 h6 17. Rh4 Rhe8 18. Be3 Nd5 19. O-O-O
+Nxe3 20. fxe3 Nf6 21. Rf1 Re7 22. Nf2 Bg3 23. Rh3 Bd6 24. Bc2 e5 25. Nd3
+exd4 26. exd4 Re2 27. g4 Rde8 28. Bd1 R2e3 29. Rxe3 Rxe3 30. Rf3 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "1"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 Qc7 10. Bd2 e6 11. O-O-O O-O-O 12. c4 Ngf6 13. Kb1 c5 14.
+Bc3 cxd4 15. Nxd4 a6 16. Nf3 Bc5 17. Qe2 Bd6 18. Ne4 Be7 19. Nxf6 Bxf6 20.
+Bxf6 Nxf6 21. Ne5 Rxd1+ 22. Rxd1 Rd8 23. Rxd8+ Kxd8 24. Qd3+ Ke7 25. Qd4 h5
+26. a3 Nd7 27. Nxd7 Qxd7 28. Qc5+ Qd6 29. Qg5+ Ke8 30. Qe3 Qc6 31. Qg3 g6
+32. b3 Qe4+ 33. Kb2 e5 34. Qe3 Qxg2 35. Qxe5+ Kf8 36. Qh8+ Ke7 37. Qe5+
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "3"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bc4 Nf6 9. O-O O-O 10. Qe2 Nc6 11. Be3 Na5 12. Bd3 b6 13. Bg5 Bb7 14.
+Rad1 Rc8 15. Rfe1 h6 16. Bc1 Bb4 17. Bd2 Bxc3 18. bxc3 Qd5 19. Qf1 Qxa2 20.
+Ne5 Nb3 21. Re2 Nxd2 22. Rexd2 Qd5 23. c4 Qd6 24. Qe2 Rfd8 25. h3 Nd7 26.
+Ng4 h5 27. Ne3 g6 28. Ra2 Ra8 29. Qc2 Kg7 30. Be4 Bxe4 31. Qxe4 Nf6 32. Qh4
+Rd7 33. Rad2 Rad8 34. Rd3 a6 35. Qg5 Ne4 36. Qh4 Nf6 37. Rb3 Qc7 38. d5 Qe5
+39. Rxb6 exd5 40. Nxd5 Nxd5 41. cxd5 Rxd5 42. Qxd8 Rxd8 43. Rxd8 Qe1+
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "5"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. g3 Na6 9. Bg2 Qb6 10. Qxb6 axb6 11. Nge2 Nb4 12. O-O Rd8 13. d6 Rxd6 14.
+Bf4 Rd7 15. Rfd1 Nbd5 16. Be5 Bh6 17. a3 e6 18. Nxd5 Nxd5 19. Rd3 Bg5 20.
+Bxd5 exd5 21. h4 Bd8 22. Rc1 Re7 23. Nf4 Be6 24. Rdc3 Bd7 25. Nxd5 Re6 26.
+Bc7 Kg7 27. Bxd8 Rxd8 28. Ne3 b5 29. d5 Rb6 30. Nc2 h6 31. Nb4 g5 32. hxg5
+hxg5 33. Kg2 Rf6 34. Re3 Rh8 35. Nd3 Rd6 36. Ne5 Bh3+ 37. Kf3 Rxd5 38. Rc7
+Be6 39. Rxb7 Rc5 40. Ra7 Bd5+ 41. Kg4 Rc2 42. Kxg5 Rxf2 43. Nd3 Rf3 44.
+Rae7 Rxe3 45. Rxe3 f6+ 46. Kf4 Kf7 47. Nb4 Bc4 48. Rc3 Rh2 49. b3 Be6 50.
+Nd3 Ra2 51. Rc7+ Kg6 52. Nc5 Bf7 53. Rb7 Rxa3 54. Rxb5 Ra1 55. Ne4 Rf1+ 56.
+Ke3 Re1+ 57. Kf3 Rf1+ 58. Ke2 Rb1 59. Nd2 Rg1 60. Kf2 Rc1 61. b4 Rc2 62.
+Ke3 Rc3+ 63. Kf4 Rd3 64. Nf3 Bd5 65. Nh4+ Kf7 66. Rb8 Rd4+ 67. Ke3 Re4+ 68.
+Kf2 Ke7 69. Ng6+ Kd7 70. Nf4 Bc6 71. Nd3 Kc7 72. Rf8 Bb5 73. Nf4 Kd7 74.
+Rf7+ Ke8 75. Rb7 Rxb4 76. Nd5 Rb2+ 77. Ke3 Rb3+ 78. Kf4 Bc4 79. Nxf6+ Kf8
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "9"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bd3 Nc6 9. O-O O-O 10. Re1 Bf6 11. Be4 Nce7 12. Qc2 g6 13. Bh6 Bg7 14.
+Bg5 f6 15. Bd2 Bd7 16. Qb3 Bc6 17. Bxd5 exd5 18. Ne4 Rf7 19. Nc5 Nf5 20. h3
+Bf8 21. Ne6 Qd7 22. Nxf8 Rfxf8 23. Bb4 Rfe8 24. Rxe8+ Rxe8 25. Re1 Rxe1+
+26. Bxe1 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "13"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+h5 Bh7 9. Bd3 Bxd3 10. Qxd3 Qc7 11. Bd2 e6 12. Qe2 Ngf6 13. O-O-O O-O-O 14.
+Ne5 Nxe5 15. dxe5 Nd7 16. f4 Be7 17. Ne4 Nc5 18. Nc3 f6 19. exf6 Bxf6 20.
+Qc4 Qb6 21. b4 Na6 22. Ne4 Nc7 23. Rhe1 Rd4 24. Qb3 Qb5 25. c3 Rxe4 26.
+Rxe4 Qxh5 27. Qc4 Qf5 28. Qe2 h5 29. Be1 Re8 30. g3 a5 31. bxa5 Qxa5 32.
+Qc2 Qf5 33. Ra4 g5 34. fxg5 Bxg5+ 35. Kb1 Qxc2+ 36. Kxc2 e5 37. Re4 Nd5 38.
+Bf2 Nf6 39. Ra4 Kc7 40. Bc5 Nd5 41. Re4 b6 42. Bg1 Bd8 43. Rf1 Nf6 44. Re2
+c5 45. Rf5 Kd6 46. a4 Kd5 47. Kd3 Ng4 48. Rb2 Rh8 49. a5 c4+ 50. Ke2 Ke4
+51. Rf7 bxa5 52. Rb8 a4 53. Rc8 Bf6 54. Rxc4+ Kf5 55. Ra7 a3 56. Rxa3 Rb8
+57. Rb4 Rc8 58. c4 Be7 59. c5 e4 60. Ra7 Bf6 61. Rh7 Kg6 62. Rd7 Kf5 63.
+Rd5+ Be5 64. Rb6 e3 65. Kf3 Nf6 66. Rd3 Rxc5 67. Bxe3 Rc2 68. Rd8 Rc3 69.
+Ke2 Rc2+ 70. Kd1 Rc3 71. Bf2 Ne4 72. Rf8+ Kg5 73. Rb5 Rd3+ 74. Ke2 Rd5 75.
+Rxd5 Nc3+ 76. Kf3 Nxd5 77. Ra8 Kf5 78. Ra5 Ke6 79. Be1 Nf6 80. Rb5 Nd5 81.
+Bd2 Bg7 82. Bc1 Be5 83. Bb2 Bc7 84. Rc5 Bd6 85. Rc1 Ne7 86. Re1+ Kf5 87.
+Ra1 Nc6 88. Ra6 Be5 89. Rxc6 Bxb2 90. Rc5+ Kg6 91. Kf4 1-0
+
+[Event "?"]
+[Site "URS"]
+[Date "1966.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bc4 O-O 9. O-O Nc6 10. Re1 Bf6 11. Ne4 b6 12. a3 Bb7 13. Qd3 Rc8 14.
+Nfg5 Bxg5 15. Bxg5 f6 16. Bd2 Qd7 17. Rad1 Nce7 18. Ba2 Rfe8 19. Bb1 Ng6
+20. Qg3 f5 21. Qd6 Rcd8 22. Qxd7 Rxd7 23. Ng5 Rde7 24. Ba2 h6 25. Nf3 Rc7
+26. Rc1 Rxc1 27. Rxc1 Rc8 28. Rxc8+ Bxc8 29. h4 Bb7 1/2-1/2
+
+[Event "Moskva tt"]
+[Site "?"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nd7 7. Bc4 e6
+8. O-O Ngf6 9. Ng5 h6 10. Nh3 Bd6 11. Nf4 Bxf4 12. Bxf4 Nd5 13. Bc1 Qh4 14.
+Bd3 Bxd3 15. Qxd3 O-O-O 16. Rd1 N7f6 17. c4 Nc7 18. b4 Rd7 19. Bb2 Rhd8 20.
+Qe2 Qg4 21. f3 Qg6 22. a4 h5 23. b5 h4 24. bxc6 bxc6 25. Ne4 Nxe4 26. fxe4
+h3 27. g3 f5 28. e5 c5 29. dxc5 Rxd1+ 30. Rxd1 Rxd1+ 31. Qxd1 Qe8 32. Qd6
+Kb7 33. c6+ Qxc6 34. Qxc6+ Kxc6 35. Bd4 a5 36. Bc3 Na6 37. Bxa5 Nc5 38. Bb4
+Nxa4 39. g4 fxg4 40. Kf2 Nb2 41. Kg3 Nxc4 42. Kxg4 Nxe5+ 43. Kxh3 Kd5 44.
+Kh4 Kc4 45. Bd6 Nf7 46. Bc7 g6 47. Kg4 Kd5 48. h4 Ke4 49. h5 Ne5+ 1/2-1/2
+
+[Event "URS-ch"]
+[Site "?"]
+[Date "1973.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rhg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "2"]
+[White "Petrosian, Tigran V."]
+[Black "Kuzmin,G"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O dxc4 8.
+Bxc4 a6 9. a3 Ba5 10. dxc5 Bxc3 11. bxc3 Qa5 12. a4 Nbd7 13. c6 bxc6 14.
+Qc2 c5 15. e4 Qc7 16. Re1 Ng4 17. Kh1 Re8 18. h3 Ngf6 19. e5 Nd5 20. Ng5
+Nf8 21. f4 Bb7 22. Ne4 Ng6 23. Qf2 Nb6 24. Bf1 Bxe4 25. Rxe4 Qc6 26. Qc2
+Nd5 27. a5 Red8 28. Kh2 Rab8 29. Rea4 Nge7 30. Bd3 Nf5 31. Bxf5 exf5 32.
+Qxf5 Nxc3 33. Rc4 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "10"]
+[White "Petrosian, Tigran V."]
+[Black "Smyslov,V"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 b6 6. Ne2 Nc6 7. O-O cxd4 8.
+exd4 Bb7 9. d5 Ne5 10. Bf4 Nxd3 11. Qxd3 exd5 12. cxd5 O-O 13. a3 Bxc3 14.
+Nxc3 Re8 15. Bd6 Ng4 16. Qg3 Nh6 17. Rfe1 Nf5 18. Qf4 Qf6 19. Be5 Qg6 20.
+Qa4 a6 21. Bf4 b5 22. Qb4 Rec8 23. Qe4 h5 24. Qd3 Rc4 25. Re4 Nh4 26. Bg3
+Rxe4 27. Nxe4 Nxg2 28. Kxg2 h4 29. Rd1 hxg3 30. hxg3 Rc8 31. f3 f5 1/2-1/2
+
+[Event "?"]
+[Site "Tilburg"]
+[Date "1982.??.??"]
+[Round "10"]
+[White "Petrosian,Tigran"]
+[Black "Browne,Walter"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Nc3 Bb4 5. e3 O-O 6. Bd3 Bb7 7. O-O d5 8.
+a3 Bd6 9. cxd5 exd5 10. b4 a6 11. Qb3 Qe7 12. Rb1 Nbd7 13. a4 Ne4 14. Bb2
+Ndf6 15. b5 a5 16. Rbd1 Nxc3 17. Bxc3 Ne4 18. Bb2 Rad8 19. Ne5 Kh8 20. Qc2
+f6 21. Nf3 Bc8 22. Ne1 f5 23. g3 Rf6 24. Nf3 Rdf8 25. Ne5 Rh6 26. f3 Ng5
+27. Qg2 Nh3+ 28. Kh1 g5 29. g4 Qf6 30. Rd2 Rh4 31. Rc2 Qg7 32. gxf5 Bxf5
+33. Bxf5 Rxf5 34. Bc3 Rh6 35. Ng4 Rh5 36. Be1 Qe7 37. Bg3 Rf7 38. Rfc1 Kg7
+39. Rc6 Kf8 40. Bxd6 cxd6 41. Qg3 Rh4 42. Qxd6 1-0
+
+[Event "?"]
+[Site "Lone"]
+[Date "1978.??.??"]
+[Round "?"]
+[White "Portisch, Lajos"]
+[Black "Petrosian, Tigran"]
+[Result "0-1"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 b6 5. Bd3 Bb7 6. Nf3 O-O 7. O-O d5 8.
+a3 Bd6 9. b4 dxc4 10. Bxc4 Nbd7 11. Bb2 a5 12. b5 e5 13. Re1 e4 14. Nd2 Qe7
+15. Be2 Rad8 16. Qc2 Rfe8 17. f3 exf3 18. Bxf3 Bxf3 19. Nxf3 Ne4 20. Nxe4
+Qxe4 21. Qxe4 Rxe4 22. Nd2 Ree8 23. e4 Nc5 24. Nc4 Nxe4 25. Rac1 Bf8 26.
+Ne5 Nd6 27. a4 f6 28. Nf3 Rxe1+ 29. Nxe1 Rd7 30. Nf3 Nf5 31. Kf2 h5 32. Rc2
+g5 33. Rc4 Bd6 34. g3 Kf7 35. Ng1 Ne7 36. Ne2 Nd5 37. Bc1 Kg6 38. Rc2 Kf5
+39. Kf3 g4+ 40. Kf2 Rh7 41. Rd2 h4 42. Kg2 Ke4 43. Rd1 Ne3+ 44. Bxe3 Kxe3
+45. Nc3 h3+ 0-1
+
+[Event "?"]
+[Site "Milano"]
+[Date "1975.??.??"]
+[Round "1"]
+[White "Petrosian, Tigran"]
+[Black "Karpov, Anatoly"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 c5 6. Nf3 d5 7. O-O cxd4 8.
+exd4 dxc4 9. Bxc4 b6 10. Bg5 Bb7 11. Qe2 Bxc3 12. bxc3 Nbd7 13. Bd3 Qc7 14.
+c4 Ng4 15. Be4 Bxe4 16. Qxe4 Ngf6 17. Qd3 h6 18. Bxf6 Nxf6 19. a4 Rac8 20.
+Rfc1 Rfd8 21. h3 e5 22. Nxe5 Qxe5 23. dxe5 Rxd3 24. exf6 Rd4 25. a5 gxf6
+26. axb6 axb6 27. Rab1 Rcxc4 28. Rxc4 Rxc4 29. Rxb6 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1971.??.??"]
+[Round "1"]
+[White "Petrosian, Tigran"]
+[Black "Kortchnoi, Viktor"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 6. a3 Bxc3+ 7. bxc3
+O-O 8. Bg5 c5 9. e3 Nbd7 10. Bd3 Qa5 11. Ne2 b6 12. O-O Ba6 13. Bxa6 Qxa6
+14. Bxf6 Nxf6 15. Nf4 Qc4 16. Qa2 Qxa2 17. Rxa2 Rac8 18. a4 Rfd8 19. Rb1
+Ne4 20. Ne2 Nd6 21. h4 Nc4 22. Nf4 Kf8 23. g4 g6 24. Kg2 h6 25. Rd1 g5 26.
+hxg5 hxg5 27. Ne2 Nd6 28. Ng3 cxd4 29. Rxd4 Ne4 30. Nxe4 dxe4 31. Rxe4 Rxc3
+32. a5 Rdc8 33. axb6 axb6 34. Rb2 R3c4 35. Rxc4 Rxc4 1/2-1/2
+
+[Event "?"]
+[Site "Wch"]
+[Date "1963.??.??"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Botvinnik, Mikhail"]
+[Result "0-1"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 6. Bg5 h6 7. Bxf6 Qxf6
+8. a3 Bxc3+ 9. Qxc3 c6 10. e3 O-O 11. Ne2 Re8 12. Ng3 g6 13. f3 h5 14. Be2
+Nd7 15. Kf2 h4 16. Nf1 Nf8 17. Nd2 Re7 18. Rhe1 Bf5 19. h3 Rae8 20. Nf1 Ne6
+21. Qd2 Ng7 22. Rad1 Nh5 23. Rc1 Qd6 24. Rc3 Ng3 25. Kg1 Nh5 26. Bd1 Re6
+27. Qf2 Qe7 28. Bb3 g5 29. Bd1 Bg6 30. g4 hxg3 31. Nxg3 Nf4 32. Qh2 c5 33.
+Qd2 c4 34. Ba4 b5 35. Bc2 Nxh3+ 36. Kf1 Qf6 37. Kg2 Nf4+ 38. exf4 Rxe1 39.
+fxg5 Qe6 40. f4 Re2+ 0-1
+
+[Event "?"]
+[Site "Curacao ct"]
+[Date "1962.??.??"]
+[Round "3"]
+[White "Petrosian, Tigran V."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nf3 b6 4. Nc3 Bb4 5. e3 c5 6. Bd3 d5 7. dxc5 bxc5 8.
+O-O O-O 9. Ne2 Bb7 10. b3 Nbd7 11. Bb2 Qe7 12. Ng3 g6 13. cxd5 exd5 14. a3
+Ba5 15. b4 cxb4 16. Qa4 Bb6 17. axb4 Ng4 18. Rfe1 Nde5 19. Nxe5 Nxe5 20.
+Rad1 Nxd3 21. Rxd3 Rfc8 22. b5 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "20"]
+[White "Petrosian, Tigran V."]
+[Black "Spassky, Boris"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 c5 6. Nf3 d5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 dxc4 10. Bxc4 Qc7 11. Bd3 e5 12. Qc2 Bg4 13. Nxe5 Nxe5 14.
+dxe5 Qxe5 15. f3 Bd7 16. a4 Rfe8 17. e4 c4 18. Be2 Be6 19. Be3 Qc7 20. Rab1
+Nd7 21. Rb5 b6 22. Rfb1 Qc6 23. Bd4 f6 24. Qa2 Kh8 25. Bf1 h6 26. h3 Rab8
+27. a5 Rb7 28. axb6 axb6 29. Qf2 Ra8 30. Qb2 Rba7 31. Bxb6 Ra2 32. Qb4 Rc2
+33. Bf2 Qc7 34. Qe7 Bxh3 35. gxh3 Rxf2 36. Kxf2 Qh2+ 37. Bg2 Ne5 38. Rb8+
+Rxb8 39. Rxb8+ Kh7 40. Rd8 Ng6 41. Qe6 1-0
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1969.??.??"]
+[Round "10"]
+[White "Petrosian, Tigran V."]
+[Black "Spassky, Boris"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 b6 6. Ne2 d5 7. O-O dxc4 8.
+Bxc4 Bb7 9. f3 c5 10. a3 cxd4 11. axb4 dxc3 12. Nxc3 Nc6 13. b5 Ne5 14. Be2
+Qc7 15. e4 Rfd8 16. Qe1 Qc5+ 17. Qf2 Qe7 18. Ra3 Ne8 19. Bf4 Ng6 20. Be3
+Nd6 21. Rfa1 Nc8 22. Bf1 f5 23. exf5 exf5 24. Ra4 Re8 25. Bd2 Qc5 26. Qxc5
+bxc5 27. Rc4 Re5 28. Na4 a6 29. Nxc5 axb5 30. Nxb7 Rxa1 31. Rxc8+ Kf7 32.
+Nd8+ Ke7 33. Nc6+ Kd7 34. Nxe5+ Kxc8 35. Nxg6 hxg6 36. Bc3 Rb1 37. Kf2 b4
+38. Bxg7 1-0
+
+[Event "?"]
+[Site "Milano"]
+[Date "1975.??.??"]
+[Round "2"]
+[White "Ljubojevic, Ljubomir"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. a3 Be7 6. Nf3 O-O 7. e3 b6 8.
+cxd5 exd5 9. b4 Re8 10. Bd3 Bb7 11. O-O Bd6 12. Bb2 a6 13. Ne5 c5 14. bxc5
+bxc5 15. Rab1 Qc7 16. h3 c4 1/2-1/2
+
+[Event "32nd ol"]
+[Site "Yerevan ARM"]
+[Date "1996.09.17"]
+[Round "02"]
+[White "Gostisa,L"]
+[Black "Petrosian,A"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. Nf3 e6 3. g3 d5 4. Bg2 Nbd7 5. O-O b5 6. b3 Bb7 7. c4 bxc4 8.
+bxc4 dxc4 9. Qa4 c5 10. Ba3 Qc7 11. Qxc4 Rc8 12. Rc1 Qb8 1/2-1/2
+
+[Event "?"]
+[Site "Belgrade"]
+[Date "1954.??.??"]
+[Round "?"]
+[White "Janosevic"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 e6 5. Nc3 Nf6 6. Bg5 Be7 7. Nf3 O-O 8.
+Rc1 a6 9. cxd5 exd5 10. Be2 Nc6 11. Ne5 Na5 12. O-O h6 13. Bh4 Bf5 14. Bf3
+Be6 15. Re1 Nc6 16. Ng6 fxg6 17. Rxe6 g5 18. Bg3 Qd7 19. Re1 Rae8 20. Be5
+Kh8 21. Qb3 g4 22. Bxd5 Nxd5 23. Nxd5 Bg5 24. Rcd1 Na5 25. Nb6 Qd8 26. Qa4
+Qxb6 27. Bxg7+ Kxg7 28. Rxe8 Nc6 29. Rxf8 Kxf8 30. d5 Ne5 31. d6 Qxb2 32.
+d7 Nf7 33. Qxg4 Qxa2 34. Qb4+ Be7 35. d8=Q+ Nxd8 36. Rxd8+ Kf7 37. Qf4+ Kg7
+38. Qg4+ Kf6 39. Rd1 b5 40. h4 Qe6 41. Qh5 Kg7 42. Rd3 Bd6 43. Qd1 Bc5 44.
+Rg3+ Kf6 45. Qa1+ Kf5 46. Qb1+ Ke5 47. Rg6 Qf7 48. Qe1+ Kd5 49. Rxa6 Qf4
+50. Qd1+ Kc4 51. Ra2 Bd4 52. Qe2+ Kb4 53. Qe1+ Kb3 54. Qb1+ Kc4 55. Rc2+
+Bc3 56. Re2 Bd4 57. Qc2+ Kd5 58. Qb3+ Kc5 59. g3 Qf6 60. Rc2+ Kb6 61. Kg2
+Qf5 62. Re2 Kc5 63. Qc2+ Qxc2 64. Rxc2+ Kd5 65. f4 b4 66. Kf3 b3 67. Rc1 b2
+68. Rd1 h5 69. g4 hxg4+ 70. Kxg4 Ke4 71. h5 Be3 72. Rb1 Bc1 73. h6 Bxf4 74.
+Re1+ 1-0
diff --git a/test/infiles/roster.txt b/test/infiles/roster.txt
new file mode 100644 (file)
index 0000000..f708dbc
--- /dev/null
@@ -0,0 +1,8 @@
+% Output the tags of the seven tag roster alphabetically.
+Black
+Date
+Event
+Result
+Round
+Site
+White
diff --git a/test/infiles/taglist.txt b/test/infiles/taglist.txt
new file mode 100644 (file)
index 0000000..6041891
--- /dev/null
@@ -0,0 +1,3 @@
+White "Fischer"
+Black "Petrosian"
+Date "1970"
diff --git a/test/infiles/test-7.pgn b/test/infiles/test-7.pgn
new file mode 100644 (file)
index 0000000..70b1099
--- /dev/null
@@ -0,0 +1,27 @@
+[Event "?"]
+[Site "Biel SKA (5)"]
+[Date "1995.??.??"]
+[Round "?"]
+[White "Adianto,U"]
+[Black "Gelfand,B"]
+[Result "1-0"]
+[WhiteElo "2590"]
+[BlackElo "2685"]
+[ECO "E63"]
+[PlyCount "166"]
+
+1. d4 Nf6 2. c4 g6 3. g3 Bg7 4. Bg2 O-O 5. Nf3 d6 6. O-O Nc6 7. Nc3 a6 8.
+h3 Bd7 9. e4 e5 10. d5 Nd4 11. Nxd4 exd4 12. Qxd4 Qc8 13. h4 b5 14. cxb5
+axb5 15. Qb4 Ng4 16. Bf4 Re8 17. Rac1 Qb8 18. Bh3 Qb6 19. Bxg4 Bxg4 20.
+Qxb5 Reb8 21. Qxb6 Rxb6 22. b3 c5 23. dxc6 Rxc6 24. Nd5 Rxc1 25. Rxc1 Rxa2
+26. Kg2 Bd4 27. Be3 Bxe3 28. Nxe3 Be6 29. Rb1 Bd7 30. g4 Bb5 31. Kg3 Bd3
+32. Rd1 Bxe4 33. Rxd6 Rb2 34. Rb6 Kg7 35. g5 h6 36. b4 hxg5 37. hxg5 Kf8
+38. f3 Bd3 39. Kf4 Ke8 40. Ke5 Re2 41. Kd4 Bb1 42. b5 Rf2 43. Rb8+ Kd7 44.
+Rb7+ Ke6 45. Rb6+ Kd7 46. Rf6 Rd2+ 47. Kc5 Ba2 48. Nc4 Rg2 49. Rxf7+ Ke6
+50. Rf4 Rxg5+ 51. Kc6 Bb3 52. Re4+ Kf6 53. Ne3 Be6 54. b6 Bc8 55. Nd5+ Kg7
+56. Nb4 Rg1 57. Rc4 Re1 58. Kc7 Re8 59. Re4 Rf8 60. Nc6 Ba6 61. Re3 Kh6 62.
+Ra3 Rf7+ 63. Kd6 Rf6+ 64. Ke7 Rxc6 65. Rxa6 Kh7 66. Kd8 Kh6 67. Ke7 Kh7 68.
+Kd7 Rf6 69. b7 Rxa6 70. b8=Q Ra5 71. Ke6 Rf5 72. Qg3 Kg7 73. Qg4 Rf6+ 74.
+Ke5 Rf7 75. Ke4 Kh7 76. Qc8 Kg7 77. Ke3 Rf8 78. Qc3+ Kh7 79. Kf2 Rf5 80.
+Kg3 Rg5+ 81. Kf4 Rf5+ 82. Kg4 Rf7 83. Qe5 1-0
+
diff --git a/test/infiles/test-C.pgn b/test/infiles/test-C.pgn
new file mode 100644 (file)
index 0000000..3777b34
--- /dev/null
@@ -0,0 +1,18 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 {Time control} 1/2-1/2
+
diff --git a/test/infiles/test-F.pgn b/test/infiles/test-F.pgn
new file mode 100644 (file)
index 0000000..3777b34
--- /dev/null
@@ -0,0 +1,18 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 {Time control} 1/2-1/2
+
diff --git a/test/infiles/test-L1.pgn b/test/infiles/test-L1.pgn
new file mode 100644 (file)
index 0000000..dddfed0
--- /dev/null
@@ -0,0 +1,9 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 Qh4# 0-1
diff --git a/test/infiles/test-L2.pgn b/test/infiles/test-L2.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-N.pgn b/test/infiles/test-N.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-P.pgn b/test/infiles/test-P.pgn
new file mode 100644 (file)
index 0000000..0582f62
--- /dev/null
@@ -0,0 +1,188 @@
+[Event "?"]
+[Site "Wch"]
+[Date "1960.??.??"]
+[Round "?"]
+[White "Botvinnik, Mikhail"]
+[Black "Tal, M."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 Ne4 6. Qc2 f5 7. Nh3 O-O
+8. f3 Nf6 9. c5 b6 10. cxb6 cxb6 11. e3 Qc7 12. Bd2 Ne8 13. c4 Ba6 14. Rc1
+Nd6 15. Qa4 Qc6 16. Qxc6 Nxc6 17. Bb4 Nxb4 18. axb4 Bxc4 19. Bxc4 Rfc8 20.
+Bxe6+ dxe6 21. Ke2 Kf7 22. Nf4 a5 23. bxa5 bxa5 24. Kd3 a4 25. Rxc8 Rxc8
+26. Ra1 Nc4 27. Rb1 a3 28. Rb7+ Kf6 29. Ra7 g5 30. Nh5+ Kg6 31. g4 Nb2+ 32.
+Kd2 Nc4+ 33. Kd3 Nb2+ 34. Kd2 Nc4+ 35. Ke2 Rc6 36. h3 e5 37. dxe5 fxg4 38.
+hxg4 Nxe5 39. Rxa3 Rc2+ 40. Kf1 Kf7 41. e4 Rd2 42. Ke1 Rg2 43. Rb3 Ke7 44.
+Ng7 Nxf3+ 45. Rxf3 Rxg4 46. Nf5+ Ke6 47. Ng3 h5 48. Nxh5 Rxe4+ 49. Kf2 Ke5
+50. Kg3 Rh4 51. Ng7 Rf4 52. Ra3 Rd4 53. Ra6 Rd6 54. Ra7 Rd4 55. Rf7 Rf4 56.
+Re7+ Kf6 57. Ra7 Re4 58. Nh5+ Kg6 59. Kf3 Rb4 60. Ng3 Rf4+ 61. Ke3 Rf7 62.
+Ra5 Rf6 63. Ne4 Rf5 64. Ra6+ Kg7 65. Ng3 Re5+ 66. Kd4 Rb5 67. Ke4 Kf7 68.
+Nf5 Rb4+ 69. Nd4 Rb1 70. Nf3 Rb4+ 71. Nd4 Rb1 72. Nc6 Kg6 73. Ne5+ Kh5 74.
+Ra5 Re1+ 75. Kf3 Rf1+ 76. Kg3 Rf5 1/2-1/2
+
+[Event "?"]
+[Site "Wch"]
+[Date "1960.??.??"]
+[Round "?"]
+[White "Botvinnik, Mikhail"]
+[Black "Tal, M."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 Ne4 6. Qc2 f5 7. Nh3 d6
+8. f3 Nf6 9. e4 fxe4 10. fxe4 e5 11. Nf2 O-O 12. Be2 c5 13. dxc5 dxc5 14.
+O-O Nc6 15. Bg5 Qe8 16. Nd1 Qg6 17. Bxf6 Rxf6 18. Ne3 Rxf1+ 19. Rxf1 Be6
+20. Qd3 Rd8 21. Nd5 Rf8 22. Nc7 Rxf1+ 23. Bxf1 Qf7 24. Qd6 Bc8 25. Na6 Qf4
+26. Qd5+ Kh8 27. Qxc5 Be6 28. Nc7 Bg8 29. Qf2 Qxe4 30. Ne8 Qg6 31. Qf8 e4
+32. Nd6 Ne5 33. c5 Nd3 34. Nf5 Ne5 35. Ne7 Qf7 36. Qxf7 Bxf7 37. Kf2 Bc4
+38. Bxc4 Nxc4 39. c6 bxc6 40. Nxc6 a5 41. a4 1/2-1/2
+
+[Event "?"]
+[Site "Wch"]
+[Date "1960.??.??"]
+[Round "?"]
+[White "Botvinnik, Mikhail"]
+[Black "Tal, M."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 Ne4 6. e3 f5 7. Qh5+ g6
+8. Qh6 d6 9. f3 Nf6 10. e4 e5 11. Bg5 Qe7 12. Bd3 Rf8 13. Ne2 Qf7 14. Qh4
+fxe4 15. fxe4 Ng4 16. h3 Qf2+ 17. Kd2 Qxh4 18. Bxh4 Nf2 19. Rhf1 Nxd3 20.
+Rxf8+ Kxf8 21. Kxd3 Be6 22. Ng3 Nd7 23. Nf1 a6 24. Bf2 Kg7 25. Nd2 Rf8 26.
+Be3 b6 27. Rb1 Nf6 1/2-1/2
+
+[Event "?"]
+[Site "Wch"]
+[Date "1960.??.??"]
+[Round "?"]
+[White "Botvinnik, Mikhail"]
+[Black "Tal, M."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 O-O 6. f3 d5 7. cxd5 exd5
+8. e3 Bf5 9. Ne2 Nbd7 10. Ng3 Bg6 11. Bd3 c5 12. O-O Re8 13. Re1 Qc7 14.
+Bxg6 hxg6 15. e4 cxd4 16. cxd4 Rac8 17. Bg5 Qc2 18. Bxf6 Qxd1 19. Rexd1
+Nxf6 20. e5 Nh5 21. Ne2 Rc2 22. Kf1 g5 23. Rdc1 Rec8 24. g3 f6 25. Rxc2
+Rxc2 26. Rb1 b6 27. Rb5 fxe5 28. dxe5 Rc5 29. Nd4 Kf7 30. Ke2 g6 31. Kd3
+Ng7 32. Rb1 Ra5 33. Nc2 Ne6 34. Rb4 Rc5 35. h4 gxh4 36. Rxh4 d4 37. Nxd4
+Rxe5 38. Nxe6 Kxe6 39. a4 Rg5 40. Re4+ Kf6 1/2-1/2
+
+[Event "?"]
+[Site "Wch"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Botvinnik, Mikhail"]
+[Black "Tal, M."]
+[Result "1-0"]
+
+1. c4 Nf6 2. Nc3 e6 3. d4 Bb4 4. a3 Bxc3+ 5. bxc3 b6 6. f3 Ba6 7. e4 d5 8.
+cxd5 Bxf1 9. Kxf1 exd5 10. Bg5 h6 11. Qa4+ c6 12. Bh4 dxe4 13. Re1 g5 14.
+Bf2 Qe7 15. Ne2 b5 16. Qc2 Qxa3 17. h4 gxh4 18. Bxh4 Nbd7 19. Ng3 O-O-O 20.
+Nxe4 Rhe8 21. Kf2 Nxe4+ 22. fxe4 f6 23. Ra1 Qe7 24. Rxa7 Qxe4 25. Qxe4 Rxe4
+26. Ra8+ Nb8 27. Bg3 Kb7 28. Rha1 Rc8 29. R8a7+ Kb6 30. Bxb8 b4 31. Bd6
+bxc3 32. Bc5+ Kb5 33. R1a4 1-0
+
+[Event "?"]
+[Site "Wch"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Botvinnik, Mikhail"]
+[Black "Tal, M."]
+[Result "1-0"]
+
+1. c4 Nf6 2. Nc3 e6 3. d4 Bb4 4. e3 O-O 5. Bd3 d5 6. a3 dxc4 7. Bxc4 Bd6 8.
+Nf3 Nc6 9. Nb5 e5 10. Nxd6 Qxd6 11. dxe5 Qxd1+ 12. Kxd1 Ng4 13. Ke2 Ncxe5
+14. Bd5 c6 15. Be4 Be6 16. Nd2 Rad8 17. h3 Nf6 18. Bc2 Rd7 19. b3 Rfd8 20.
+Rd1 Nd3 21. Bxd3 Rxd3 22. Bb2 R3d7 23. Bxf6 gxf6 24. b4 Bf5 25. Nb3 Bd3+
+26. Ke1 b6 27. Rac1 Be4 28. f3 Rxd1+ 29. Rxd1 Rxd1+ 30. Kxd1 Bd5 31. Nd4 c5
+32. bxc5 bxc5 33. Nb5 a6 34. Nc7 Bc4 35. Ne8 f5 36. h4 Kf8 37. Nd6 Bf1 38.
+g3 Ke7 39. Nxf5+ Ke6 40. e4 Ke5 41. Kd2 1-0
+
+[Event "?"]
+[Site "Wch"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Botvinnik, Mikhail"]
+[Black "Tal, M."]
+[Result "1-0"]
+
+1. c4 Nf6 2. Nc3 e6 3. d4 Bb4 4. e3 O-O 5. Bd3 d5 6. a3 dxc4 7. Bxc4 Bd6 8.
+Nf3 Nc6 9. b4 e5 10. Bb2 Bg4 11. d5 Ne7 12. h3 Bd7 13. Ng5 Ng6 14. Ne6 fxe6
+15. dxe6 Kh8 16. exd7 Qxd7 17. O-O Qf5 18. Nd5 Ng8 19. Qg4 Qc2 20. Qe2 Qf5
+21. Qg4 Qc2 22. Qe2 Qf5 23. e4 Qd7 24. Rad1 Rad8 25. Qg4 Qe8 26. g3 Nh6 27.
+Qh5 Ng8 28. Qe2 N6e7 29. Ne3 Nh6 30. Ng4 Nxg4 31. hxg4 Nc6 32. Kg2 Be7 33.
+Bd5 Nd4 34. Bxd4 exd4 35. Bc4 c5 36. b5 Bf6 37. f4 d3 38. Rxd3 Rxd3 39.
+Bxd3 Bd4 40. e5 g6 41. Rh1 Kg7 42. Qe4 b6 43. Bc4 1-0
+
+[Event "WM Moskau"]
+[Site "?"]
+[Date "1960.??.??"]
+[Round "?"]
+[White "Botvinnik"]
+[Black "Tal, Mikhail N."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 Ne4 6. Nh3 c5 7. e3 Qa5
+8. Bd2 cxd4 9. cxd4 Nxd2 10. Qxd2 Qxd2+ 11. Kxd2 b6 12. Bd3 Ba6 13. Rhc1
+Nc6 14. Rab1 Ke7 15. c5 Bxd3 16. Kxd3 Rab8 17. Rb5 bxc5 18. Rcxc5 a6 19.
+Rxb8 Rxb8 20. Kc2 Rc8 21. Nf4 d6 22. Rc3 g5 1/2-1/2
+
+[Event "WM Moskau"]
+[Site "?"]
+[Date "1960.??.??"]
+[Round "?"]
+[White "Botvinnik"]
+[Black "Tal, Mikhail N."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 Ne4 6. Qc2 f5 7. Nh3 O-O
+8. f3 Nf6 9. c5 b6 10. cxb6 cxb6 11. e3 Qc7 12. Bd2 Ne8 13. c4 Ba6 14. Rc1
+Nd6 15. Qa4 Qc6 16. Qxc6 Nxc6 17. Bb4 Nxb4 18. axb4 Bxc4 19. Bxc4 Rfc8 20.
+Bxe6+ dxe6 21. Kd2 Kf7 22. Nf4 a5 23. bxa5 bxa5 24. Kd3 a4 25. Rxc8 Rxc8
+26. Ra1 Nc4 27. Rb1 a3 28. Rb7+ Kf6 29. Ra7 g5 30. Nh5+ Kg6 31. g4 Nb2+ 32.
+Kd2 Nc4+ 33. Kd3 Nb2+ 34. Kd2 Nc4+ 35. Ke2 Rc6 36. h3 e5 37. dxe5 fxg4 38.
+hxg4 Nxe5 39. Rxa3 Rc2+ 40. Kf1 Kf7 41. e4 Rd2 42. Ke1 Rg2 43. Rb3 Ke7 44.
+Ng7 Nxf3+ 45. Rxf3 Rxg4 46. Nf5+ Ke6 47. Ng3 h5 48. Nxh5 Rxe4+ 49. Kf2 Ke5
+50. Kg3 Rh4 51. Ng7 Rf4 52. Ra3 Rd4 53. Ra6 Rd6 54. Ra7 Rd4 55. Rf7 Rf4 56.
+Re7+ Kf6 57. Ra7 Re4 58. Nh5+ Kg6 59. Kf3 Rb4 60. Ng3 Rf4+ 61. Ke3 Rf7 62.
+Ra5 Rf6 63. Ne4 Rf5 64. Ra6+ Kg7 65. Ng3 Re5+ 66. Kd4 Rb5 67. Ke4 Kf7 68.
+Nf5 Rb4+ 69. Nd4 Rb1 70. Nf3 Rb4+ 71. Nd4 Rb1 72. Nc6 Kg6 73. Ne5+ Kh5 74.
+Ra5 Re1+ 75. Kf3 Rf1+ 76. Kg3 Rf4 1/2-1/2
+
+[Event "WM Moskau"]
+[Site "?"]
+[Date "1960.??.??"]
+[Round "?"]
+[White "Botvinnik"]
+[Black "Tal, Mikhail N."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. a3 Bxc3+ 5. bxc3 Ne4 6. Qc2 f5 7. Nh3 d6
+8. f3 Nf6 9. e4 fxe4 10. fxe4 e5 11. Nf2 O-O 12. Be2 c5 13. dxe5 dxe5 14.
+O-O Nc6 15. Bg5 Qe8 16. Nd1 Qg6 17. Bxf6 Rxf6 18. Ne3 Rxf1+ 19. Rxf1 Be6
+20. Qd3 Rd8 21. Nd5 Rf8 22. Nc7 Rxf1+ 23. Bxf1 Qf7 24. Qd6 Bc8 25. Na6 Qf4
+26. Qd5+ Kh8 27. Qxc5 Be6 28. Nc7 Bg8 29. Qf2 Qxe4 30. Ne8 Qg6 31. Qf8 e4
+32. Nd6 Ne5 33. c5 Nd3 34. Nf5 Ne5 35. Ne7 Qf7 36. Qxf7 Bxf7 37. Kf2 Bc4
+38. Bxc4 Nxc4 39. c6 bxc6 40. Nxc6 a5 41. a4 1/2-1/2
+
+[Event "WM Moskau"]
+[Site "?"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Botvinnik"]
+[Black "Tal, Mikhail N."]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. Nc3 e6 3. d4 Bb4 4. e3 O-O 5. Bd3 d5 6. a3 dxc4 7. Bxc4 Bd6 8.
+Nf3 Nc6 9. b4 e5 10. Bb2 Bg4 11. dxe5 Nxe5 12. Be2 Qe7 13. Nb5 Rfd8 14. Qc2
+a6 15. Nxd6 cxd6 16. Qd1 Rac8 17. O-O Ne4 18. Nd4 Bxe2 19. Qxe2 Nc4 20.
+Rac1 d5 21. Qg4 Qd7 22. Qxd7 Rxd7 23. Rc2 Ned6 24. Rd1 Rdd8 25. Nb3 Nxb2
+26. Rxb2 Nc4 27. Ra2 b6 28. Kf1 f6 29. a4 Ne5 30. b5 Rc3 31. Nd4 Ra8 32.
+Rda1 a5 33. Rd1 Rac8 34. Nf5 R8c7 35. Rxd5 Kf7 36. Rd1 Ke6 37. Nd4+ Kf7 38.
+Ke2 R7c4 39. h3 Rb4 40. Nc2 Rbc4 41. Rd2 Ke7 42. Nd4 g6 43. Rd1 Nd7 44.
+Nc6+ Ke8 45. Rd6 Rc2+ 46. Rxc2 Rxc2+ 47. Kf3 Ra2 48. Re6+ Kf8 49. Rd6 Ke8
+50. Re6+ Kf8 51. Kg3 Rxa4 52. Re7 Nc5 53. Rxh7 Ne4+ 54. Kh2 Nd6 55. Rh8+
+Kf7 56. Rb8 Nc4 57. Rc8 Nd2 58. g4 Ra2 59. Rb8 Ne4 60. Rxb6 Rxf2+ 61. Kg1
+Rb2 62. Nxa5 Nd2 63. Nc6 Nc4 64. Rb7+ Ke6 65. h4 Kd5 66. Rd7+ Kc5 67. Rd3
+Kxb5 68. Nd4+ Kc5 69. Nf3 Re2 70. h5 gxh5 71. gxh5 Nxe3 72. h6 Rg2+ 73. Kh1
+Rg3 1/2-1/2
+
diff --git a/test/infiles/test-R.pgn b/test/infiles/test-R.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-S.pgn b/test/infiles/test-S.pgn
new file mode 100644 (file)
index 0000000..cdcf62b
--- /dev/null
@@ -0,0 +1,49 @@
+[Event "?"]
+[Site "Zuerich"]
+[Date "1953.??.??"]
+[Round "?"]
+[White "Reshevsky, Samuel"]
+[Black "Petrosjan, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 d5 6. Nf3 c5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 b6 10. cxd5 exd5 11. Bb2 c4 12. Bc2 Bg4 13. Qe1 Ne4 14. Nd2
+Nxd2 15. Qxd2 Bh5 16. f3 Bg6 17. e4 Qd7 18. Rae1 dxe4 19. fxe4 Rfe8 20. Qf4
+b5 21. Bd1 Re7 22. Bg4 Qe8 23. e5 a5 24. Re3 Rd8 25. Rfe1 Re6 26. a4 Ne7
+27. Bxe6 fxe6 28. Qf1 Nd5 29. Rf3 Bd3 30. Rxd3 cxd3 31. Qxd3 b4 32. cxb4
+axb4 33. a5 Ra8 34. Ra1 Qc6 35. Bc1 Qc7 36. a6 Qb6 37. Bd2 b3 38. Qc4 h6
+39. h3 b2 40. Rb1 Kh8 41. Be1 1/2-1/2
+
+[Event "?"]
+[Site "Zuerich"]
+[Date "1953.??.??"]
+[Round "?"]
+[White "Smyslov, V."]
+[Black "Petrosjan, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 d5 6. Nf3 c5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 b6 10. cxd5 exd5 11. Bb2 c4 12. Bc2 Bg4 13. Qe1 Ne4 14. Nd2
+Nxd2 15. Qxd2 Bh5 16. f3 Bg6 17. e4 Qd7 18. Rae1 f5 19. exd5 Qxd5 20. a4
+Rfe8 21. Qg5 Qf7 22. Ba3 h6 23. Qg3 Rxe1 24. Rxe1 Re8 25. Rxe8+ Qxe8 26.
+Kf2 Na5 27. Qf4 Nb3 28. Bxf5 Bxf5 29. Qxf5 Qxa4 30. Qf8+ Kh7 31. Qf5+ Kg8
+32. Qe6+ Kh7 33. Qe4+ Kg8 34. Qa8+ Kh7 35. Qe4+ Kg8 36. Qd5+ Kh7 37. Be7
+Nc1 38. Qf5+ Kg8 39. Qf8+ Kh7 40. Qf5+ Kg8 41. d5 Qa2+ 42. Kg3 Qd2 43. d6
+Qe1+ 44. Kg4 Nd3 45. Qd5+ Kh7 46. d7 Qe5 47. Qxd3+ cxd3 48. d8=Q 1/2-1/2
+
+[Event "?"]
+[Site "Zuerich"]
+[Date "1953.??.??"]
+[Round "?"]
+[White "Taimanov, M."]
+[Black "Petrosjan, Tigran V."]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 b6 10. cxd5 exd5 11. Ne5 Qc7 12. Nxc6 Qxc6 13. f3 Be6 14.
+Qe1 Nd7 15. e4 c4 16. Bc2 f5 17. e5 Rf7 18. a4 a5 19. f4 b5 20. axb5 Qxb5
+21. Ba3 Nb6 22. Qh4 Qe8 23. Rf3 Nc8 24. Ba4 Rd7 25. Rb1 Qd8 26. Bxd7 Qxd7
+27. Rg3 Na7 28. Be7 Bf7 29. Qg5 Bg6 30. h4 Nc6 31. Ba3 Nd8 32. h5 Ne6 33.
+Qh4 Bf7 34. h6 g6 35. Qf6 Qd8 36. Be7 Qc7 37. Rxg6+ hxg6 38. h7+ Kxh7 39.
+Qxf7+ Ng7 40. Kf2 1-0
+
diff --git a/test/infiles/test-Ta.pgn b/test/infiles/test-Ta.pgn
new file mode 100644 (file)
index 0000000..02f0677
--- /dev/null
@@ -0,0 +1,20 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+[Annotator "Barnes, David J."]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-V.pgn b/test/infiles/test-V.pgn
new file mode 100644 (file)
index 0000000..3777b34
--- /dev/null
@@ -0,0 +1,18 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 {Time control} 1/2-1/2
+
diff --git a/test/infiles/test-W.pgn b/test/infiles/test-W.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-a.txt b/test/infiles/test-a.txt
new file mode 100644 (file)
index 0000000..740554d
--- /dev/null
@@ -0,0 +1,6 @@
+b2b3 e7e5 c1b2 d7d6 d2d4 e5d4 d1d4 b8c6 d4d2 g8f6 b1c3 c8e6 e2e4 d6d5 e4d5
+e6d5 d2e3+ f8e7 g1f3 e8g8 f1e2 f8e8 e1c1 e7b4 e3d3 b4c3 b2c3 d8e7 h1e1 f6e4
+c3b2 a8d8 d3e3 b7b6 e2b5 e7e6 f3d4 c6d4 d1d4 c7c5 d4e4 d5e4 b5e8 d8e8 f2f3
+e4d5 e3e6 e8e6 e1e6 d5e6 c1d2 g8f8 b2e5 b6b5 e5b8 a7a6 b8a7 c5c4 d2c3 f8e7
+c3d4 e7d6 a7c5+ d6d7 c5a7 d7d6 a7c5+ d6d7 d4c3 g7g6 c5d4 f7f5 1/2-1/2
+
diff --git a/test/infiles/test-addhashcode.pgn b/test/infiles/test-addhashcode.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-checkmate.pgn b/test/infiles/test-checkmate.pgn
new file mode 100644 (file)
index 0000000..8d8cba2
--- /dev/null
@@ -0,0 +1,29 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 Qh4# 0-1
+
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-e.pgn b/test/infiles/test-e.pgn
new file mode 100644 (file)
index 0000000..46a50b7
--- /dev/null
@@ -0,0 +1,93 @@
+[Event "?"]
+[Site "Sarajevo"]
+[Date "1972"]
+[Round "?"]
+[White "Petrosian,T"]
+[Black "Hort"]
+[Result "1-0"]
+
+1. Nf3 c5 2. b3 d5 3. e3 Nf6 4. Bb2 e6 5. c4 Nc6 6. cxd5 exd5 7. Be2 Be7 8.
+O-O O-O 9. d4 Bg4 10. dxc5 Bxc5 11. Nc3 Rc8 12. Rc1 Be7 13. Nd4 Bxe2 14.
+Ncxe2 Qd7 15. Nf4 Rfd8 16. Qd3 Ne4 17. Nxc6 bxc6 18. Rc2 Bf8 19. Rfc1 Qb7
+20. Qe2 Re8 21. Qg4 g6 22. Qd1 Bd6 23. Nxd5 Rcd8 24. Rxc6 Qb8 25. f4 Re6
+26. Qd4 1-0
+
+[Event "?"]
+[Site "Buenos Aires m"]
+[Date "1971"]
+[Round "6"]
+[White "Petrosian,T"]
+[Black "Fischer,R"]
+[Result "0-1"]
+
+1. Nf3 c5 2. b3 d5 3. Bb2 f6 4. c4 d4 5. d3 e5 6. e3 Ne7 7. Be2 Nec6 8.
+Nbd2 Be7 9. O-O O-O 10. e4 a6 11. Ne1 b5 12. Bg4 Bxg4 13. Qxg4 Qc8 14. Qe2
+Nd7 15. Nc2 Rb8 16. Rfc1 Qe8 17. Ba3 Bd6 18. Ne1 g6 19. cxb5 axb5 20. Bb2
+Nb6 21. Nef3 Ra8 22. a3 Na5 23. Qd1 Qf7 24. a4 bxa4 25. bxa4 c4 26. dxc4
+Nbxc4 27. Nxc4 Nxc4 28. Qe2 Nxb2 29. Qxb2 Rfb8 30. Qa2 Bb4 31. Qxf7+ Kxf7
+32. Rc7+ Ke6 33. g4 Bc3 34. Ra2 Rc8 35. Rxc8 Rxc8 36. a5 Ra8 37. a6 Ra7 38.
+Kf1 g5 39. Ke2 Kd6 40. Kd3 Kc5 41. Ng1 Kb5 42. Ne2 Ba5 43. Rb2+ Kxa6 44.
+Rb1 Rc7 45. Rb2 Be1 46. f3 Ka5 47. Rc2 Rb7 48. Ra2+ Kb5 49. Rb2+ Bb4 50.
+Ra2 Rc7 51. Ra1 Rc8 52. Ra7 Ba5 53. Rd7 Bb6 54. Rd5+ Bc5 55. Nc1 Ka4 56.
+Rd7 Bb4 57. Ne2 Kb3 58. Rb7 Ra8 59. Rxh7 Ra1 60. Nxd4+ exd4 61. Kxd4 Rd1+
+62. Ke3 Bc5+ 63. Ke2 Rh1 64. h4 Kc4 65. h5 Rh2+ 66. Ke1 Kd3 0-1
+
+[Event "Tilburg Grandmaster Tournament"]
+[Site "Tilburg, NED"]
+[Date "1982.09.??"]
+[Round "2"]
+[White "Karpov, Anatoly"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nd2 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a3 a4 10. Ba2 h6 11. N5f3 c5 12. c3 Bd7 13. Ne5 cxd4 14. cxd4
+Be7 15. Ngf3 O-O 16. O-O Be8 17. Bd2 Nbd5 18. Rfc1 Qb6 19. Bc4 Bc6 20. Re1
+Nc7 21. Nxc6 bxc6 22. Bf4 Ncd5 23. Be5 Rfd8 24. Rad1 Bd6 25. Rd2 Bxe5 26.
+dxe5 Nd7 27. g3 Nf8 28. Red1 Rd7 29. Qe4 Rb7 30. Rc2 Rab8 31. Rdd2 Ne7 32.
+Kg2 Qa5 33. h4 Rd7 34. Be2 Rd5 35. Rd4 Rxd4 36. Qxd4 Nd5 37. Rxc6 Qa8 38.
+Rc4 Qb7 39. Rc2 Nb6 40. Bb5 Ng6 41. Qd6 Qa8 42. Bc6 1-0
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "15"]
+[White "Tal,M"]
+[Black "Petrosian,T"]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rdg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "2"]
+[White "Petrosian,T"]
+[Black "Kuzmin,G"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O dxc4 8.
+Bxc4 a6 9. a3 Ba5 10. dxc5 Bxc3 11. bxc3 Qa5 12. a4 Nbd7 13. c6 bxc6 14.
+Qc2 c5 15. e4 Qc7 16. Re1 Ng4 17. Kh1 Re8 18. h3 Ngf6 19. e5 Nd5 20. Ng5
+Nf8 21. f4 Bb7 22. Ne4 Ng6 23. Qf2 Nb6 24. Bf1 Bxe4 25. Rxe4 Qc6 26. Qc2
+Nd5 27. a5 Red8 28. Kh2 Rab8 29. Rea4 Nge7 30. Bd3 Nf5 31. Bxf5 exf5 32.
+Qxf5 Nxc3 33. Rc4 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "10"]
+[White "Petrosian,T"]
+[Black "Smyslov,V"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 b6 6. Ne2 Nc6 7. O-O cxd4 8.
+exd4 Bb7 9. d5 Ne5 10. Bf4 Nxd3 11. Qxd3 exd5 12. cxd5 O-O 13. a3 Bxc3 14.
+Nxc3 Re8 15. Bd6 Ng4 16. Qg3 Nh6 17. Rfe1 Nf5 18. Qf4 Qf6 19. Be5 Qg6 20.
+Qa4 a6 21. Bf4 b5 22. Qb4 Rec8 23. Qe4 h5 24. Qd3 Rc4 25. Re4 Nh4 26. Bg3
+Rxe4 27. Nxe4 Nxg2 28. Kxg2 h4 29. Rd1 hxg3 30. hxg3 Rc8 31. f3 f5 1/2-1/2
+
diff --git a/test/infiles/test-evaluation.pgn b/test/infiles/test-evaluation.pgn
new file mode 100644 (file)
index 0000000..dddfed0
--- /dev/null
@@ -0,0 +1,9 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 Qh4# 0-1
diff --git a/test/infiles/test-f1.pgn b/test/infiles/test-f1.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-f2.pgn b/test/infiles/test-f2.pgn
new file mode 100644 (file)
index 0000000..dddfed0
--- /dev/null
@@ -0,0 +1,9 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 Qh4# 0-1
diff --git a/test/infiles/test-fencomments.pgn b/test/infiles/test-fencomments.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-hash.pgn b/test/infiles/test-hash.pgn
new file mode 100644 (file)
index 0000000..022e7ca
--- /dev/null
@@ -0,0 +1,597 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxf1+ 32. Bxf1
+Rxh7 33. Qxh7 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "3"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
diff --git a/test/infiles/test-long-line.pgn b/test/infiles/test-long-line.pgn
new file mode 100644 (file)
index 0000000..99ba858
--- /dev/null
@@ -0,0 +1,11 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4
+{ only-a-fool-would-play-this-move-and-only-someone-wanting-to-test-how-the-program-copes-with-very-long-lines-would-type-a-comment-like-this }
+Qh4# 0-1
diff --git a/test/infiles/test-nochecks.pgn b/test/infiles/test-nochecks.pgn
new file mode 100644 (file)
index 0000000..5a0b094
--- /dev/null
@@ -0,0 +1,28 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 Qh4# 0-1
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-nomovenumbers.pgn b/test/infiles/test-nomovenumbers.pgn
new file mode 100644 (file)
index 0000000..3777b34
--- /dev/null
@@ -0,0 +1,18 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 {Time control} 1/2-1/2
+
diff --git a/test/infiles/test-noresults.pgn b/test/infiles/test-noresults.pgn
new file mode 100644 (file)
index 0000000..3777b34
--- /dev/null
@@ -0,0 +1,18 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 {Time control} 1/2-1/2
+
diff --git a/test/infiles/test-notags.pgn b/test/infiles/test-notags.pgn
new file mode 100644 (file)
index 0000000..3777b34
--- /dev/null
@@ -0,0 +1,18 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 {Time control} 1/2-1/2
+
diff --git a/test/infiles/test-o.txt b/test/infiles/test-o.txt
new file mode 100644 (file)
index 0000000..740554d
--- /dev/null
@@ -0,0 +1,6 @@
+b2b3 e7e5 c1b2 d7d6 d2d4 e5d4 d1d4 b8c6 d4d2 g8f6 b1c3 c8e6 e2e4 d6d5 e4d5
+e6d5 d2e3+ f8e7 g1f3 e8g8 f1e2 f8e8 e1c1 e7b4 e3d3 b4c3 b2c3 d8e7 h1e1 f6e4
+c3b2 a8d8 d3e3 b7b6 e2b5 e7e6 f3d4 c6d4 d1d4 c7c5 d4e4 d5e4 b5e8 d8e8 f2f3
+e4d5 e3e6 e8e6 e1e6 d5e6 c1d2 g8f8 b2e5 b6b5 e5b8 a7a6 b8a7 c5c4 d2c3 f8e7
+c3d4 e7d6 a7c5+ d6d7 c5a7 d7d6 a7c5+ d6d7 d4c3 g7g6 c5d4 f7f5 1/2-1/2
+
diff --git a/test/infiles/test-plylimit.pgn b/test/infiles/test-plylimit.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/test-r.txt b/test/infiles/test-r.txt
new file mode 100644 (file)
index 0000000..c83aab4
--- /dev/null
@@ -0,0 +1 @@
+f3 e5 g4 Qh4 Kf2 0-1
diff --git a/test/infiles/test-selectonly.pgn b/test/infiles/test-selectonly.pgn
new file mode 100644 (file)
index 0000000..aa39fb5
--- /dev/null
@@ -0,0 +1,581 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
+
diff --git a/test/infiles/test-stalemate.pgn b/test/infiles/test-stalemate.pgn
new file mode 100644 (file)
index 0000000..d17ec22
--- /dev/null
@@ -0,0 +1,46 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 Qh4# 0-1
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
+[Event "?"]
+[Site "Lloyds Bank Masters"]
+[Date "1994.??.??"]
+[Round "1"]
+[White "Rix,S"]
+[Black "Thipsay,BP"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. Nf3 Bg4 6. c3 e6 7. Bf4 Nf6 8.
+Nbd2 Bd6 9. Bxd6 Qxd6 10. O-O O-O 11. h3 Bh5 12. Re1 Rab8 13. Qe2 Rfc8 14.
+Qe3 Bxf3 15. Nxf3 b5 16. Rac1 b4 17. b3 bxc3 18. Rxc3 Nb4 19. Bb1 Rxc3 20.
+Qxc3 Ne4 21. Bxe4 dxe4 22. Rxe4 Nxa2 23. Qa5 Nc1 24. Qxa7 Nxb3 25. Ne5 Rf8
+26. Rf4 f5 27. h4 Nd2 28. Qc5 Rd8 29. Qxd6 Rxd6 30. g4 g6 31. Kg2 Ne4 32.
+gxf5 gxf5 33. Nf3 Nf6 34. Ng5 h6 35. Nxe6 Rxe6 36. Rxf5 Kg7 37. Kf3 Kg6 38.
+Re5 Rd6 39. h5+ Kf7 40. Ra5 Rxd4 41. Ra7+ Ke6 42. Rg7 Rh4 43. Ra7 Rxh5 44.
+Ra6+ Kf7 45. Kg3 Rg5+ 46. Kh4 Kg6 47. Ra4 Rf5 48. Kg3 Nh5+ 49. Kh3 Rxf2 50.
+Rg4+ Kf5 51. Rg5+ hxg5 1/2-1/2
+
diff --git a/test/infiles/test-t.pgn b/test/infiles/test-t.pgn
new file mode 100644 (file)
index 0000000..54c4b09
--- /dev/null
@@ -0,0 +1,100 @@
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxf1+ 32. Bxf1
+Rxh7 33. Qxh7 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "3"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
diff --git a/test/infiles/test-totalplycount.pgn b/test/infiles/test-totalplycount.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/infiles/vvars.txt b/test/infiles/vvars.txt
new file mode 100644 (file)
index 0000000..2aa8fc7
--- /dev/null
@@ -0,0 +1 @@
+e4 c5 Nf3 d6 d4 cxd4 Nxd4 * Nc3 * Be3
diff --git a/test/infiles/xvars.txt b/test/infiles/xvars.txt
new file mode 100644 (file)
index 0000000..209ab8b
--- /dev/null
@@ -0,0 +1 @@
+e4 c5 Nf3 d6 d4 cxd4 Nxd4 Nf6 Nc3 a6 Be3
diff --git a/test/infiles/zmatch.txt b/test/infiles/zmatch.txt
new file mode 100644 (file)
index 0000000..ecf09aa
--- /dev/null
@@ -0,0 +1 @@
+q*r+l*p+ q=r1<=l2>=p1<
diff --git a/test/outfiles/1.pgn b/test/outfiles/1.pgn
new file mode 100644 (file)
index 0000000..2732c1b
--- /dev/null
@@ -0,0 +1,351 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxf1+ 32. Bxf1
+Rxh7 33. Qxh7 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
diff --git a/test/outfiles/2.pgn b/test/outfiles/2.pgn
new file mode 100644 (file)
index 0000000..65b056a
--- /dev/null
@@ -0,0 +1,246 @@
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "3"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
diff --git a/test/outfiles/A.pgn b/test/outfiles/A.pgn
new file mode 100644 (file)
index 0000000..958119b
--- /dev/null
@@ -0,0 +1,39 @@
+[Event "?"]
+[Site "Sarajevo"]
+[Date "1972"]
+[Round "?"]
+[White "Petrosian,T"]
+[Black "Hort"]
+[Result "1-0"]
+[ECO "A13"]
+[Opening "English"]
+[Variation "Wimpey system"]
+
+1. Nf3 c5 2. b3 d5 3. e3 Nf6 4. Bb2 e6 5. c4 Nc6 6. cxd5 exd5 7. Be2 Be7 8.
+O-O O-O 9. d4 Bg4 10. dxc5 Bxc5 11. Nc3 Rc8 12. Rc1 Be7 13. Nd4 Bxe2 14.
+Ncxe2 Qd7 15. Nf4 Rfd8 16. Qd3 Ne4 17. Nxc6 bxc6 18. Rc2 Bf8 19. Rfc1 Qb7
+20. Qe2 Re8 21. Qg4 g6 22. Qd1 Bd6 23. Nxd5 Rcd8 24. Rxc6 Qb8 25. f4 Re6
+26. Qd4 1-0
+
+[Event "?"]
+[Site "Buenos Aires m"]
+[Date "1971"]
+[Round "6"]
+[White "Petrosian,T"]
+[Black "Fischer,R"]
+[Result "0-1"]
+[ECO "A04"]
+[Opening "Reti opening"]
+
+1. Nf3 c5 2. b3 d5 3. Bb2 f6 4. c4 d4 5. d3 e5 6. e3 Ne7 7. Be2 Nec6 8.
+Nbd2 Be7 9. O-O O-O 10. e4 a6 11. Ne1 b5 12. Bg4 Bxg4 13. Qxg4 Qc8 14. Qe2
+Nd7 15. Nc2 Rb8 16. Rfc1 Qe8 17. Ba3 Bd6 18. Ne1 g6 19. cxb5 axb5 20. Bb2
+Nb6 21. Nef3 Ra8 22. a3 Na5 23. Qd1 Qf7 24. a4 bxa4 25. bxa4 c4 26. dxc4
+Nbxc4 27. Nxc4 Nxc4 28. Qe2 Nxb2 29. Qxb2 Rfb8 30. Qa2 Bb4 31. Qxf7+ Kxf7
+32. Rc7+ Ke6 33. g4 Bc3 34. Ra2 Rc8 35. Rxc8 Rxc8 36. a5 Ra8 37. a6 Ra7 38.
+Kf1 g5 39. Ke2 Kd6 40. Kd3 Kc5 41. Ng1 Kb5 42. Ne2 Ba5 43. Rb2+ Kxa6 44.
+Rb1 Rc7 45. Rb2 Be1 46. f3 Ka5 47. Rc2 Rb7 48. Ra2+ Kb5 49. Rb2+ Bb4 50.
+Ra2 Rc7 51. Ra1 Rc8 52. Ra7 Ba5 53. Rd7 Bb6 54. Rd5+ Bc5 55. Nc1 Ka4 56.
+Rd7 Bb4 57. Ne2 Kb3 58. Rb7 Ra8 59. Rxh7 Ra1 60. Nxd4+ exd4 61. Kxd4 Rd1+
+62. Ke3 Bc5+ 63. Ke2 Rh1 64. h4 Kc4 65. h5 Rh2+ 66. Ke1 Kd3 0-1
+
diff --git a/test/outfiles/B.pgn b/test/outfiles/B.pgn
new file mode 100644 (file)
index 0000000..e8bf37c
--- /dev/null
@@ -0,0 +1,36 @@
+[Event "Tilburg Grandmaster Tournament"]
+[Site "Tilburg, NED"]
+[Date "1982.09.??"]
+[Round "2"]
+[White "Karpov, Anatoly"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+[ECO "B17"]
+[Opening "Caro-Kann"]
+[Variation "Steinitz variation"]
+
+1. e4 c6 2. d4 d5 3. Nd2 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a3 a4 10. Ba2 h6 11. N5f3 c5 12. c3 Bd7 13. Ne5 cxd4 14. cxd4
+Be7 15. Ngf3 O-O 16. O-O Be8 17. Bd2 Nbd5 18. Rfc1 Qb6 19. Bc4 Bc6 20. Re1
+Nc7 21. Nxc6 bxc6 22. Bf4 Ncd5 23. Be5 Rfd8 24. Rad1 Bd6 25. Rd2 Bxe5 26.
+dxe5 Nd7 27. g3 Nf8 28. Red1 Rd7 29. Qe4 Rb7 30. Rc2 Rab8 31. Rdd2 Ne7 32.
+Kg2 Qa5 33. h4 Rd7 34. Be2 Rd5 35. Rd4 Rxd4 36. Qxd4 Nd5 37. Rxc6 Qa8 38.
+Rc4 Qb7 39. Rc2 Nb6 40. Bb5 Ng6 41. Qd6 Qa8 42. Bc6 1-0
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "15"]
+[White "Tal,M"]
+[Black "Petrosian,T"]
+[Result "0-1"]
+[ECO "B17"]
+[Opening "Caro-Kann"]
+[Variation "Steinitz variation"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rdg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
diff --git a/test/outfiles/E.pgn b/test/outfiles/E.pgn
new file mode 100644 (file)
index 0000000..5b693d3
--- /dev/null
@@ -0,0 +1,35 @@
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "2"]
+[White "Petrosian,T"]
+[Black "Kuzmin,G"]
+[Result "1/2-1/2"]
+[ECO "E54"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Gligoric system with 7...dc"]
+
+1. c4 Nf6 2. d4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O dxc4 8.
+Bxc4 a6 9. a3 Ba5 10. dxc5 Bxc3 11. bxc3 Qa5 12. a4 Nbd7 13. c6 bxc6 14.
+Qc2 c5 15. e4 Qc7 16. Re1 Ng4 17. Kh1 Re8 18. h3 Ngf6 19. e5 Nd5 20. Ng5
+Nf8 21. f4 Bb7 22. Ne4 Ng6 23. Qf2 Nb6 24. Bf1 Bxe4 25. Rxe4 Qc6 26. Qc2
+Nd5 27. a5 Red8 28. Kh2 Rab8 29. Rea4 Nge7 30. Bd3 Nf5 31. Bxf5 exf5 32.
+Qxf5 Nxc3 33. Rc4 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "10"]
+[White "Petrosian,T"]
+[Black "Smyslov,V"]
+[Result "1/2-1/2"]
+[ECO "E41"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3 c5"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 b6 6. Ne2 Nc6 7. O-O cxd4 8.
+exd4 Bb7 9. d5 Ne5 10. Bf4 Nxd3 11. Qxd3 exd5 12. cxd5 O-O 13. a3 Bxc3 14.
+Nxc3 Re8 15. Bd6 Ng4 16. Qg3 Nh6 17. Rfe1 Nf5 18. Qf4 Qf6 19. Be5 Qg6 20.
+Qa4 a6 21. Bf4 b5 22. Qb4 Rec8 23. Qe4 h5 24. Qd3 Rc4 25. Re4 Nh4 26. Bg3
+Rxe4 27. Nxe4 Nxg2 28. Kxg2 h4 29. Rd1 hxg3 30. hxg3 Rc8 31. f3 f5 1/2-1/2
+
diff --git a/test/outfiles/LLog.txt b/test/outfiles/LLog.txt
new file mode 100644 (file)
index 0000000..67d6f64
--- /dev/null
@@ -0,0 +1,6 @@
+Processing infiles/test-L1.pgn
+? - ? ? ? ????.??.?? 
+1 game matched out of 1.
+Processing infiles/test-L2.pgn
+Barnes, David J. - Horton, Mark Dover vs Herne Bay, Minor League Margate Chess Club 1994.10.10 
+1 game matched out of 1.
diff --git a/test/outfiles/fischer-b30-out.pgn b/test/outfiles/fischer-b30-out.pgn
new file mode 100644 (file)
index 0000000..7470979
--- /dev/null
@@ -0,0 +1,28 @@
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
diff --git a/test/outfiles/fischer-bl45-out.pgn b/test/outfiles/fischer-bl45-out.pgn
new file mode 100644 (file)
index 0000000..f495af6
--- /dev/null
@@ -0,0 +1,305 @@
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
diff --git a/test/outfiles/fischer-bu45-out.pgn b/test/outfiles/fischer-bu45-out.pgn
new file mode 100644 (file)
index 0000000..37d44e9
--- /dev/null
@@ -0,0 +1,275 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
diff --git a/test/outfiles/log.txt b/test/outfiles/log.txt
new file mode 100644 (file)
index 0000000..eecc16f
--- /dev/null
@@ -0,0 +1,36 @@
+Processing infiles/fischer.pgn
+Fischer, Robert J. - Kampars, N. Milwaukee Northwestern ? 1957 
+Fischer, Robert J. - Addison, William G. US Open ? 1957 
+Fischer, Robert J. - Goldsmith, Julius West Orange Open ? 1957 
+Fischer, Robert J. - Cardoso, Rudolfo T. Bad Portoroz Interzonal ? 1958 
+Fischer, Robert J. - Weinstein, Raymond USA Championship ? 1959 
+Fischer, Robert J. - Benko, Pal Yugoslavia Candidate Trn ? 1959 
+Fischer, Robert J. - Keres, Paul Yugoslavia Candidate Trn ? 1959 
+Fischer, Robert J. - Keres, Paul Yugoslavia Candidate Trn ? 1959 
+Fischer, Robert J. - Olafsson, Fridrik Yugoslavia Candidate Trn ? 1959 
+Fischer, Robert J. - Smyslov, Vasily V. Yugoslavia Candidate Trn ? 1959 
+Fischer, R. - Petrosian, T. ? Yugoslavia, Bled 1959.??.?? 
+Fischer, R. - Petrosian, T. ? Yugoslavia, Zagreb 1959.??.?? 
+Fischer, Robert J. - Larsen, Bent Zurich ? 1959 
+Fischer, Robert J. - Foguelman, Alberto Buenos Aires ? 1960 
+Fischer, Robert J. - Ivkov, Boris Buenos Aires ? 1960 
+Fischer, Robert J. - Euwe, Max Leipzig Olympiad Final ? 1960 
+Fischer, Robert J. - Keres, Paul Bled ? 1961 
+Fischer, Robert J. - Petrosian, Tigran V. Bled ? 1961 
+Fischer, Robert J. - Barcza, Gedeon Stockholm Interzonal ? 1962 
+Fischer, Robert J. - Donner, Jan H. Varna Olympiad Final ? 1962 
+Fischer, Robert J. - Steinmeyer, Robert H. USA Championship ? 1963 
+Fischer, Robert J. - Panov, Vasil Skopje ? 1967 
+Fischer, Robert J. - Cagan, Shimon Nathania ? 1968 
+Fischer, Robert J. - Czerniak, Moshe Nathania ? 1968 
+Fischer, Robert J. - Yanofsky, Daniel A. Nathania ? 1968 
+Fischer, Robert J. - Hort, Vlastimil Vinkovci ? 1968 
+Fischer, Robert J. - Hubner, Robert Palma de Mallorca ? 1970 
+Fischer, Robert J. - Hort, Vlastimil Siegen Olympiad Final ? 1970 
+Fischer, Robert J. - Ibrahimoglu, Ismet Siegen Olympiad Prelim ? 1970 
+Fischer, Robert J. - Petrosian, Tigran V. USSR-World ? 1970 
+Fischer, Robert J. - Petrosian, Tigran V. USSR-World ? 1970 
+Fischer, Robert J. - Marovic, Drazen Zabreb ? 1970 
+Fischer, Robert J. - Portisch, Lajos ? Stockholm 1962.??.?? 
+Fischer, Robert J. - Keres, Paul ? Yugoslavia ct 1959.??.?? 
+34 games matched out of 34.
diff --git a/test/outfiles/test-7-out.pgn b/test/outfiles/test-7-out.pgn
new file mode 100644 (file)
index 0000000..53717ae
--- /dev/null
@@ -0,0 +1,23 @@
+[Event "?"]
+[Site "Biel SKA (5)"]
+[Date "1995.??.??"]
+[Round "?"]
+[White "Adianto,U"]
+[Black "Gelfand,B"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 g6 3. g3 Bg7 4. Bg2 O-O 5. Nf3 d6 6. O-O Nc6 7. Nc3 a6 8.
+h3 Bd7 9. e4 e5 10. d5 Nd4 11. Nxd4 exd4 12. Qxd4 Qc8 13. h4 b5 14. cxb5
+axb5 15. Qb4 Ng4 16. Bf4 Re8 17. Rac1 Qb8 18. Bh3 Qb6 19. Bxg4 Bxg4 20.
+Qxb5 Reb8 21. Qxb6 Rxb6 22. b3 c5 23. dxc6 Rxc6 24. Nd5 Rxc1 25. Rxc1 Rxa2
+26. Kg2 Bd4 27. Be3 Bxe3 28. Nxe3 Be6 29. Rb1 Bd7 30. g4 Bb5 31. Kg3 Bd3
+32. Rd1 Bxe4 33. Rxd6 Rb2 34. Rb6 Kg7 35. g5 h6 36. b4 hxg5 37. hxg5 Kf8
+38. f3 Bd3 39. Kf4 Ke8 40. Ke5 Re2 41. Kd4 Bb1 42. b5 Rf2 43. Rb8+ Kd7 44.
+Rb7+ Ke6 45. Rb6+ Kd7 46. Rf6 Rd2+ 47. Kc5 Ba2 48. Nc4 Rg2 49. Rxf7+ Ke6
+50. Rf4 Rxg5+ 51. Kc6 Bb3 52. Re4+ Kf6 53. Ne3 Be6 54. b6 Bc8 55. Nd5+ Kg7
+56. Nb4 Rg1 57. Rc4 Re1 58. Kc7 Re8 59. Re4 Rf8 60. Nc6 Ba6 61. Re3 Kh6 62.
+Ra3 Rf7+ 63. Kd6 Rf6+ 64. Ke7 Rxc6 65. Rxa6 Kh7 66. Kd8 Kh6 67. Ke7 Kh7 68.
+Kd7 Rf6 69. b7 Rxa6 70. b8=Q Ra5 71. Ke6 Rf5 72. Qg3 Kg7 73. Qg4 Rf6+ 74.
+Ke5 Rf7 75. Ke4 Kh7 76. Qc8 Kg7 77. Ke3 Rf8 78. Qc3+ Kh7 79. Kf2 Rf5 80.
+Kg3 Rg5+ 81. Kf4 Rf5+ 82. Kg4 Rf7 83. Qe5 1-0
+
diff --git a/test/outfiles/test-AA-dupes.pgn b/test/outfiles/test-AA-dupes.pgn
new file mode 100644 (file)
index 0000000..c852240
--- /dev/null
@@ -0,0 +1,50 @@
+{ From: infiles/petrosian.pgn }
+{ First found in: infiles/fischer.pgn }
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+{ First found in: infiles/fischer.pgn }
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+{ First found in: infiles/fischer.pgn }
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
diff --git a/test/outfiles/test-AA-unique.pgn b/test/outfiles/test-AA-unique.pgn
new file mode 100644 (file)
index 0000000..fe33ef4
--- /dev/null
@@ -0,0 +1,83 @@
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
diff --git a/test/outfiles/test-CC-out.pgn b/test/outfiles/test-CC-out.pgn
new file mode 100644 (file)
index 0000000..8492f59
--- /dev/null
@@ -0,0 +1,16 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6
+Bxe6 26. Kd2 Kf8 27. Be5 b5 28. Bb8 $2 (28. Bd6+) 28... a6 29. Ba7 c4 30.
+Kc3 Ke7 31. Kd4 Kd6 32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36.
+Bd4 f5 1/2-1/2
+
diff --git a/test/outfiles/test-DD-unique.pgn b/test/outfiles/test-DD-unique.pgn
new file mode 100644 (file)
index 0000000..c0142c4
--- /dev/null
@@ -0,0 +1,1050 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
+[Event "?"]
+[Site "Sarajevo"]
+[Date "1972"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Hort"]
+[Result "1-0"]
+
+1. Nf3 c5 2. b3 d5 3. e3 Nf6 4. Bb2 e6 5. c4 Nc6 6. cxd5 exd5 7. Be2 Be7 8.
+O-O O-O 9. d4 Bg4 10. dxc5 Bxc5 11. Nc3 Rc8 12. Rc1 Be7 13. Nd4 Bxe2 14.
+Ncxe2 Qd7 15. Nf4 Rfd8 16. Qd3 Ne4 17. Nxc6 bxc6 18. Rc2 Bf8 19. Rfc1 Qb7
+20. Qe2 Re8 21. Qg4 g6 22. Qd1 Bd6 23. Nxd5 Rcd8 24. Rxc6 Qb8 25. f4 Re6
+26. Qd4 1-0
+
+[Event "?"]
+[Site "Buenos Aires m"]
+[Date "1971"]
+[Round "6"]
+[White "Petrosian, Tigran V."]
+[Black "Fischer, Robert J."]
+[Result "0-1"]
+
+1. Nf3 c5 2. b3 d5 3. Bb2 f6 4. c4 d4 5. d3 e5 6. e3 Ne7 7. Be2 Nec6 8.
+Nbd2 Be7 9. O-O O-O 10. e4 a6 11. Ne1 b5 12. Bg4 Bxg4 13. Qxg4 Qc8 14. Qe2
+Nd7 15. Nc2 Rb8 16. Rfc1 Qe8 17. Ba3 Bd6 18. Ne1 g6 19. cxb5 axb5 20. Bb2
+Nb6 21. Nef3 Ra8 22. a3 Na5 23. Qd1 Qf7 24. a4 bxa4 25. bxa4 c4 26. dxc4
+Nbxc4 27. Nxc4 Nxc4 28. Qe2 Nxb2 29. Qxb2 Rfb8 30. Qa2 Bb4 31. Qxf7+ Kxf7
+32. Rc7+ Ke6 33. g4 Bc3 34. Ra2 Rc8 35. Rxc8 Rxc8 36. a5 Ra8 37. a6 Ra7 38.
+Kf1 g5 39. Ke2 Kd6 40. Kd3 Kc5 41. Ng1 Kb5 42. Ne2 Ba5 43. Rb2+ Kxa6 44.
+Rb1 Rc7 45. Rb2 Be1 46. f3 Ka5 47. Rc2 Rb7 48. Ra2+ Kb5 49. Rb2+ Bb4 50.
+Ra2 Rc7 51. Ra1 Rc8 52. Ra7 Ba5 53. Rd7 Bb6 54. Rd5+ Bc5 55. Nc1 Ka4 56.
+Rd7 Bb4 57. Ne2 Kb3 58. Rb7 Ra8 59. Rxh7 Ra1 60. Nxd4+ exd4 61. Kxd4 Rd1+
+62. Ke3 Bc5+ 63. Ke2 Rh1 64. h4 Kc4 65. h5 Rh2+ 66. Ke1 Kd3 0-1
+
+[Event "?"]
+[Site "USSR 26/2"]
+[Date "1978"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Balashov,Y"]
+[Result "1-0"]
+
+1. b3 e5 2. Bb2 Nc6 3. c4 Nf6 4. e3 d5 5. cxd5 Nxd5 6. a3 Bd6 7. Qc2 O-O 8.
+Nf3 Qe7 9. Bd3 Kh8 10. Be4 Nb6 11. Bxc6 bxc6 12. d3 Bd7 13. Nbd2 f5 14. e4
+fxe4 15. dxe4 Rf4 16. Qc3 Re8 17. O-O c5 18. Kh1 Bc6 19. Rae1 Nd7 20. Ng1
+Nf6 21. f3 Nh5 22. g4 1-0
+
+[Event "?"]
+[Site "Tilburg 32/3"]
+[Date "1981"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Sosonko,G"]
+[Result "1-0"]
+
+1. c4 e5 2. b3 Nf6 3. Bb2 Nc6 4. e3 Be7 5. a3 O-O 6. Qc2 d5 7. cxd5 Nxd5 8.
+Nf3 Bf6 9. d3 g6 10. Nbd2 Bg7 11. Rc1 g5 12. Nc4 Qe7 13. b4 a6 14. Nfd2 f5
+15. Be2 g4 16. Nb3 Kh8 17. Nca5 Nxa5 18. Nxa5 Qf7 19. O-O c6 20. Nc4 Qe7
+21. Rfe1 Bd7 22. Bf1 Nc7 23. Nb6 Rad8 24. Qc5 Qxc5 25. Rxc5 Ne6 26. Rxe5
+Bxe5 27. Bxe5+ Kg8 28. d4 Be8 29. Nc4 b5 30. Nd6 Bd7 31. Rc1 Ng5 32. Nb7
+Rc8 33. Bd3 Ra8 34. Kf1 Be6 35. Bf4 Nf7 36. Ke2 Bd5 37. Bxf5 Ne5 38. Bxe5
+Rxf5 39. Nd6 Rff8 40. e4 Bc4+ 41. Nxc4 bxc4 42. Rxc4 a5 43. Bd6 Rfe8 44. e5
+axb4 45. Bxb4 1-0
+
+[Event "Tilburg Grandmaster Tournament"]
+[Site "Tilburg, NED"]
+[Date "1982.09.??"]
+[Round "2"]
+[White "Karpov, Anatoly"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nd2 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a3 a4 10. Ba2 h6 11. N5f3 c5 12. c3 Bd7 13. Ne5 cxd4 14. cxd4
+Be7 15. Ngf3 O-O 16. O-O Be8 17. Bd2 Nbd5 18. Rfc1 Qb6 19. Bc4 Bc6 20. Re1
+Nc7 21. Nxc6 bxc6 22. Bf4 Ncd5 23. Be5 Rfd8 24. Rad1 Bd6 25. Rd2 Bxe5 26.
+dxe5 Nd7 27. g3 Nf8 28. Red1 Rd7 29. Qe4 Rb7 30. Rc2 Rab8 31. Rdd2 Ne7 32.
+Kg2 Qa5 33. h4 Rd7 34. Be2 Rd5 35. Rd4 Rxd4 36. Qxd4 Nd5 37. Rxc6 Qa8 38.
+Rc4 Qb7 39. Rc2 Nb6 40. Bb5 Ng6 41. Qd6 Qa8 42. Bc6 1-0
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "15"]
+[White "Tal,M"]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rdg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Tilburg"]
+[Date "1982.??.??"]
+[Round "7"]
+[White "Nunn,John"]
+[Black "Petrosian,Tigran"]
+[Result "1-0"]
+
+1. e4 c6 2. c4 d5 3. exd5 cxd5 4. cxd5 Nf6 5. Nc3 Nxd5 6. Nf3 Nxc3 7. bxc3
+g6 8. d4 Bg7 9. Bd3 Nc6 10. O-O O-O 11. Re1 Bg4 12. Be4 Rc8 13. Bg5 Re8 14.
+Rb1 Qd7 15. h3 Bxf3 16. Bxf3 b6 17. Bg4 f5 18. Be2 h6 19. Bc1 Kh7 20. d5
+1-0
+
+[Event "?"]
+[Site "Bled"]
+[Date "1961.??.??"]
+[Round "17"]
+[White "Keres, Paul"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. N1e2 e6 7. h4 h6 8.
+Nf4 Bh7 9. c3 Nf6 10. Bd3 Bxd3 11. Nxd3 Bd6 12. Qf3 Nbd7 13. Bf4 Bxf4 14.
+Qxf4 Qb8 15. Qf3 Qd6 16. O-O-O Qd5 17. Qxd5 cxd5 18. f4 Ne4 19. Nxe4 dxe4
+20. Ne5 Rd8 21. h5 1/2-1/2
+
+[Event "?"]
+[Site "Piatgorsky Cup"]
+[Date "1963.??.??"]
+[Round "1"]
+[White "Keres, Paul"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Bc4 e6 7. N1e2 Nf6
+8. Nf4 Bd6 9. Bb3 Nbd7 10. Qf3 Qc7 11. h4 O-O-O 12. h5 Bf5 13. Nxf5 Qa5+
+14. c3 Qxf5 15. Qd3 Qxd3 16. Nxd3 h6 17. Rh4 Rhe8 18. Be3 Nd5 19. O-O-O
+Nxe3 20. fxe3 Nf6 21. Rf1 Re7 22. Nf2 Bg3 23. Rh3 Bd6 24. Bc2 e5 25. Nd3
+exd4 26. exd4 Re2 27. g4 Rde8 28. Bd1 R2e3 29. Rxe3 Rxe3 30. Rf3 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "1"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 Qc7 10. Bd2 e6 11. O-O-O O-O-O 12. c4 Ngf6 13. Kb1 c5 14.
+Bc3 cxd4 15. Nxd4 a6 16. Nf3 Bc5 17. Qe2 Bd6 18. Ne4 Be7 19. Nxf6 Bxf6 20.
+Bxf6 Nxf6 21. Ne5 Rxd1+ 22. Rxd1 Rd8 23. Rxd8+ Kxd8 24. Qd3+ Ke7 25. Qd4 h5
+26. a3 Nd7 27. Nxd7 Qxd7 28. Qc5+ Qd6 29. Qg5+ Ke8 30. Qe3 Qc6 31. Qg3 g6
+32. b3 Qe4+ 33. Kb2 e5 34. Qe3 Qxg2 35. Qxe5+ Kf8 36. Qh8+ Ke7 37. Qe5+
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "3"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bc4 Nf6 9. O-O O-O 10. Qe2 Nc6 11. Be3 Na5 12. Bd3 b6 13. Bg5 Bb7 14.
+Rad1 Rc8 15. Rfe1 h6 16. Bc1 Bb4 17. Bd2 Bxc3 18. bxc3 Qd5 19. Qf1 Qxa2 20.
+Ne5 Nb3 21. Re2 Nxd2 22. Rexd2 Qd5 23. c4 Qd6 24. Qe2 Rfd8 25. h3 Nd7 26.
+Ng4 h5 27. Ne3 g6 28. Ra2 Ra8 29. Qc2 Kg7 30. Be4 Bxe4 31. Qxe4 Nf6 32. Qh4
+Rd7 33. Rad2 Rad8 34. Rd3 a6 35. Qg5 Ne4 36. Qh4 Nf6 37. Rb3 Qc7 38. d5 Qe5
+39. Rxb6 exd5 40. Nxd5 Nxd5 41. cxd5 Rxd5 42. Qxd8 Rxd8 43. Rxd8 Qe1+
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "5"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. g3 Na6 9. Bg2 Qb6 10. Qxb6 axb6 11. Nge2 Nb4 12. O-O Rd8 13. d6 Rxd6 14.
+Bf4 Rd7 15. Rfd1 Nbd5 16. Be5 Bh6 17. a3 e6 18. Nxd5 Nxd5 19. Rd3 Bg5 20.
+Bxd5 exd5 21. h4 Bd8 22. Rc1 Re7 23. Nf4 Be6 24. Rdc3 Bd7 25. Nxd5 Re6 26.
+Bc7 Kg7 27. Bxd8 Rxd8 28. Ne3 b5 29. d5 Rb6 30. Nc2 h6 31. Nb4 g5 32. hxg5
+hxg5 33. Kg2 Rf6 34. Re3 Rh8 35. Nd3 Rd6 36. Ne5 Bh3+ 37. Kf3 Rxd5 38. Rc7
+Be6 39. Rxb7 Rc5 40. Ra7 Bd5+ 41. Kg4 Rc2 42. Kxg5 Rxf2 43. Nd3 Rf3 44.
+Rae7 Rxe3 45. Rxe3 f6+ 46. Kf4 Kf7 47. Nb4 Bc4 48. Rc3 Rh2 49. b3 Be6 50.
+Nd3 Ra2 51. Rc7+ Kg6 52. Nc5 Bf7 53. Rb7 Rxa3 54. Rxb5 Ra1 55. Ne4 Rf1+ 56.
+Ke3 Re1+ 57. Kf3 Rf1+ 58. Ke2 Rb1 59. Nd2 Rg1 60. Kf2 Rc1 61. b4 Rc2 62.
+Ke3 Rc3+ 63. Kf4 Rd3 64. Nf3 Bd5 65. Nh4+ Kf7 66. Rb8 Rd4+ 67. Ke3 Re4+ 68.
+Kf2 Ke7 69. Ng6+ Kd7 70. Nf4 Bc6 71. Nd3 Kc7 72. Rf8 Bb5 73. Nf4 Kd7 74.
+Rf7+ Ke8 75. Rb7 Rxb4 76. Nd5 Rb2+ 77. Ke3 Rb3+ 78. Kf4 Bc4 79. Nxf6+ Kf8
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "9"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bd3 Nc6 9. O-O O-O 10. Re1 Bf6 11. Be4 Nce7 12. Qc2 g6 13. Bh6 Bg7 14.
+Bg5 f6 15. Bd2 Bd7 16. Qb3 Bc6 17. Bxd5 exd5 18. Ne4 Rf7 19. Nc5 Nf5 20. h3
+Bf8 21. Ne6 Qd7 22. Nxf8 Rfxf8 23. Bb4 Rfe8 24. Rxe8+ Rxe8 25. Re1 Rxe1+
+26. Bxe1 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "13"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+h5 Bh7 9. Bd3 Bxd3 10. Qxd3 Qc7 11. Bd2 e6 12. Qe2 Ngf6 13. O-O-O O-O-O 14.
+Ne5 Nxe5 15. dxe5 Nd7 16. f4 Be7 17. Ne4 Nc5 18. Nc3 f6 19. exf6 Bxf6 20.
+Qc4 Qb6 21. b4 Na6 22. Ne4 Nc7 23. Rhe1 Rd4 24. Qb3 Qb5 25. c3 Rxe4 26.
+Rxe4 Qxh5 27. Qc4 Qf5 28. Qe2 h5 29. Be1 Re8 30. g3 a5 31. bxa5 Qxa5 32.
+Qc2 Qf5 33. Ra4 g5 34. fxg5 Bxg5+ 35. Kb1 Qxc2+ 36. Kxc2 e5 37. Re4 Nd5 38.
+Bf2 Nf6 39. Ra4 Kc7 40. Bc5 Nd5 41. Re4 b6 42. Bg1 Bd8 43. Rf1 Nf6 44. Re2
+c5 45. Rf5 Kd6 46. a4 Kd5 47. Kd3 Ng4 48. Rb2 Rh8 49. a5 c4+ 50. Ke2 Ke4
+51. Rf7 bxa5 52. Rb8 a4 53. Rc8 Bf6 54. Rxc4+ Kf5 55. Ra7 a3 56. Rxa3 Rb8
+57. Rb4 Rc8 58. c4 Be7 59. c5 e4 60. Ra7 Bf6 61. Rh7 Kg6 62. Rd7 Kf5 63.
+Rd5+ Be5 64. Rb6 e3 65. Kf3 Nf6 66. Rd3 Rxc5 67. Bxe3 Rc2 68. Rd8 Rc3 69.
+Ke2 Rc2+ 70. Kd1 Rc3 71. Bf2 Ne4 72. Rf8+ Kg5 73. Rb5 Rd3+ 74. Ke2 Rd5 75.
+Rxd5 Nc3+ 76. Kf3 Nxd5 77. Ra8 Kf5 78. Ra5 Ke6 79. Be1 Nf6 80. Rb5 Nd5 81.
+Bd2 Bg7 82. Bc1 Be5 83. Bb2 Bc7 84. Rc5 Bd6 85. Rc1 Ne7 86. Re1+ Kf5 87.
+Ra1 Nc6 88. Ra6 Be5 89. Rxc6 Bxb2 90. Rc5+ Kg6 91. Kf4 1-0
+
+[Event "?"]
+[Site "URS"]
+[Date "1966.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bc4 O-O 9. O-O Nc6 10. Re1 Bf6 11. Ne4 b6 12. a3 Bb7 13. Qd3 Rc8 14.
+Nfg5 Bxg5 15. Bxg5 f6 16. Bd2 Qd7 17. Rad1 Nce7 18. Ba2 Rfe8 19. Bb1 Ng6
+20. Qg3 f5 21. Qd6 Rcd8 22. Qxd7 Rxd7 23. Ng5 Rde7 24. Ba2 h6 25. Nf3 Rc7
+26. Rc1 Rxc1 27. Rxc1 Rc8 28. Rxc8+ Bxc8 29. h4 Bb7 1/2-1/2
+
+[Event "Moskva tt"]
+[Site "?"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nd7 7. Bc4 e6
+8. O-O Ngf6 9. Ng5 h6 10. Nh3 Bd6 11. Nf4 Bxf4 12. Bxf4 Nd5 13. Bc1 Qh4 14.
+Bd3 Bxd3 15. Qxd3 O-O-O 16. Rd1 N7f6 17. c4 Nc7 18. b4 Rd7 19. Bb2 Rhd8 20.
+Qe2 Qg4 21. f3 Qg6 22. a4 h5 23. b5 h4 24. bxc6 bxc6 25. Ne4 Nxe4 26. fxe4
+h3 27. g3 f5 28. e5 c5 29. dxc5 Rxd1+ 30. Rxd1 Rxd1+ 31. Qxd1 Qe8 32. Qd6
+Kb7 33. c6+ Qxc6 34. Qxc6+ Kxc6 35. Bd4 a5 36. Bc3 Na6 37. Bxa5 Nc5 38. Bb4
+Nxa4 39. g4 fxg4 40. Kf2 Nb2 41. Kg3 Nxc4 42. Kxg4 Nxe5+ 43. Kxh3 Kd5 44.
+Kh4 Kc4 45. Bd6 Nf7 46. Bc7 g6 47. Kg4 Kd5 48. h4 Ke4 49. h5 Ne5+ 1/2-1/2
+
+[Event "URS-ch"]
+[Site "?"]
+[Date "1973.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rhg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "2"]
+[White "Petrosian, Tigran V."]
+[Black "Kuzmin,G"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O dxc4 8.
+Bxc4 a6 9. a3 Ba5 10. dxc5 Bxc3 11. bxc3 Qa5 12. a4 Nbd7 13. c6 bxc6 14.
+Qc2 c5 15. e4 Qc7 16. Re1 Ng4 17. Kh1 Re8 18. h3 Ngf6 19. e5 Nd5 20. Ng5
+Nf8 21. f4 Bb7 22. Ne4 Ng6 23. Qf2 Nb6 24. Bf1 Bxe4 25. Rxe4 Qc6 26. Qc2
+Nd5 27. a5 Red8 28. Kh2 Rab8 29. Rea4 Nge7 30. Bd3 Nf5 31. Bxf5 exf5 32.
+Qxf5 Nxc3 33. Rc4 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "10"]
+[White "Petrosian, Tigran V."]
+[Black "Smyslov,V"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 b6 6. Ne2 Nc6 7. O-O cxd4 8.
+exd4 Bb7 9. d5 Ne5 10. Bf4 Nxd3 11. Qxd3 exd5 12. cxd5 O-O 13. a3 Bxc3 14.
+Nxc3 Re8 15. Bd6 Ng4 16. Qg3 Nh6 17. Rfe1 Nf5 18. Qf4 Qf6 19. Be5 Qg6 20.
+Qa4 a6 21. Bf4 b5 22. Qb4 Rec8 23. Qe4 h5 24. Qd3 Rc4 25. Re4 Nh4 26. Bg3
+Rxe4 27. Nxe4 Nxg2 28. Kxg2 h4 29. Rd1 hxg3 30. hxg3 Rc8 31. f3 f5 1/2-1/2
+
+[Event "?"]
+[Site "Tilburg"]
+[Date "1982.??.??"]
+[Round "10"]
+[White "Petrosian,Tigran"]
+[Black "Browne,Walter"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Nc3 Bb4 5. e3 O-O 6. Bd3 Bb7 7. O-O d5 8.
+a3 Bd6 9. cxd5 exd5 10. b4 a6 11. Qb3 Qe7 12. Rb1 Nbd7 13. a4 Ne4 14. Bb2
+Ndf6 15. b5 a5 16. Rbd1 Nxc3 17. Bxc3 Ne4 18. Bb2 Rad8 19. Ne5 Kh8 20. Qc2
+f6 21. Nf3 Bc8 22. Ne1 f5 23. g3 Rf6 24. Nf3 Rdf8 25. Ne5 Rh6 26. f3 Ng5
+27. Qg2 Nh3+ 28. Kh1 g5 29. g4 Qf6 30. Rd2 Rh4 31. Rc2 Qg7 32. gxf5 Bxf5
+33. Bxf5 Rxf5 34. Bc3 Rh6 35. Ng4 Rh5 36. Be1 Qe7 37. Bg3 Rf7 38. Rfc1 Kg7
+39. Rc6 Kf8 40. Bxd6 cxd6 41. Qg3 Rh4 42. Qxd6 1-0
+
+[Event "?"]
+[Site "Lone"]
+[Date "1978.??.??"]
+[Round "?"]
+[White "Portisch, Lajos"]
+[Black "Petrosian, Tigran"]
+[Result "0-1"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 b6 5. Bd3 Bb7 6. Nf3 O-O 7. O-O d5 8.
+a3 Bd6 9. b4 dxc4 10. Bxc4 Nbd7 11. Bb2 a5 12. b5 e5 13. Re1 e4 14. Nd2 Qe7
+15. Be2 Rad8 16. Qc2 Rfe8 17. f3 exf3 18. Bxf3 Bxf3 19. Nxf3 Ne4 20. Nxe4
+Qxe4 21. Qxe4 Rxe4 22. Nd2 Ree8 23. e4 Nc5 24. Nc4 Nxe4 25. Rac1 Bf8 26.
+Ne5 Nd6 27. a4 f6 28. Nf3 Rxe1+ 29. Nxe1 Rd7 30. Nf3 Nf5 31. Kf2 h5 32. Rc2
+g5 33. Rc4 Bd6 34. g3 Kf7 35. Ng1 Ne7 36. Ne2 Nd5 37. Bc1 Kg6 38. Rc2 Kf5
+39. Kf3 g4+ 40. Kf2 Rh7 41. Rd2 h4 42. Kg2 Ke4 43. Rd1 Ne3+ 44. Bxe3 Kxe3
+45. Nc3 h3+ 0-1
+
+[Event "?"]
+[Site "Milano"]
+[Date "1975.??.??"]
+[Round "1"]
+[White "Petrosian, Tigran"]
+[Black "Karpov, Anatoly"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 c5 6. Nf3 d5 7. O-O cxd4 8.
+exd4 dxc4 9. Bxc4 b6 10. Bg5 Bb7 11. Qe2 Bxc3 12. bxc3 Nbd7 13. Bd3 Qc7 14.
+c4 Ng4 15. Be4 Bxe4 16. Qxe4 Ngf6 17. Qd3 h6 18. Bxf6 Nxf6 19. a4 Rac8 20.
+Rfc1 Rfd8 21. h3 e5 22. Nxe5 Qxe5 23. dxe5 Rxd3 24. exf6 Rd4 25. a5 gxf6
+26. axb6 axb6 27. Rab1 Rcxc4 28. Rxc4 Rxc4 29. Rxb6 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1971.??.??"]
+[Round "1"]
+[White "Petrosian, Tigran"]
+[Black "Kortchnoi, Viktor"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 6. a3 Bxc3+ 7. bxc3
+O-O 8. Bg5 c5 9. e3 Nbd7 10. Bd3 Qa5 11. Ne2 b6 12. O-O Ba6 13. Bxa6 Qxa6
+14. Bxf6 Nxf6 15. Nf4 Qc4 16. Qa2 Qxa2 17. Rxa2 Rac8 18. a4 Rfd8 19. Rb1
+Ne4 20. Ne2 Nd6 21. h4 Nc4 22. Nf4 Kf8 23. g4 g6 24. Kg2 h6 25. Rd1 g5 26.
+hxg5 hxg5 27. Ne2 Nd6 28. Ng3 cxd4 29. Rxd4 Ne4 30. Nxe4 dxe4 31. Rxe4 Rxc3
+32. a5 Rdc8 33. axb6 axb6 34. Rb2 R3c4 35. Rxc4 Rxc4 1/2-1/2
+
+[Event "?"]
+[Site "Wch"]
+[Date "1963.??.??"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Botvinnik, Mikhail"]
+[Result "0-1"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 6. Bg5 h6 7. Bxf6 Qxf6
+8. a3 Bxc3+ 9. Qxc3 c6 10. e3 O-O 11. Ne2 Re8 12. Ng3 g6 13. f3 h5 14. Be2
+Nd7 15. Kf2 h4 16. Nf1 Nf8 17. Nd2 Re7 18. Rhe1 Bf5 19. h3 Rae8 20. Nf1 Ne6
+21. Qd2 Ng7 22. Rad1 Nh5 23. Rc1 Qd6 24. Rc3 Ng3 25. Kg1 Nh5 26. Bd1 Re6
+27. Qf2 Qe7 28. Bb3 g5 29. Bd1 Bg6 30. g4 hxg3 31. Nxg3 Nf4 32. Qh2 c5 33.
+Qd2 c4 34. Ba4 b5 35. Bc2 Nxh3+ 36. Kf1 Qf6 37. Kg2 Nf4+ 38. exf4 Rxe1 39.
+fxg5 Qe6 40. f4 Re2+ 0-1
+
+[Event "?"]
+[Site "Curacao ct"]
+[Date "1962.??.??"]
+[Round "3"]
+[White "Petrosian, Tigran V."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nf3 b6 4. Nc3 Bb4 5. e3 c5 6. Bd3 d5 7. dxc5 bxc5 8.
+O-O O-O 9. Ne2 Bb7 10. b3 Nbd7 11. Bb2 Qe7 12. Ng3 g6 13. cxd5 exd5 14. a3
+Ba5 15. b4 cxb4 16. Qa4 Bb6 17. axb4 Ng4 18. Rfe1 Nde5 19. Nxe5 Nxe5 20.
+Rad1 Nxd3 21. Rxd3 Rfc8 22. b5 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "20"]
+[White "Petrosian, Tigran V."]
+[Black "Spassky, Boris"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 c5 6. Nf3 d5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 dxc4 10. Bxc4 Qc7 11. Bd3 e5 12. Qc2 Bg4 13. Nxe5 Nxe5 14.
+dxe5 Qxe5 15. f3 Bd7 16. a4 Rfe8 17. e4 c4 18. Be2 Be6 19. Be3 Qc7 20. Rab1
+Nd7 21. Rb5 b6 22. Rfb1 Qc6 23. Bd4 f6 24. Qa2 Kh8 25. Bf1 h6 26. h3 Rab8
+27. a5 Rb7 28. axb6 axb6 29. Qf2 Ra8 30. Qb2 Rba7 31. Bxb6 Ra2 32. Qb4 Rc2
+33. Bf2 Qc7 34. Qe7 Bxh3 35. gxh3 Rxf2 36. Kxf2 Qh2+ 37. Bg2 Ne5 38. Rb8+
+Rxb8 39. Rxb8+ Kh7 40. Rd8 Ng6 41. Qe6 1-0
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1969.??.??"]
+[Round "10"]
+[White "Petrosian, Tigran V."]
+[Black "Spassky, Boris"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 b6 6. Ne2 d5 7. O-O dxc4 8.
+Bxc4 Bb7 9. f3 c5 10. a3 cxd4 11. axb4 dxc3 12. Nxc3 Nc6 13. b5 Ne5 14. Be2
+Qc7 15. e4 Rfd8 16. Qe1 Qc5+ 17. Qf2 Qe7 18. Ra3 Ne8 19. Bf4 Ng6 20. Be3
+Nd6 21. Rfa1 Nc8 22. Bf1 f5 23. exf5 exf5 24. Ra4 Re8 25. Bd2 Qc5 26. Qxc5
+bxc5 27. Rc4 Re5 28. Na4 a6 29. Nxc5 axb5 30. Nxb7 Rxa1 31. Rxc8+ Kf7 32.
+Nd8+ Ke7 33. Nc6+ Kd7 34. Nxe5+ Kxc8 35. Nxg6 hxg6 36. Bc3 Rb1 37. Kf2 b4
+38. Bxg7 1-0
+
+[Event "?"]
+[Site "Milano"]
+[Date "1975.??.??"]
+[Round "2"]
+[White "Ljubojevic, Ljubomir"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. a3 Be7 6. Nf3 O-O 7. e3 b6 8.
+cxd5 exd5 9. b4 Re8 10. Bd3 Bb7 11. O-O Bd6 12. Bb2 a6 13. Ne5 c5 14. bxc5
+bxc5 15. Rab1 Qc7 16. h3 c4 1/2-1/2
+
+[Event "32nd ol"]
+[Site "Yerevan ARM"]
+[Date "1996.09.17"]
+[Round "02"]
+[White "Gostisa,L"]
+[Black "Petrosian,A"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. Nf3 e6 3. g3 d5 4. Bg2 Nbd7 5. O-O b5 6. b3 Bb7 7. c4 bxc4 8.
+bxc4 dxc4 9. Qa4 c5 10. Ba3 Qc7 11. Qxc4 Rc8 12. Rc1 Qb8 1/2-1/2
+
+[Event "?"]
+[Site "Belgrade"]
+[Date "1954.??.??"]
+[Round "?"]
+[White "Janosevic"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 e6 5. Nc3 Nf6 6. Bg5 Be7 7. Nf3 O-O 8.
+Rc1 a6 9. cxd5 exd5 10. Be2 Nc6 11. Ne5 Na5 12. O-O h6 13. Bh4 Bf5 14. Bf3
+Be6 15. Re1 Nc6 16. Ng6 fxg6 17. Rxe6 g5 18. Bg3 Qd7 19. Re1 Rae8 20. Be5
+Kh8 21. Qb3 g4 22. Bxd5 Nxd5 23. Nxd5 Bg5 24. Rcd1 Na5 25. Nb6 Qd8 26. Qa4
+Qxb6 27. Bxg7+ Kxg7 28. Rxe8 Nc6 29. Rxf8 Kxf8 30. d5 Ne5 31. d6 Qxb2 32.
+d7 Nf7 33. Qxg4 Qxa2 34. Qb4+ Be7 35. d8=Q+ Nxd8 36. Rxd8+ Kf7 37. Qf4+ Kg7
+38. Qg4+ Kf6 39. Rd1 b5 40. h4 Qe6 41. Qh5 Kg7 42. Rd3 Bd6 43. Qd1 Bc5 44.
+Rg3+ Kf6 45. Qa1+ Kf5 46. Qb1+ Ke5 47. Rg6 Qf7 48. Qe1+ Kd5 49. Rxa6 Qf4
+50. Qd1+ Kc4 51. Ra2 Bd4 52. Qe2+ Kb4 53. Qe1+ Kb3 54. Qb1+ Kc4 55. Rc2+
+Bc3 56. Re2 Bd4 57. Qc2+ Kd5 58. Qb3+ Kc5 59. g3 Qf6 60. Rc2+ Kb6 61. Kg2
+Qf5 62. Re2 Kc5 63. Qc2+ Qxc2 64. Rxc2+ Kd5 65. f4 b4 66. Kf3 b3 67. Rc1 b2
+68. Rd1 h5 69. g4 hxg4+ 70. Kxg4 Ke4 71. h5 Be3 72. Rb1 Bc1 73. h6 Bxf4 74.
+Re1+ 1-0
+
diff --git a/test/outfiles/test-FF-out.pgn b/test/outfiles/test-FF-out.pgn
new file mode 100644 (file)
index 0000000..8b3ba74
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control
+} { "8/3k3p/p3b1p1/1p3p2/2pB4/1PK2P2/P1P3PP/8 w - f6 0 38" } 1/2-1/2
+
diff --git a/test/outfiles/test-NN-out.pgn b/test/outfiles/test-NN-out.pgn
new file mode 100644 (file)
index 0000000..3685c29
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6 32.
+Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control. }
+1/2-1/2
+
diff --git a/test/outfiles/test-PP-out.pgn b/test/outfiles/test-PP-out.pgn
new file mode 100644 (file)
index 0000000..f0e528d
--- /dev/null
@@ -0,0 +1,69 @@
+[Event "?"]
+[Site "Wch"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Botvinnik, Mikhail"]
+[Black "Tal, M."]
+[Result "1-0"]
+
+1. c4 Nf6 2. Nc3 e6 3. d4 Bb4 4. a3 Bxc3+ 5. bxc3 b6 6. f3 Ba6 7. e4 d5 8.
+cxd5 Bxf1 9. Kxf1 exd5 10. Bg5 h6 11. Qa4+ c6 12. Bh4 dxe4 13. Re1 g5 14.
+Bf2 Qe7 15. Ne2 b5 16. Qc2 Qxa3 17. h4 gxh4 18. Bxh4 Nbd7 19. Ng3 O-O-O 20.
+Nxe4 Rhe8 21. Kf2 Nxe4+ 22. fxe4 f6 23. Ra1 Qe7 24. Rxa7 Qxe4 25. Qxe4 Rxe4
+26. Ra8+ Nb8 27. Bg3 Kb7 28. Rha1 Rc8 29. R8a7+ Kb6 30. Bxb8 b4 31. Bd6
+bxc3 32. Bc5+ Kb5 33. R1a4 1-0
+
+[Event "?"]
+[Site "Wch"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Botvinnik, Mikhail"]
+[Black "Tal, M."]
+[Result "1-0"]
+
+1. c4 Nf6 2. Nc3 e6 3. d4 Bb4 4. e3 O-O 5. Bd3 d5 6. a3 dxc4 7. Bxc4 Bd6 8.
+Nf3 Nc6 9. Nb5 e5 10. Nxd6 Qxd6 11. dxe5 Qxd1+ 12. Kxd1 Ng4 13. Ke2 Ncxe5
+14. Bd5 c6 15. Be4 Be6 16. Nd2 Rad8 17. h3 Nf6 18. Bc2 Rd7 19. b3 Rfd8 20.
+Rd1 Nd3 21. Bxd3 Rxd3 22. Bb2 R3d7 23. Bxf6 gxf6 24. b4 Bf5 25. Nb3 Bd3+
+26. Ke1 b6 27. Rac1 Be4 28. f3 Rxd1+ 29. Rxd1 Rxd1+ 30. Kxd1 Bd5 31. Nd4 c5
+32. bxc5 bxc5 33. Nb5 a6 34. Nc7 Bc4 35. Ne8 f5 36. h4 Kf8 37. Nd6 Bf1 38.
+g3 Ke7 39. Nxf5+ Ke6 40. e4 Ke5 41. Kd2 1-0
+
+[Event "?"]
+[Site "Wch"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Botvinnik, Mikhail"]
+[Black "Tal, M."]
+[Result "1-0"]
+
+1. c4 Nf6 2. Nc3 e6 3. d4 Bb4 4. e3 O-O 5. Bd3 d5 6. a3 dxc4 7. Bxc4 Bd6 8.
+Nf3 Nc6 9. b4 e5 10. Bb2 Bg4 11. d5 Ne7 12. h3 Bd7 13. Ng5 Ng6 14. Ne6 fxe6
+15. dxe6 Kh8 16. exd7 Qxd7 17. O-O Qf5 18. Nd5 Ng8 19. Qg4 Qc2 20. Qe2 Qf5
+21. Qg4 Qc2 22. Qe2 Qf5 23. e4 Qd7 24. Rad1 Rad8 25. Qg4 Qe8 26. g3 Nh6 27.
+Qh5 Ng8 28. Qe2 N6e7 29. Ne3 Nh6 30. Ng4 Nxg4 31. hxg4 Nc6 32. Kg2 Be7 33.
+Bd5 Nd4 34. Bxd4 exd4 35. Bc4 c5 36. b5 Bf6 37. f4 d3 38. Rxd3 Rxd3 39.
+Bxd3 Bd4 40. e5 g6 41. Rh1 Kg7 42. Qe4 b6 43. Bc4 1-0
+
+[Event "WM Moskau"]
+[Site "?"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Botvinnik"]
+[Black "Tal, Mikhail N."]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. Nc3 e6 3. d4 Bb4 4. e3 O-O 5. Bd3 d5 6. a3 dxc4 7. Bxc4 Bd6 8.
+Nf3 Nc6 9. b4 e5 10. Bb2 Bg4 11. dxe5 Nxe5 12. Be2 Qe7 13. Nb5 Rfd8 14. Qc2
+a6 15. Nxd6 cxd6 16. Qd1 Rac8 17. O-O Ne4 18. Nd4 Bxe2 19. Qxe2 Nc4 20.
+Rac1 d5 21. Qg4 Qd7 22. Qxd7 Rxd7 23. Rc2 Ned6 24. Rd1 Rdd8 25. Nb3 Nxb2
+26. Rxb2 Nc4 27. Ra2 b6 28. Kf1 f6 29. a4 Ne5 30. b5 Rc3 31. Nd4 Ra8 32.
+Rda1 a5 33. Rd1 Rac8 34. Nf5 R8c7 35. Rxd5 Kf7 36. Rd1 Ke6 37. Nd4+ Kf7 38.
+Ke2 R7c4 39. h3 Rb4 40. Nc2 Rbc4 41. Rd2 Ke7 42. Nd4 g6 43. Rd1 Nd7 44.
+Nc6+ Ke8 45. Rd6 Rc2+ 46. Rxc2 Rxc2+ 47. Kf3 Ra2 48. Re6+ Kf8 49. Rd6 Ke8
+50. Re6+ Kf8 51. Kg3 Rxa4 52. Re7 Nc5 53. Rxh7 Ne4+ 54. Kh2 Nd6 55. Rh8+
+Kf7 56. Rb8 Nc4 57. Rc8 Nd2 58. g4 Ra2 59. Rb8 Ne4 60. Rxb6 Rxf2+ 61. Kg1
+Rb2 62. Nxa5 Nd2 63. Nc6 Nc4 64. Rb7+ Ke6 65. h4 Kd5 66. Rd7+ Kc5 67. Rd3
+Kxb5 68. Nd4+ Kc5 69. Nf3 Re2 70. h5 gxh5 71. gxh5 Nxe3 72. h6 Rg2+ 73. Kh1
+Rg3 1/2-1/2
+
diff --git a/test/outfiles/test-RR-out.pgn b/test/outfiles/test-RR-out.pgn
new file mode 100644 (file)
index 0000000..3a059d0
--- /dev/null
@@ -0,0 +1,19 @@
+[Black "Horton, Mark"]
+[Date "1994.10.10"]
+[Event "Dover vs Herne Bay, Minor League"]
+[Result "1/2-1/2"]
+[Round ""]
+[Site "Margate Chess Club"]
+[White "Barnes, David J."]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/outfiles/test-SS-out.pgn b/test/outfiles/test-SS-out.pgn
new file mode 100644 (file)
index 0000000..cdcf62b
--- /dev/null
@@ -0,0 +1,49 @@
+[Event "?"]
+[Site "Zuerich"]
+[Date "1953.??.??"]
+[Round "?"]
+[White "Reshevsky, Samuel"]
+[Black "Petrosjan, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 d5 6. Nf3 c5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 b6 10. cxd5 exd5 11. Bb2 c4 12. Bc2 Bg4 13. Qe1 Ne4 14. Nd2
+Nxd2 15. Qxd2 Bh5 16. f3 Bg6 17. e4 Qd7 18. Rae1 dxe4 19. fxe4 Rfe8 20. Qf4
+b5 21. Bd1 Re7 22. Bg4 Qe8 23. e5 a5 24. Re3 Rd8 25. Rfe1 Re6 26. a4 Ne7
+27. Bxe6 fxe6 28. Qf1 Nd5 29. Rf3 Bd3 30. Rxd3 cxd3 31. Qxd3 b4 32. cxb4
+axb4 33. a5 Ra8 34. Ra1 Qc6 35. Bc1 Qc7 36. a6 Qb6 37. Bd2 b3 38. Qc4 h6
+39. h3 b2 40. Rb1 Kh8 41. Be1 1/2-1/2
+
+[Event "?"]
+[Site "Zuerich"]
+[Date "1953.??.??"]
+[Round "?"]
+[White "Smyslov, V."]
+[Black "Petrosjan, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 d5 6. Nf3 c5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 b6 10. cxd5 exd5 11. Bb2 c4 12. Bc2 Bg4 13. Qe1 Ne4 14. Nd2
+Nxd2 15. Qxd2 Bh5 16. f3 Bg6 17. e4 Qd7 18. Rae1 f5 19. exd5 Qxd5 20. a4
+Rfe8 21. Qg5 Qf7 22. Ba3 h6 23. Qg3 Rxe1 24. Rxe1 Re8 25. Rxe8+ Qxe8 26.
+Kf2 Na5 27. Qf4 Nb3 28. Bxf5 Bxf5 29. Qxf5 Qxa4 30. Qf8+ Kh7 31. Qf5+ Kg8
+32. Qe6+ Kh7 33. Qe4+ Kg8 34. Qa8+ Kh7 35. Qe4+ Kg8 36. Qd5+ Kh7 37. Be7
+Nc1 38. Qf5+ Kg8 39. Qf8+ Kh7 40. Qf5+ Kg8 41. d5 Qa2+ 42. Kg3 Qd2 43. d6
+Qe1+ 44. Kg4 Nd3 45. Qd5+ Kh7 46. d7 Qe5 47. Qxd3+ cxd3 48. d8=Q 1/2-1/2
+
+[Event "?"]
+[Site "Zuerich"]
+[Date "1953.??.??"]
+[Round "?"]
+[White "Taimanov, M."]
+[Black "Petrosjan, Tigran V."]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 b6 10. cxd5 exd5 11. Ne5 Qc7 12. Nxc6 Qxc6 13. f3 Be6 14.
+Qe1 Nd7 15. e4 c4 16. Bc2 f5 17. e5 Rf7 18. a4 a5 19. f4 b5 20. axb5 Qxb5
+21. Ba3 Nb6 22. Qh4 Qe8 23. Rf3 Nc8 24. Ba4 Rd7 25. Rb1 Qd8 26. Bxd7 Qxd7
+27. Rg3 Na7 28. Be7 Bf7 29. Qg5 Bg6 30. h4 Nc6 31. Ba3 Nd8 32. h5 Ne6 33.
+Qh4 Bf7 34. h6 g6 35. Qf6 Qd8 36. Be7 Qc7 37. Rxg6+ hxg6 38. h7+ Kxh7 39.
+Qxf7+ Ng7 40. Kf2 1-0
+
diff --git a/test/outfiles/test-TTa-out.pgn b/test/outfiles/test-TTa-out.pgn
new file mode 100644 (file)
index 0000000..02f0677
--- /dev/null
@@ -0,0 +1,20 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+[Annotator "Barnes, David J."]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/outfiles/test-TTb-out.pgn b/test/outfiles/test-TTb-out.pgn
new file mode 100644 (file)
index 0000000..fe33ef4
--- /dev/null
@@ -0,0 +1,83 @@
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
diff --git a/test/outfiles/test-TTd-out.pgn b/test/outfiles/test-TTd-out.pgn
new file mode 100644 (file)
index 0000000..27e2cd5
--- /dev/null
@@ -0,0 +1,100 @@
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
diff --git a/test/outfiles/test-TTdd-out.pgn b/test/outfiles/test-TTdd-out.pgn
new file mode 100644 (file)
index 0000000..3426c69
--- /dev/null
@@ -0,0 +1,111 @@
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
diff --git a/test/outfiles/test-TTp-out.pgn b/test/outfiles/test-TTp-out.pgn
new file mode 100644 (file)
index 0000000..fe33ef4
--- /dev/null
@@ -0,0 +1,83 @@
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
diff --git a/test/outfiles/test-TTr-out.pgn b/test/outfiles/test-TTr-out.pgn
new file mode 100644 (file)
index 0000000..31d4571
--- /dev/null
@@ -0,0 +1,83 @@
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
diff --git a/test/outfiles/test-TTw-out.pgn b/test/outfiles/test-TTw-out.pgn
new file mode 100644 (file)
index 0000000..5e5267d
--- /dev/null
@@ -0,0 +1,580 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
diff --git a/test/outfiles/test-UU-unique.pgn b/test/outfiles/test-UU-unique.pgn
new file mode 100644 (file)
index 0000000..2fda710
--- /dev/null
@@ -0,0 +1,46 @@
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
diff --git a/test/outfiles/test-VV-out.pgn b/test/outfiles/test-VV-out.pgn
new file mode 100644 (file)
index 0000000..63fbe6b
--- /dev/null
@@ -0,0 +1,18 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6 32. Bc5+ Kd7 33. Ba7 Kd6
+34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control } 1/2-1/2
+
diff --git a/test/outfiles/test-WWdeutsch-out.pgn b/test/outfiles/test-WWdeutsch-out.pgn
new file mode 100644 (file)
index 0000000..b007edb
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Lb2 d6 3. d4 exd4 4. Dxd4 Sc6 5. Dd2 Sf6 6. Sc3 Le6 7. e4 d5 8.
+exd5 Lxd5 9. De3+ Le7 10. Sf3 O-O 11. Le2 Te8 12. O-O-O Lb4 13. Dd3 Lxc3
+14. Lxc3 De7 15. The1 Se4 16. Lb2 Tad8 17. De3 b6 18. Lb5 De6 19. Sd4 Sxd4
+20. Txd4 c5 21. Txe4 Lxe4 22. Lxe8 { 2 minutes to time-control at move 36.
+} 22... Txe8 23. f3 Ld5 24. Dxe6 Txe6 25. Txe6 Lxe6 26. Kd2 Kf8 27. Le5 b5
+28. Lb8 $2 (28. Ld6+ { wins }) 28... a6 29. La7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Lc5+ Kd7 33. La7 Kd6 34. Lc5+ Kd7 35. Kc3 g6 36. Ld4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/outfiles/test-WWelalg-out.pgn b/test/outfiles/test-WWelalg-out.pgn
new file mode 100644 (file)
index 0000000..dcc5821
--- /dev/null
@@ -0,0 +1,20 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b2b3 e7e5 2. Bc1b2 d7d6 3. d2d4 e5d4 4. Qd1d4 Nb8c6 5. Qd4d2 Ng8f6 6.
+Nb1c3 Bc8e6 7. e2e4 d6d5 8. e4d5 Be6d5 9. Qd2e3+ Bf8e7 10. Ng1f3 e8g8 11.
+Bf1e2 Rf8e8 12. e1c1 Be7b4 13. Qe3d3 Bb4c3 14. Bb2c3 Qd8e7 15. Rh1e1 Nf6e4
+16. Bc3b2 Ra8d8 17. Qd3e3 b7b6 18. Be2b5 Qe7e6 19. Nf3d4 Nc6d4 20. Rd1d4
+c7c5 21. Rd4e4 Bd5e4 22. Bb5e8 { 2 minutes to time-control at move 36. }
+22... Rd8e8 23. f2f3 Be4d5 24. Qe3e6 Re8e6 25. Re1e6 Bd5e6 26. Kc1d2 Kg8f8
+27. Bb2e5 b6b5 28. Be5b8 $2 (28. Be5d6+ { wins }) 28... a7a6 29. Bb8a7 c5c4
+30. Kd2c3 Kf8e7 31. Kc3d4 Ke7d6 32. Ba7c5+ Kd6d7 33. Bc5a7 Kd7d6 34. Ba7c5+
+Kd6d7 35. Kd4c3 g7g6 36. Bc5d4 f7f5 { Time control. } 1/2-1/2
+
diff --git a/test/outfiles/test-WWhalg-out.pgn b/test/outfiles/test-WWhalg-out.pgn
new file mode 100644 (file)
index 0000000..5d9c5c2
--- /dev/null
@@ -0,0 +1,21 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b2-b3 e7-e5 2. c1-b2 d7-d6 3. d2-d4 e5-d4 4. d1-d4 b8-c6 5. d4-d2 g8-f6
+6. b1-c3 c8-e6 7. e2-e4 d6-d5 8. e4-d5 e6-d5 9. d2-e3+ f8-e7 10. g1-f3
+e8-g8 11. f1-e2 f8-e8 12. e1-c1 e7-b4 13. e3-d3 b4-c3 14. b2-c3 d8-e7 15.
+h1-e1 f6-e4 16. c3-b2 a8-d8 17. d3-e3 b7-b6 18. e2-b5 e7-e6 19. f3-d4 c6-d4
+20. d1-d4 c7-c5 21. d4-e4 d5-e4 22. b5-e8 { 2 minutes to time-control at
+move 36. } 22... d8-e8 23. f2-f3 e4-d5 24. e3-e6 e8-e6 25. e1-e6 d5-e6 26.
+c1-d2 g8-f8 27. b2-e5 b6-b5 28. e5-b8 $2 (28. e5-d6+ { wins }) 28... a7-a6
+29. b8-a7 c5-c4 30. d2-c3 f8-e7 31. c3-d4 e7-d6 32. a7-c5+ d6-d7 33. c5-a7
+d7-d6 34. a7-c5+ d6-d7 35. d4-c3 g7-g6 36. c5-d4 f7-f5 { Time control. }
+1/2-1/2
+
diff --git a/test/outfiles/test-WWlalg-out.pgn b/test/outfiles/test-WWlalg-out.pgn
new file mode 100644 (file)
index 0000000..e07e301
--- /dev/null
@@ -0,0 +1,20 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b2b3 e7e5 2. c1b2 d7d6 3. d2d4 e5d4 4. d1d4 b8c6 5. d4d2 g8f6 6. b1c3
+c8e6 7. e2e4 d6d5 8. e4d5 e6d5 9. d2e3+ f8e7 10. g1f3 e8g8 11. f1e2 f8e8
+12. e1c1 e7b4 13. e3d3 b4c3 14. b2c3 d8e7 15. h1e1 f6e4 16. c3b2 a8d8 17.
+d3e3 b7b6 18. e2b5 e7e6 19. f3d4 c6d4 20. d1d4 c7c5 21. d4e4 d5e4 22. b5e8
+{ 2 minutes to time-control at move 36. } 22... d8e8 23. f2f3 e4d5 24. e3e6
+e8e6 25. e1e6 d5e6 26. c1d2 g8f8 27. b2e5 b6b5 28. e5b8 $2 (28. e5d6+ {
+wins }) 28... a7a6 29. b8a7 c5c4 30. d2c3 f8e7 31. c3d4 e7d6 32. a7c5+ d6d7
+33. c5a7 d7d6 34. a7c5+ d6d7 35. d4c3 g7g6 36. c5d4 f7f5 { Time control. }
+1/2-1/2
+
diff --git a/test/outfiles/test-WWuci-out.pgn b/test/outfiles/test-WWuci-out.pgn
new file mode 100644 (file)
index 0000000..7d3d219
--- /dev/null
@@ -0,0 +1,10 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+b2b3 e7e5 c1b2 d7d6 d2d4 e5d4 d1d4 b8c6 d4d2 g8f6 b1c3 c8e6 e2e4 d6d5 e4d5 e6d5 d2e3 f8e7 g1f3 e8g8 f1e2 f8e8 e1c1 e7b4 e3d3 b4c3 b2c3 d8e7 h1e1 f6e4 c3b2 a8d8 d3e3 b7b6 e2b5 e7e6 f3d4 c6d4 d1d4 c7c5 d4e4 d5e4 b5e8 d8e8 f2f3 e4d5 e3e6 e8e6 e1e6 d5e6 c1d2 g8f8 b2e5 b6b5 e5b8 a7a6 b8a7 c5c4 d2c3 f8e7 c3d4 e7d6 a7c5 d6d7 c5a7 d7d6 a7c5 d6d7 d4c3 g7g6 c5d4 f7f5 1/2-1/2
+
diff --git a/test/outfiles/test-Wdeutsch-out.pgn b/test/outfiles/test-Wdeutsch-out.pgn
new file mode 100644 (file)
index 0000000..b007edb
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Lb2 d6 3. d4 exd4 4. Dxd4 Sc6 5. Dd2 Sf6 6. Sc3 Le6 7. e4 d5 8.
+exd5 Lxd5 9. De3+ Le7 10. Sf3 O-O 11. Le2 Te8 12. O-O-O Lb4 13. Dd3 Lxc3
+14. Lxc3 De7 15. The1 Se4 16. Lb2 Tad8 17. De3 b6 18. Lb5 De6 19. Sd4 Sxd4
+20. Txd4 c5 21. Txe4 Lxe4 22. Lxe8 { 2 minutes to time-control at move 36.
+} 22... Txe8 23. f3 Ld5 24. Dxe6 Txe6 25. Txe6 Lxe6 26. Kd2 Kf8 27. Le5 b5
+28. Lb8 $2 (28. Ld6+ { wins }) 28... a6 29. La7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Lc5+ Kd7 33. La7 Kd6 34. Lc5+ Kd7 35. Kc3 g6 36. Ld4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/outfiles/test-Welalg-out.pgn b/test/outfiles/test-Welalg-out.pgn
new file mode 100644 (file)
index 0000000..dcc5821
--- /dev/null
@@ -0,0 +1,20 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b2b3 e7e5 2. Bc1b2 d7d6 3. d2d4 e5d4 4. Qd1d4 Nb8c6 5. Qd4d2 Ng8f6 6.
+Nb1c3 Bc8e6 7. e2e4 d6d5 8. e4d5 Be6d5 9. Qd2e3+ Bf8e7 10. Ng1f3 e8g8 11.
+Bf1e2 Rf8e8 12. e1c1 Be7b4 13. Qe3d3 Bb4c3 14. Bb2c3 Qd8e7 15. Rh1e1 Nf6e4
+16. Bc3b2 Ra8d8 17. Qd3e3 b7b6 18. Be2b5 Qe7e6 19. Nf3d4 Nc6d4 20. Rd1d4
+c7c5 21. Rd4e4 Bd5e4 22. Bb5e8 { 2 minutes to time-control at move 36. }
+22... Rd8e8 23. f2f3 Be4d5 24. Qe3e6 Re8e6 25. Re1e6 Bd5e6 26. Kc1d2 Kg8f8
+27. Bb2e5 b6b5 28. Be5b8 $2 (28. Be5d6+ { wins }) 28... a7a6 29. Bb8a7 c5c4
+30. Kd2c3 Kf8e7 31. Kc3d4 Ke7d6 32. Ba7c5+ Kd6d7 33. Bc5a7 Kd7d6 34. Ba7c5+
+Kd6d7 35. Kd4c3 g7g6 36. Bc5d4 f7f5 { Time control. } 1/2-1/2
+
diff --git a/test/outfiles/test-Whalg-out.pgn b/test/outfiles/test-Whalg-out.pgn
new file mode 100644 (file)
index 0000000..5d9c5c2
--- /dev/null
@@ -0,0 +1,21 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b2-b3 e7-e5 2. c1-b2 d7-d6 3. d2-d4 e5-d4 4. d1-d4 b8-c6 5. d4-d2 g8-f6
+6. b1-c3 c8-e6 7. e2-e4 d6-d5 8. e4-d5 e6-d5 9. d2-e3+ f8-e7 10. g1-f3
+e8-g8 11. f1-e2 f8-e8 12. e1-c1 e7-b4 13. e3-d3 b4-c3 14. b2-c3 d8-e7 15.
+h1-e1 f6-e4 16. c3-b2 a8-d8 17. d3-e3 b7-b6 18. e2-b5 e7-e6 19. f3-d4 c6-d4
+20. d1-d4 c7-c5 21. d4-e4 d5-e4 22. b5-e8 { 2 minutes to time-control at
+move 36. } 22... d8-e8 23. f2-f3 e4-d5 24. e3-e6 e8-e6 25. e1-e6 d5-e6 26.
+c1-d2 g8-f8 27. b2-e5 b6-b5 28. e5-b8 $2 (28. e5-d6+ { wins }) 28... a7-a6
+29. b8-a7 c5-c4 30. d2-c3 f8-e7 31. c3-d4 e7-d6 32. a7-c5+ d6-d7 33. c5-a7
+d7-d6 34. a7-c5+ d6-d7 35. d4-c3 g7-g6 36. c5-d4 f7-f5 { Time control. }
+1/2-1/2
+
diff --git a/test/outfiles/test-Wlalg-out.pgn b/test/outfiles/test-Wlalg-out.pgn
new file mode 100644 (file)
index 0000000..e07e301
--- /dev/null
@@ -0,0 +1,20 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b2b3 e7e5 2. c1b2 d7d6 3. d2d4 e5d4 4. d1d4 b8c6 5. d4d2 g8f6 6. b1c3
+c8e6 7. e2e4 d6d5 8. e4d5 e6d5 9. d2e3+ f8e7 10. g1f3 e8g8 11. f1e2 f8e8
+12. e1c1 e7b4 13. e3d3 b4c3 14. b2c3 d8e7 15. h1e1 f6e4 16. c3b2 a8d8 17.
+d3e3 b7b6 18. e2b5 e7e6 19. f3d4 c6d4 20. d1d4 c7c5 21. d4e4 d5e4 22. b5e8
+{ 2 minutes to time-control at move 36. } 22... d8e8 23. f2f3 e4d5 24. e3e6
+e8e6 25. e1e6 d5e6 26. c1d2 g8f8 27. b2e5 b6b5 28. e5b8 $2 (28. e5d6+ {
+wins }) 28... a7a6 29. b8a7 c5c4 30. d2c3 f8e7 31. c3d4 e7d6 32. a7c5+ d6d7
+33. c5a7 d7d6 34. a7c5+ d6d7 35. d4c3 g7g6 36. c5d4 f7f5 { Time control. }
+1/2-1/2
+
diff --git a/test/outfiles/test-ZZ-dupes.pgn b/test/outfiles/test-ZZ-dupes.pgn
new file mode 100644 (file)
index 0000000..c852240
--- /dev/null
@@ -0,0 +1,50 @@
+{ From: infiles/petrosian.pgn }
+{ First found in: infiles/fischer.pgn }
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+{ First found in: infiles/fischer.pgn }
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+{ First found in: infiles/fischer.pgn }
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
diff --git a/test/outfiles/test-ZZ-unique.pgn b/test/outfiles/test-ZZ-unique.pgn
new file mode 100644 (file)
index 0000000..c0142c4
--- /dev/null
@@ -0,0 +1,1050 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
+[Event "?"]
+[Site "Sarajevo"]
+[Date "1972"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Hort"]
+[Result "1-0"]
+
+1. Nf3 c5 2. b3 d5 3. e3 Nf6 4. Bb2 e6 5. c4 Nc6 6. cxd5 exd5 7. Be2 Be7 8.
+O-O O-O 9. d4 Bg4 10. dxc5 Bxc5 11. Nc3 Rc8 12. Rc1 Be7 13. Nd4 Bxe2 14.
+Ncxe2 Qd7 15. Nf4 Rfd8 16. Qd3 Ne4 17. Nxc6 bxc6 18. Rc2 Bf8 19. Rfc1 Qb7
+20. Qe2 Re8 21. Qg4 g6 22. Qd1 Bd6 23. Nxd5 Rcd8 24. Rxc6 Qb8 25. f4 Re6
+26. Qd4 1-0
+
+[Event "?"]
+[Site "Buenos Aires m"]
+[Date "1971"]
+[Round "6"]
+[White "Petrosian, Tigran V."]
+[Black "Fischer, Robert J."]
+[Result "0-1"]
+
+1. Nf3 c5 2. b3 d5 3. Bb2 f6 4. c4 d4 5. d3 e5 6. e3 Ne7 7. Be2 Nec6 8.
+Nbd2 Be7 9. O-O O-O 10. e4 a6 11. Ne1 b5 12. Bg4 Bxg4 13. Qxg4 Qc8 14. Qe2
+Nd7 15. Nc2 Rb8 16. Rfc1 Qe8 17. Ba3 Bd6 18. Ne1 g6 19. cxb5 axb5 20. Bb2
+Nb6 21. Nef3 Ra8 22. a3 Na5 23. Qd1 Qf7 24. a4 bxa4 25. bxa4 c4 26. dxc4
+Nbxc4 27. Nxc4 Nxc4 28. Qe2 Nxb2 29. Qxb2 Rfb8 30. Qa2 Bb4 31. Qxf7+ Kxf7
+32. Rc7+ Ke6 33. g4 Bc3 34. Ra2 Rc8 35. Rxc8 Rxc8 36. a5 Ra8 37. a6 Ra7 38.
+Kf1 g5 39. Ke2 Kd6 40. Kd3 Kc5 41. Ng1 Kb5 42. Ne2 Ba5 43. Rb2+ Kxa6 44.
+Rb1 Rc7 45. Rb2 Be1 46. f3 Ka5 47. Rc2 Rb7 48. Ra2+ Kb5 49. Rb2+ Bb4 50.
+Ra2 Rc7 51. Ra1 Rc8 52. Ra7 Ba5 53. Rd7 Bb6 54. Rd5+ Bc5 55. Nc1 Ka4 56.
+Rd7 Bb4 57. Ne2 Kb3 58. Rb7 Ra8 59. Rxh7 Ra1 60. Nxd4+ exd4 61. Kxd4 Rd1+
+62. Ke3 Bc5+ 63. Ke2 Rh1 64. h4 Kc4 65. h5 Rh2+ 66. Ke1 Kd3 0-1
+
+[Event "?"]
+[Site "USSR 26/2"]
+[Date "1978"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Balashov,Y"]
+[Result "1-0"]
+
+1. b3 e5 2. Bb2 Nc6 3. c4 Nf6 4. e3 d5 5. cxd5 Nxd5 6. a3 Bd6 7. Qc2 O-O 8.
+Nf3 Qe7 9. Bd3 Kh8 10. Be4 Nb6 11. Bxc6 bxc6 12. d3 Bd7 13. Nbd2 f5 14. e4
+fxe4 15. dxe4 Rf4 16. Qc3 Re8 17. O-O c5 18. Kh1 Bc6 19. Rae1 Nd7 20. Ng1
+Nf6 21. f3 Nh5 22. g4 1-0
+
+[Event "?"]
+[Site "Tilburg 32/3"]
+[Date "1981"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Sosonko,G"]
+[Result "1-0"]
+
+1. c4 e5 2. b3 Nf6 3. Bb2 Nc6 4. e3 Be7 5. a3 O-O 6. Qc2 d5 7. cxd5 Nxd5 8.
+Nf3 Bf6 9. d3 g6 10. Nbd2 Bg7 11. Rc1 g5 12. Nc4 Qe7 13. b4 a6 14. Nfd2 f5
+15. Be2 g4 16. Nb3 Kh8 17. Nca5 Nxa5 18. Nxa5 Qf7 19. O-O c6 20. Nc4 Qe7
+21. Rfe1 Bd7 22. Bf1 Nc7 23. Nb6 Rad8 24. Qc5 Qxc5 25. Rxc5 Ne6 26. Rxe5
+Bxe5 27. Bxe5+ Kg8 28. d4 Be8 29. Nc4 b5 30. Nd6 Bd7 31. Rc1 Ng5 32. Nb7
+Rc8 33. Bd3 Ra8 34. Kf1 Be6 35. Bf4 Nf7 36. Ke2 Bd5 37. Bxf5 Ne5 38. Bxe5
+Rxf5 39. Nd6 Rff8 40. e4 Bc4+ 41. Nxc4 bxc4 42. Rxc4 a5 43. Bd6 Rfe8 44. e5
+axb4 45. Bxb4 1-0
+
+[Event "Tilburg Grandmaster Tournament"]
+[Site "Tilburg, NED"]
+[Date "1982.09.??"]
+[Round "2"]
+[White "Karpov, Anatoly"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nd2 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a3 a4 10. Ba2 h6 11. N5f3 c5 12. c3 Bd7 13. Ne5 cxd4 14. cxd4
+Be7 15. Ngf3 O-O 16. O-O Be8 17. Bd2 Nbd5 18. Rfc1 Qb6 19. Bc4 Bc6 20. Re1
+Nc7 21. Nxc6 bxc6 22. Bf4 Ncd5 23. Be5 Rfd8 24. Rad1 Bd6 25. Rd2 Bxe5 26.
+dxe5 Nd7 27. g3 Nf8 28. Red1 Rd7 29. Qe4 Rb7 30. Rc2 Rab8 31. Rdd2 Ne7 32.
+Kg2 Qa5 33. h4 Rd7 34. Be2 Rd5 35. Rd4 Rxd4 36. Qxd4 Nd5 37. Rxc6 Qa8 38.
+Rc4 Qb7 39. Rc2 Nb6 40. Bb5 Ng6 41. Qd6 Qa8 42. Bc6 1-0
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "15"]
+[White "Tal,M"]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rdg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Tilburg"]
+[Date "1982.??.??"]
+[Round "7"]
+[White "Nunn,John"]
+[Black "Petrosian,Tigran"]
+[Result "1-0"]
+
+1. e4 c6 2. c4 d5 3. exd5 cxd5 4. cxd5 Nf6 5. Nc3 Nxd5 6. Nf3 Nxc3 7. bxc3
+g6 8. d4 Bg7 9. Bd3 Nc6 10. O-O O-O 11. Re1 Bg4 12. Be4 Rc8 13. Bg5 Re8 14.
+Rb1 Qd7 15. h3 Bxf3 16. Bxf3 b6 17. Bg4 f5 18. Be2 h6 19. Bc1 Kh7 20. d5
+1-0
+
+[Event "?"]
+[Site "Bled"]
+[Date "1961.??.??"]
+[Round "17"]
+[White "Keres, Paul"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. N1e2 e6 7. h4 h6 8.
+Nf4 Bh7 9. c3 Nf6 10. Bd3 Bxd3 11. Nxd3 Bd6 12. Qf3 Nbd7 13. Bf4 Bxf4 14.
+Qxf4 Qb8 15. Qf3 Qd6 16. O-O-O Qd5 17. Qxd5 cxd5 18. f4 Ne4 19. Nxe4 dxe4
+20. Ne5 Rd8 21. h5 1/2-1/2
+
+[Event "?"]
+[Site "Piatgorsky Cup"]
+[Date "1963.??.??"]
+[Round "1"]
+[White "Keres, Paul"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Bc4 e6 7. N1e2 Nf6
+8. Nf4 Bd6 9. Bb3 Nbd7 10. Qf3 Qc7 11. h4 O-O-O 12. h5 Bf5 13. Nxf5 Qa5+
+14. c3 Qxf5 15. Qd3 Qxd3 16. Nxd3 h6 17. Rh4 Rhe8 18. Be3 Nd5 19. O-O-O
+Nxe3 20. fxe3 Nf6 21. Rf1 Re7 22. Nf2 Bg3 23. Rh3 Bd6 24. Bc2 e5 25. Nd3
+exd4 26. exd4 Re2 27. g4 Rde8 28. Bd1 R2e3 29. Rxe3 Rxe3 30. Rf3 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "1"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 Qc7 10. Bd2 e6 11. O-O-O O-O-O 12. c4 Ngf6 13. Kb1 c5 14.
+Bc3 cxd4 15. Nxd4 a6 16. Nf3 Bc5 17. Qe2 Bd6 18. Ne4 Be7 19. Nxf6 Bxf6 20.
+Bxf6 Nxf6 21. Ne5 Rxd1+ 22. Rxd1 Rd8 23. Rxd8+ Kxd8 24. Qd3+ Ke7 25. Qd4 h5
+26. a3 Nd7 27. Nxd7 Qxd7 28. Qc5+ Qd6 29. Qg5+ Ke8 30. Qe3 Qc6 31. Qg3 g6
+32. b3 Qe4+ 33. Kb2 e5 34. Qe3 Qxg2 35. Qxe5+ Kf8 36. Qh8+ Ke7 37. Qe5+
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "3"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bc4 Nf6 9. O-O O-O 10. Qe2 Nc6 11. Be3 Na5 12. Bd3 b6 13. Bg5 Bb7 14.
+Rad1 Rc8 15. Rfe1 h6 16. Bc1 Bb4 17. Bd2 Bxc3 18. bxc3 Qd5 19. Qf1 Qxa2 20.
+Ne5 Nb3 21. Re2 Nxd2 22. Rexd2 Qd5 23. c4 Qd6 24. Qe2 Rfd8 25. h3 Nd7 26.
+Ng4 h5 27. Ne3 g6 28. Ra2 Ra8 29. Qc2 Kg7 30. Be4 Bxe4 31. Qxe4 Nf6 32. Qh4
+Rd7 33. Rad2 Rad8 34. Rd3 a6 35. Qg5 Ne4 36. Qh4 Nf6 37. Rb3 Qc7 38. d5 Qe5
+39. Rxb6 exd5 40. Nxd5 Nxd5 41. cxd5 Rxd5 42. Qxd8 Rxd8 43. Rxd8 Qe1+
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "5"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. g3 Na6 9. Bg2 Qb6 10. Qxb6 axb6 11. Nge2 Nb4 12. O-O Rd8 13. d6 Rxd6 14.
+Bf4 Rd7 15. Rfd1 Nbd5 16. Be5 Bh6 17. a3 e6 18. Nxd5 Nxd5 19. Rd3 Bg5 20.
+Bxd5 exd5 21. h4 Bd8 22. Rc1 Re7 23. Nf4 Be6 24. Rdc3 Bd7 25. Nxd5 Re6 26.
+Bc7 Kg7 27. Bxd8 Rxd8 28. Ne3 b5 29. d5 Rb6 30. Nc2 h6 31. Nb4 g5 32. hxg5
+hxg5 33. Kg2 Rf6 34. Re3 Rh8 35. Nd3 Rd6 36. Ne5 Bh3+ 37. Kf3 Rxd5 38. Rc7
+Be6 39. Rxb7 Rc5 40. Ra7 Bd5+ 41. Kg4 Rc2 42. Kxg5 Rxf2 43. Nd3 Rf3 44.
+Rae7 Rxe3 45. Rxe3 f6+ 46. Kf4 Kf7 47. Nb4 Bc4 48. Rc3 Rh2 49. b3 Be6 50.
+Nd3 Ra2 51. Rc7+ Kg6 52. Nc5 Bf7 53. Rb7 Rxa3 54. Rxb5 Ra1 55. Ne4 Rf1+ 56.
+Ke3 Re1+ 57. Kf3 Rf1+ 58. Ke2 Rb1 59. Nd2 Rg1 60. Kf2 Rc1 61. b4 Rc2 62.
+Ke3 Rc3+ 63. Kf4 Rd3 64. Nf3 Bd5 65. Nh4+ Kf7 66. Rb8 Rd4+ 67. Ke3 Re4+ 68.
+Kf2 Ke7 69. Ng6+ Kd7 70. Nf4 Bc6 71. Nd3 Kc7 72. Rf8 Bb5 73. Nf4 Kd7 74.
+Rf7+ Ke8 75. Rb7 Rxb4 76. Nd5 Rb2+ 77. Ke3 Rb3+ 78. Kf4 Bc4 79. Nxf6+ Kf8
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "9"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bd3 Nc6 9. O-O O-O 10. Re1 Bf6 11. Be4 Nce7 12. Qc2 g6 13. Bh6 Bg7 14.
+Bg5 f6 15. Bd2 Bd7 16. Qb3 Bc6 17. Bxd5 exd5 18. Ne4 Rf7 19. Nc5 Nf5 20. h3
+Bf8 21. Ne6 Qd7 22. Nxf8 Rfxf8 23. Bb4 Rfe8 24. Rxe8+ Rxe8 25. Re1 Rxe1+
+26. Bxe1 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "13"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+h5 Bh7 9. Bd3 Bxd3 10. Qxd3 Qc7 11. Bd2 e6 12. Qe2 Ngf6 13. O-O-O O-O-O 14.
+Ne5 Nxe5 15. dxe5 Nd7 16. f4 Be7 17. Ne4 Nc5 18. Nc3 f6 19. exf6 Bxf6 20.
+Qc4 Qb6 21. b4 Na6 22. Ne4 Nc7 23. Rhe1 Rd4 24. Qb3 Qb5 25. c3 Rxe4 26.
+Rxe4 Qxh5 27. Qc4 Qf5 28. Qe2 h5 29. Be1 Re8 30. g3 a5 31. bxa5 Qxa5 32.
+Qc2 Qf5 33. Ra4 g5 34. fxg5 Bxg5+ 35. Kb1 Qxc2+ 36. Kxc2 e5 37. Re4 Nd5 38.
+Bf2 Nf6 39. Ra4 Kc7 40. Bc5 Nd5 41. Re4 b6 42. Bg1 Bd8 43. Rf1 Nf6 44. Re2
+c5 45. Rf5 Kd6 46. a4 Kd5 47. Kd3 Ng4 48. Rb2 Rh8 49. a5 c4+ 50. Ke2 Ke4
+51. Rf7 bxa5 52. Rb8 a4 53. Rc8 Bf6 54. Rxc4+ Kf5 55. Ra7 a3 56. Rxa3 Rb8
+57. Rb4 Rc8 58. c4 Be7 59. c5 e4 60. Ra7 Bf6 61. Rh7 Kg6 62. Rd7 Kf5 63.
+Rd5+ Be5 64. Rb6 e3 65. Kf3 Nf6 66. Rd3 Rxc5 67. Bxe3 Rc2 68. Rd8 Rc3 69.
+Ke2 Rc2+ 70. Kd1 Rc3 71. Bf2 Ne4 72. Rf8+ Kg5 73. Rb5 Rd3+ 74. Ke2 Rd5 75.
+Rxd5 Nc3+ 76. Kf3 Nxd5 77. Ra8 Kf5 78. Ra5 Ke6 79. Be1 Nf6 80. Rb5 Nd5 81.
+Bd2 Bg7 82. Bc1 Be5 83. Bb2 Bc7 84. Rc5 Bd6 85. Rc1 Ne7 86. Re1+ Kf5 87.
+Ra1 Nc6 88. Ra6 Be5 89. Rxc6 Bxb2 90. Rc5+ Kg6 91. Kf4 1-0
+
+[Event "?"]
+[Site "URS"]
+[Date "1966.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bc4 O-O 9. O-O Nc6 10. Re1 Bf6 11. Ne4 b6 12. a3 Bb7 13. Qd3 Rc8 14.
+Nfg5 Bxg5 15. Bxg5 f6 16. Bd2 Qd7 17. Rad1 Nce7 18. Ba2 Rfe8 19. Bb1 Ng6
+20. Qg3 f5 21. Qd6 Rcd8 22. Qxd7 Rxd7 23. Ng5 Rde7 24. Ba2 h6 25. Nf3 Rc7
+26. Rc1 Rxc1 27. Rxc1 Rc8 28. Rxc8+ Bxc8 29. h4 Bb7 1/2-1/2
+
+[Event "Moskva tt"]
+[Site "?"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nd7 7. Bc4 e6
+8. O-O Ngf6 9. Ng5 h6 10. Nh3 Bd6 11. Nf4 Bxf4 12. Bxf4 Nd5 13. Bc1 Qh4 14.
+Bd3 Bxd3 15. Qxd3 O-O-O 16. Rd1 N7f6 17. c4 Nc7 18. b4 Rd7 19. Bb2 Rhd8 20.
+Qe2 Qg4 21. f3 Qg6 22. a4 h5 23. b5 h4 24. bxc6 bxc6 25. Ne4 Nxe4 26. fxe4
+h3 27. g3 f5 28. e5 c5 29. dxc5 Rxd1+ 30. Rxd1 Rxd1+ 31. Qxd1 Qe8 32. Qd6
+Kb7 33. c6+ Qxc6 34. Qxc6+ Kxc6 35. Bd4 a5 36. Bc3 Na6 37. Bxa5 Nc5 38. Bb4
+Nxa4 39. g4 fxg4 40. Kf2 Nb2 41. Kg3 Nxc4 42. Kxg4 Nxe5+ 43. Kxh3 Kd5 44.
+Kh4 Kc4 45. Bd6 Nf7 46. Bc7 g6 47. Kg4 Kd5 48. h4 Ke4 49. h5 Ne5+ 1/2-1/2
+
+[Event "URS-ch"]
+[Site "?"]
+[Date "1973.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rhg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "2"]
+[White "Petrosian, Tigran V."]
+[Black "Kuzmin,G"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O dxc4 8.
+Bxc4 a6 9. a3 Ba5 10. dxc5 Bxc3 11. bxc3 Qa5 12. a4 Nbd7 13. c6 bxc6 14.
+Qc2 c5 15. e4 Qc7 16. Re1 Ng4 17. Kh1 Re8 18. h3 Ngf6 19. e5 Nd5 20. Ng5
+Nf8 21. f4 Bb7 22. Ne4 Ng6 23. Qf2 Nb6 24. Bf1 Bxe4 25. Rxe4 Qc6 26. Qc2
+Nd5 27. a5 Red8 28. Kh2 Rab8 29. Rea4 Nge7 30. Bd3 Nf5 31. Bxf5 exf5 32.
+Qxf5 Nxc3 33. Rc4 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "10"]
+[White "Petrosian, Tigran V."]
+[Black "Smyslov,V"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 b6 6. Ne2 Nc6 7. O-O cxd4 8.
+exd4 Bb7 9. d5 Ne5 10. Bf4 Nxd3 11. Qxd3 exd5 12. cxd5 O-O 13. a3 Bxc3 14.
+Nxc3 Re8 15. Bd6 Ng4 16. Qg3 Nh6 17. Rfe1 Nf5 18. Qf4 Qf6 19. Be5 Qg6 20.
+Qa4 a6 21. Bf4 b5 22. Qb4 Rec8 23. Qe4 h5 24. Qd3 Rc4 25. Re4 Nh4 26. Bg3
+Rxe4 27. Nxe4 Nxg2 28. Kxg2 h4 29. Rd1 hxg3 30. hxg3 Rc8 31. f3 f5 1/2-1/2
+
+[Event "?"]
+[Site "Tilburg"]
+[Date "1982.??.??"]
+[Round "10"]
+[White "Petrosian,Tigran"]
+[Black "Browne,Walter"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Nc3 Bb4 5. e3 O-O 6. Bd3 Bb7 7. O-O d5 8.
+a3 Bd6 9. cxd5 exd5 10. b4 a6 11. Qb3 Qe7 12. Rb1 Nbd7 13. a4 Ne4 14. Bb2
+Ndf6 15. b5 a5 16. Rbd1 Nxc3 17. Bxc3 Ne4 18. Bb2 Rad8 19. Ne5 Kh8 20. Qc2
+f6 21. Nf3 Bc8 22. Ne1 f5 23. g3 Rf6 24. Nf3 Rdf8 25. Ne5 Rh6 26. f3 Ng5
+27. Qg2 Nh3+ 28. Kh1 g5 29. g4 Qf6 30. Rd2 Rh4 31. Rc2 Qg7 32. gxf5 Bxf5
+33. Bxf5 Rxf5 34. Bc3 Rh6 35. Ng4 Rh5 36. Be1 Qe7 37. Bg3 Rf7 38. Rfc1 Kg7
+39. Rc6 Kf8 40. Bxd6 cxd6 41. Qg3 Rh4 42. Qxd6 1-0
+
+[Event "?"]
+[Site "Lone"]
+[Date "1978.??.??"]
+[Round "?"]
+[White "Portisch, Lajos"]
+[Black "Petrosian, Tigran"]
+[Result "0-1"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 b6 5. Bd3 Bb7 6. Nf3 O-O 7. O-O d5 8.
+a3 Bd6 9. b4 dxc4 10. Bxc4 Nbd7 11. Bb2 a5 12. b5 e5 13. Re1 e4 14. Nd2 Qe7
+15. Be2 Rad8 16. Qc2 Rfe8 17. f3 exf3 18. Bxf3 Bxf3 19. Nxf3 Ne4 20. Nxe4
+Qxe4 21. Qxe4 Rxe4 22. Nd2 Ree8 23. e4 Nc5 24. Nc4 Nxe4 25. Rac1 Bf8 26.
+Ne5 Nd6 27. a4 f6 28. Nf3 Rxe1+ 29. Nxe1 Rd7 30. Nf3 Nf5 31. Kf2 h5 32. Rc2
+g5 33. Rc4 Bd6 34. g3 Kf7 35. Ng1 Ne7 36. Ne2 Nd5 37. Bc1 Kg6 38. Rc2 Kf5
+39. Kf3 g4+ 40. Kf2 Rh7 41. Rd2 h4 42. Kg2 Ke4 43. Rd1 Ne3+ 44. Bxe3 Kxe3
+45. Nc3 h3+ 0-1
+
+[Event "?"]
+[Site "Milano"]
+[Date "1975.??.??"]
+[Round "1"]
+[White "Petrosian, Tigran"]
+[Black "Karpov, Anatoly"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 c5 6. Nf3 d5 7. O-O cxd4 8.
+exd4 dxc4 9. Bxc4 b6 10. Bg5 Bb7 11. Qe2 Bxc3 12. bxc3 Nbd7 13. Bd3 Qc7 14.
+c4 Ng4 15. Be4 Bxe4 16. Qxe4 Ngf6 17. Qd3 h6 18. Bxf6 Nxf6 19. a4 Rac8 20.
+Rfc1 Rfd8 21. h3 e5 22. Nxe5 Qxe5 23. dxe5 Rxd3 24. exf6 Rd4 25. a5 gxf6
+26. axb6 axb6 27. Rab1 Rcxc4 28. Rxc4 Rxc4 29. Rxb6 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1971.??.??"]
+[Round "1"]
+[White "Petrosian, Tigran"]
+[Black "Kortchnoi, Viktor"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 6. a3 Bxc3+ 7. bxc3
+O-O 8. Bg5 c5 9. e3 Nbd7 10. Bd3 Qa5 11. Ne2 b6 12. O-O Ba6 13. Bxa6 Qxa6
+14. Bxf6 Nxf6 15. Nf4 Qc4 16. Qa2 Qxa2 17. Rxa2 Rac8 18. a4 Rfd8 19. Rb1
+Ne4 20. Ne2 Nd6 21. h4 Nc4 22. Nf4 Kf8 23. g4 g6 24. Kg2 h6 25. Rd1 g5 26.
+hxg5 hxg5 27. Ne2 Nd6 28. Ng3 cxd4 29. Rxd4 Ne4 30. Nxe4 dxe4 31. Rxe4 Rxc3
+32. a5 Rdc8 33. axb6 axb6 34. Rb2 R3c4 35. Rxc4 Rxc4 1/2-1/2
+
+[Event "?"]
+[Site "Wch"]
+[Date "1963.??.??"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Botvinnik, Mikhail"]
+[Result "0-1"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 6. Bg5 h6 7. Bxf6 Qxf6
+8. a3 Bxc3+ 9. Qxc3 c6 10. e3 O-O 11. Ne2 Re8 12. Ng3 g6 13. f3 h5 14. Be2
+Nd7 15. Kf2 h4 16. Nf1 Nf8 17. Nd2 Re7 18. Rhe1 Bf5 19. h3 Rae8 20. Nf1 Ne6
+21. Qd2 Ng7 22. Rad1 Nh5 23. Rc1 Qd6 24. Rc3 Ng3 25. Kg1 Nh5 26. Bd1 Re6
+27. Qf2 Qe7 28. Bb3 g5 29. Bd1 Bg6 30. g4 hxg3 31. Nxg3 Nf4 32. Qh2 c5 33.
+Qd2 c4 34. Ba4 b5 35. Bc2 Nxh3+ 36. Kf1 Qf6 37. Kg2 Nf4+ 38. exf4 Rxe1 39.
+fxg5 Qe6 40. f4 Re2+ 0-1
+
+[Event "?"]
+[Site "Curacao ct"]
+[Date "1962.??.??"]
+[Round "3"]
+[White "Petrosian, Tigran V."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nf3 b6 4. Nc3 Bb4 5. e3 c5 6. Bd3 d5 7. dxc5 bxc5 8.
+O-O O-O 9. Ne2 Bb7 10. b3 Nbd7 11. Bb2 Qe7 12. Ng3 g6 13. cxd5 exd5 14. a3
+Ba5 15. b4 cxb4 16. Qa4 Bb6 17. axb4 Ng4 18. Rfe1 Nde5 19. Nxe5 Nxe5 20.
+Rad1 Nxd3 21. Rxd3 Rfc8 22. b5 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "20"]
+[White "Petrosian, Tigran V."]
+[Black "Spassky, Boris"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 c5 6. Nf3 d5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 dxc4 10. Bxc4 Qc7 11. Bd3 e5 12. Qc2 Bg4 13. Nxe5 Nxe5 14.
+dxe5 Qxe5 15. f3 Bd7 16. a4 Rfe8 17. e4 c4 18. Be2 Be6 19. Be3 Qc7 20. Rab1
+Nd7 21. Rb5 b6 22. Rfb1 Qc6 23. Bd4 f6 24. Qa2 Kh8 25. Bf1 h6 26. h3 Rab8
+27. a5 Rb7 28. axb6 axb6 29. Qf2 Ra8 30. Qb2 Rba7 31. Bxb6 Ra2 32. Qb4 Rc2
+33. Bf2 Qc7 34. Qe7 Bxh3 35. gxh3 Rxf2 36. Kxf2 Qh2+ 37. Bg2 Ne5 38. Rb8+
+Rxb8 39. Rxb8+ Kh7 40. Rd8 Ng6 41. Qe6 1-0
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1969.??.??"]
+[Round "10"]
+[White "Petrosian, Tigran V."]
+[Black "Spassky, Boris"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 b6 6. Ne2 d5 7. O-O dxc4 8.
+Bxc4 Bb7 9. f3 c5 10. a3 cxd4 11. axb4 dxc3 12. Nxc3 Nc6 13. b5 Ne5 14. Be2
+Qc7 15. e4 Rfd8 16. Qe1 Qc5+ 17. Qf2 Qe7 18. Ra3 Ne8 19. Bf4 Ng6 20. Be3
+Nd6 21. Rfa1 Nc8 22. Bf1 f5 23. exf5 exf5 24. Ra4 Re8 25. Bd2 Qc5 26. Qxc5
+bxc5 27. Rc4 Re5 28. Na4 a6 29. Nxc5 axb5 30. Nxb7 Rxa1 31. Rxc8+ Kf7 32.
+Nd8+ Ke7 33. Nc6+ Kd7 34. Nxe5+ Kxc8 35. Nxg6 hxg6 36. Bc3 Rb1 37. Kf2 b4
+38. Bxg7 1-0
+
+[Event "?"]
+[Site "Milano"]
+[Date "1975.??.??"]
+[Round "2"]
+[White "Ljubojevic, Ljubomir"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. a3 Be7 6. Nf3 O-O 7. e3 b6 8.
+cxd5 exd5 9. b4 Re8 10. Bd3 Bb7 11. O-O Bd6 12. Bb2 a6 13. Ne5 c5 14. bxc5
+bxc5 15. Rab1 Qc7 16. h3 c4 1/2-1/2
+
+[Event "32nd ol"]
+[Site "Yerevan ARM"]
+[Date "1996.09.17"]
+[Round "02"]
+[White "Gostisa,L"]
+[Black "Petrosian,A"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. Nf3 e6 3. g3 d5 4. Bg2 Nbd7 5. O-O b5 6. b3 Bb7 7. c4 bxc4 8.
+bxc4 dxc4 9. Qa4 c5 10. Ba3 Qc7 11. Qxc4 Rc8 12. Rc1 Qb8 1/2-1/2
+
+[Event "?"]
+[Site "Belgrade"]
+[Date "1954.??.??"]
+[Round "?"]
+[White "Janosevic"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 e6 5. Nc3 Nf6 6. Bg5 Be7 7. Nf3 O-O 8.
+Rc1 a6 9. cxd5 exd5 10. Be2 Nc6 11. Ne5 Na5 12. O-O h6 13. Bh4 Bf5 14. Bf3
+Be6 15. Re1 Nc6 16. Ng6 fxg6 17. Rxe6 g5 18. Bg3 Qd7 19. Re1 Rae8 20. Be5
+Kh8 21. Qb3 g4 22. Bxd5 Nxd5 23. Nxd5 Bg5 24. Rcd1 Na5 25. Nb6 Qd8 26. Qa4
+Qxb6 27. Bxg7+ Kxg7 28. Rxe8 Nc6 29. Rxf8 Kxf8 30. d5 Ne5 31. d6 Qxb2 32.
+d7 Nf7 33. Qxg4 Qxa2 34. Qb4+ Be7 35. d8=Q+ Nxd8 36. Rxd8+ Kf7 37. Qf4+ Kg7
+38. Qg4+ Kf6 39. Rd1 b5 40. h4 Qe6 41. Qh5 Kg7 42. Rd3 Bd6 43. Qd1 Bc5 44.
+Rg3+ Kf6 45. Qa1+ Kf5 46. Qb1+ Ke5 47. Rg6 Qf7 48. Qe1+ Kd5 49. Rxa6 Qf4
+50. Qd1+ Kc4 51. Ra2 Bd4 52. Qe2+ Kb4 53. Qe1+ Kb3 54. Qb1+ Kc4 55. Rc2+
+Bc3 56. Re2 Bd4 57. Qc2+ Kd5 58. Qb3+ Kc5 59. g3 Qf6 60. Rc2+ Kb6 61. Kg2
+Qf5 62. Re2 Kc5 63. Qc2+ Qxc2 64. Rxc2+ Kd5 65. f4 b4 66. Kf3 b3 67. Rc1 b2
+68. Rd1 h5 69. g4 hxg4+ 70. Kxg4 Ke4 71. h5 Be3 72. Rb1 Bc1 73. h6 Bxf4 74.
+Re1+ 1-0
+
diff --git a/test/outfiles/test-a-out.pgn b/test/outfiles/test-a-out.pgn
new file mode 100644 (file)
index 0000000..fdb9a7b
--- /dev/null
@@ -0,0 +1,30 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "1/2-1/2"]
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6
+Bxe6 26. Kd2 Kf8 27. Be5 b5 28. Bb8 a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 1/2-1/2
+
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "1/2-1/2"]
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6
+Bxe6 26. Kd2 Kf8 27. Be5 b5 28. Bb8 a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 1/2-1/2
+
diff --git a/test/outfiles/test-addhashcode-out.pgn b/test/outfiles/test-addhashcode-out.pgn
new file mode 100644 (file)
index 0000000..1169cc9
--- /dev/null
@@ -0,0 +1,20 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+[HashCode "b8be77df"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/outfiles/test-b30-out.pgn b/test/outfiles/test-b30-out.pgn
new file mode 100644 (file)
index 0000000..7470979
--- /dev/null
@@ -0,0 +1,28 @@
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
diff --git a/test/outfiles/test-bl45-out.pgn b/test/outfiles/test-bl45-out.pgn
new file mode 100644 (file)
index 0000000..f495af6
--- /dev/null
@@ -0,0 +1,305 @@
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
diff --git a/test/outfiles/test-bu45-out.pgn b/test/outfiles/test-bu45-out.pgn
new file mode 100644 (file)
index 0000000..37d44e9
--- /dev/null
@@ -0,0 +1,275 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
diff --git a/test/outfiles/test-c-out.pgn b/test/outfiles/test-c-out.pgn
new file mode 100644 (file)
index 0000000..eb3f67e
--- /dev/null
@@ -0,0 +1,37 @@
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
diff --git a/test/outfiles/test-checkmate-out.pgn b/test/outfiles/test-checkmate-out.pgn
new file mode 100644 (file)
index 0000000..7c9f174
--- /dev/null
@@ -0,0 +1,10 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 Qh4# 0-1
+
diff --git a/test/outfiles/test-d-dupes.pgn b/test/outfiles/test-d-dupes.pgn
new file mode 100644 (file)
index 0000000..c852240
--- /dev/null
@@ -0,0 +1,50 @@
+{ From: infiles/petrosian.pgn }
+{ First found in: infiles/fischer.pgn }
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+{ First found in: infiles/fischer.pgn }
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+{ First found in: infiles/fischer.pgn }
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
diff --git a/test/outfiles/test-d-unique.pgn b/test/outfiles/test-d-unique.pgn
new file mode 100644 (file)
index 0000000..c0142c4
--- /dev/null
@@ -0,0 +1,1050 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
+[Event "?"]
+[Site "Sarajevo"]
+[Date "1972"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Hort"]
+[Result "1-0"]
+
+1. Nf3 c5 2. b3 d5 3. e3 Nf6 4. Bb2 e6 5. c4 Nc6 6. cxd5 exd5 7. Be2 Be7 8.
+O-O O-O 9. d4 Bg4 10. dxc5 Bxc5 11. Nc3 Rc8 12. Rc1 Be7 13. Nd4 Bxe2 14.
+Ncxe2 Qd7 15. Nf4 Rfd8 16. Qd3 Ne4 17. Nxc6 bxc6 18. Rc2 Bf8 19. Rfc1 Qb7
+20. Qe2 Re8 21. Qg4 g6 22. Qd1 Bd6 23. Nxd5 Rcd8 24. Rxc6 Qb8 25. f4 Re6
+26. Qd4 1-0
+
+[Event "?"]
+[Site "Buenos Aires m"]
+[Date "1971"]
+[Round "6"]
+[White "Petrosian, Tigran V."]
+[Black "Fischer, Robert J."]
+[Result "0-1"]
+
+1. Nf3 c5 2. b3 d5 3. Bb2 f6 4. c4 d4 5. d3 e5 6. e3 Ne7 7. Be2 Nec6 8.
+Nbd2 Be7 9. O-O O-O 10. e4 a6 11. Ne1 b5 12. Bg4 Bxg4 13. Qxg4 Qc8 14. Qe2
+Nd7 15. Nc2 Rb8 16. Rfc1 Qe8 17. Ba3 Bd6 18. Ne1 g6 19. cxb5 axb5 20. Bb2
+Nb6 21. Nef3 Ra8 22. a3 Na5 23. Qd1 Qf7 24. a4 bxa4 25. bxa4 c4 26. dxc4
+Nbxc4 27. Nxc4 Nxc4 28. Qe2 Nxb2 29. Qxb2 Rfb8 30. Qa2 Bb4 31. Qxf7+ Kxf7
+32. Rc7+ Ke6 33. g4 Bc3 34. Ra2 Rc8 35. Rxc8 Rxc8 36. a5 Ra8 37. a6 Ra7 38.
+Kf1 g5 39. Ke2 Kd6 40. Kd3 Kc5 41. Ng1 Kb5 42. Ne2 Ba5 43. Rb2+ Kxa6 44.
+Rb1 Rc7 45. Rb2 Be1 46. f3 Ka5 47. Rc2 Rb7 48. Ra2+ Kb5 49. Rb2+ Bb4 50.
+Ra2 Rc7 51. Ra1 Rc8 52. Ra7 Ba5 53. Rd7 Bb6 54. Rd5+ Bc5 55. Nc1 Ka4 56.
+Rd7 Bb4 57. Ne2 Kb3 58. Rb7 Ra8 59. Rxh7 Ra1 60. Nxd4+ exd4 61. Kxd4 Rd1+
+62. Ke3 Bc5+ 63. Ke2 Rh1 64. h4 Kc4 65. h5 Rh2+ 66. Ke1 Kd3 0-1
+
+[Event "?"]
+[Site "USSR 26/2"]
+[Date "1978"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Balashov,Y"]
+[Result "1-0"]
+
+1. b3 e5 2. Bb2 Nc6 3. c4 Nf6 4. e3 d5 5. cxd5 Nxd5 6. a3 Bd6 7. Qc2 O-O 8.
+Nf3 Qe7 9. Bd3 Kh8 10. Be4 Nb6 11. Bxc6 bxc6 12. d3 Bd7 13. Nbd2 f5 14. e4
+fxe4 15. dxe4 Rf4 16. Qc3 Re8 17. O-O c5 18. Kh1 Bc6 19. Rae1 Nd7 20. Ng1
+Nf6 21. f3 Nh5 22. g4 1-0
+
+[Event "?"]
+[Site "Tilburg 32/3"]
+[Date "1981"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Sosonko,G"]
+[Result "1-0"]
+
+1. c4 e5 2. b3 Nf6 3. Bb2 Nc6 4. e3 Be7 5. a3 O-O 6. Qc2 d5 7. cxd5 Nxd5 8.
+Nf3 Bf6 9. d3 g6 10. Nbd2 Bg7 11. Rc1 g5 12. Nc4 Qe7 13. b4 a6 14. Nfd2 f5
+15. Be2 g4 16. Nb3 Kh8 17. Nca5 Nxa5 18. Nxa5 Qf7 19. O-O c6 20. Nc4 Qe7
+21. Rfe1 Bd7 22. Bf1 Nc7 23. Nb6 Rad8 24. Qc5 Qxc5 25. Rxc5 Ne6 26. Rxe5
+Bxe5 27. Bxe5+ Kg8 28. d4 Be8 29. Nc4 b5 30. Nd6 Bd7 31. Rc1 Ng5 32. Nb7
+Rc8 33. Bd3 Ra8 34. Kf1 Be6 35. Bf4 Nf7 36. Ke2 Bd5 37. Bxf5 Ne5 38. Bxe5
+Rxf5 39. Nd6 Rff8 40. e4 Bc4+ 41. Nxc4 bxc4 42. Rxc4 a5 43. Bd6 Rfe8 44. e5
+axb4 45. Bxb4 1-0
+
+[Event "Tilburg Grandmaster Tournament"]
+[Site "Tilburg, NED"]
+[Date "1982.09.??"]
+[Round "2"]
+[White "Karpov, Anatoly"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nd2 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a3 a4 10. Ba2 h6 11. N5f3 c5 12. c3 Bd7 13. Ne5 cxd4 14. cxd4
+Be7 15. Ngf3 O-O 16. O-O Be8 17. Bd2 Nbd5 18. Rfc1 Qb6 19. Bc4 Bc6 20. Re1
+Nc7 21. Nxc6 bxc6 22. Bf4 Ncd5 23. Be5 Rfd8 24. Rad1 Bd6 25. Rd2 Bxe5 26.
+dxe5 Nd7 27. g3 Nf8 28. Red1 Rd7 29. Qe4 Rb7 30. Rc2 Rab8 31. Rdd2 Ne7 32.
+Kg2 Qa5 33. h4 Rd7 34. Be2 Rd5 35. Rd4 Rxd4 36. Qxd4 Nd5 37. Rxc6 Qa8 38.
+Rc4 Qb7 39. Rc2 Nb6 40. Bb5 Ng6 41. Qd6 Qa8 42. Bc6 1-0
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "15"]
+[White "Tal,M"]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rdg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Tilburg"]
+[Date "1982.??.??"]
+[Round "7"]
+[White "Nunn,John"]
+[Black "Petrosian,Tigran"]
+[Result "1-0"]
+
+1. e4 c6 2. c4 d5 3. exd5 cxd5 4. cxd5 Nf6 5. Nc3 Nxd5 6. Nf3 Nxc3 7. bxc3
+g6 8. d4 Bg7 9. Bd3 Nc6 10. O-O O-O 11. Re1 Bg4 12. Be4 Rc8 13. Bg5 Re8 14.
+Rb1 Qd7 15. h3 Bxf3 16. Bxf3 b6 17. Bg4 f5 18. Be2 h6 19. Bc1 Kh7 20. d5
+1-0
+
+[Event "?"]
+[Site "Bled"]
+[Date "1961.??.??"]
+[Round "17"]
+[White "Keres, Paul"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. N1e2 e6 7. h4 h6 8.
+Nf4 Bh7 9. c3 Nf6 10. Bd3 Bxd3 11. Nxd3 Bd6 12. Qf3 Nbd7 13. Bf4 Bxf4 14.
+Qxf4 Qb8 15. Qf3 Qd6 16. O-O-O Qd5 17. Qxd5 cxd5 18. f4 Ne4 19. Nxe4 dxe4
+20. Ne5 Rd8 21. h5 1/2-1/2
+
+[Event "?"]
+[Site "Piatgorsky Cup"]
+[Date "1963.??.??"]
+[Round "1"]
+[White "Keres, Paul"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Bc4 e6 7. N1e2 Nf6
+8. Nf4 Bd6 9. Bb3 Nbd7 10. Qf3 Qc7 11. h4 O-O-O 12. h5 Bf5 13. Nxf5 Qa5+
+14. c3 Qxf5 15. Qd3 Qxd3 16. Nxd3 h6 17. Rh4 Rhe8 18. Be3 Nd5 19. O-O-O
+Nxe3 20. fxe3 Nf6 21. Rf1 Re7 22. Nf2 Bg3 23. Rh3 Bd6 24. Bc2 e5 25. Nd3
+exd4 26. exd4 Re2 27. g4 Rde8 28. Bd1 R2e3 29. Rxe3 Rxe3 30. Rf3 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "1"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 Qc7 10. Bd2 e6 11. O-O-O O-O-O 12. c4 Ngf6 13. Kb1 c5 14.
+Bc3 cxd4 15. Nxd4 a6 16. Nf3 Bc5 17. Qe2 Bd6 18. Ne4 Be7 19. Nxf6 Bxf6 20.
+Bxf6 Nxf6 21. Ne5 Rxd1+ 22. Rxd1 Rd8 23. Rxd8+ Kxd8 24. Qd3+ Ke7 25. Qd4 h5
+26. a3 Nd7 27. Nxd7 Qxd7 28. Qc5+ Qd6 29. Qg5+ Ke8 30. Qe3 Qc6 31. Qg3 g6
+32. b3 Qe4+ 33. Kb2 e5 34. Qe3 Qxg2 35. Qxe5+ Kf8 36. Qh8+ Ke7 37. Qe5+
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "3"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bc4 Nf6 9. O-O O-O 10. Qe2 Nc6 11. Be3 Na5 12. Bd3 b6 13. Bg5 Bb7 14.
+Rad1 Rc8 15. Rfe1 h6 16. Bc1 Bb4 17. Bd2 Bxc3 18. bxc3 Qd5 19. Qf1 Qxa2 20.
+Ne5 Nb3 21. Re2 Nxd2 22. Rexd2 Qd5 23. c4 Qd6 24. Qe2 Rfd8 25. h3 Nd7 26.
+Ng4 h5 27. Ne3 g6 28. Ra2 Ra8 29. Qc2 Kg7 30. Be4 Bxe4 31. Qxe4 Nf6 32. Qh4
+Rd7 33. Rad2 Rad8 34. Rd3 a6 35. Qg5 Ne4 36. Qh4 Nf6 37. Rb3 Qc7 38. d5 Qe5
+39. Rxb6 exd5 40. Nxd5 Nxd5 41. cxd5 Rxd5 42. Qxd8 Rxd8 43. Rxd8 Qe1+
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "5"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. g3 Na6 9. Bg2 Qb6 10. Qxb6 axb6 11. Nge2 Nb4 12. O-O Rd8 13. d6 Rxd6 14.
+Bf4 Rd7 15. Rfd1 Nbd5 16. Be5 Bh6 17. a3 e6 18. Nxd5 Nxd5 19. Rd3 Bg5 20.
+Bxd5 exd5 21. h4 Bd8 22. Rc1 Re7 23. Nf4 Be6 24. Rdc3 Bd7 25. Nxd5 Re6 26.
+Bc7 Kg7 27. Bxd8 Rxd8 28. Ne3 b5 29. d5 Rb6 30. Nc2 h6 31. Nb4 g5 32. hxg5
+hxg5 33. Kg2 Rf6 34. Re3 Rh8 35. Nd3 Rd6 36. Ne5 Bh3+ 37. Kf3 Rxd5 38. Rc7
+Be6 39. Rxb7 Rc5 40. Ra7 Bd5+ 41. Kg4 Rc2 42. Kxg5 Rxf2 43. Nd3 Rf3 44.
+Rae7 Rxe3 45. Rxe3 f6+ 46. Kf4 Kf7 47. Nb4 Bc4 48. Rc3 Rh2 49. b3 Be6 50.
+Nd3 Ra2 51. Rc7+ Kg6 52. Nc5 Bf7 53. Rb7 Rxa3 54. Rxb5 Ra1 55. Ne4 Rf1+ 56.
+Ke3 Re1+ 57. Kf3 Rf1+ 58. Ke2 Rb1 59. Nd2 Rg1 60. Kf2 Rc1 61. b4 Rc2 62.
+Ke3 Rc3+ 63. Kf4 Rd3 64. Nf3 Bd5 65. Nh4+ Kf7 66. Rb8 Rd4+ 67. Ke3 Re4+ 68.
+Kf2 Ke7 69. Ng6+ Kd7 70. Nf4 Bc6 71. Nd3 Kc7 72. Rf8 Bb5 73. Nf4 Kd7 74.
+Rf7+ Ke8 75. Rb7 Rxb4 76. Nd5 Rb2+ 77. Ke3 Rb3+ 78. Kf4 Bc4 79. Nxf6+ Kf8
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "9"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bd3 Nc6 9. O-O O-O 10. Re1 Bf6 11. Be4 Nce7 12. Qc2 g6 13. Bh6 Bg7 14.
+Bg5 f6 15. Bd2 Bd7 16. Qb3 Bc6 17. Bxd5 exd5 18. Ne4 Rf7 19. Nc5 Nf5 20. h3
+Bf8 21. Ne6 Qd7 22. Nxf8 Rfxf8 23. Bb4 Rfe8 24. Rxe8+ Rxe8 25. Re1 Rxe1+
+26. Bxe1 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "13"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+h5 Bh7 9. Bd3 Bxd3 10. Qxd3 Qc7 11. Bd2 e6 12. Qe2 Ngf6 13. O-O-O O-O-O 14.
+Ne5 Nxe5 15. dxe5 Nd7 16. f4 Be7 17. Ne4 Nc5 18. Nc3 f6 19. exf6 Bxf6 20.
+Qc4 Qb6 21. b4 Na6 22. Ne4 Nc7 23. Rhe1 Rd4 24. Qb3 Qb5 25. c3 Rxe4 26.
+Rxe4 Qxh5 27. Qc4 Qf5 28. Qe2 h5 29. Be1 Re8 30. g3 a5 31. bxa5 Qxa5 32.
+Qc2 Qf5 33. Ra4 g5 34. fxg5 Bxg5+ 35. Kb1 Qxc2+ 36. Kxc2 e5 37. Re4 Nd5 38.
+Bf2 Nf6 39. Ra4 Kc7 40. Bc5 Nd5 41. Re4 b6 42. Bg1 Bd8 43. Rf1 Nf6 44. Re2
+c5 45. Rf5 Kd6 46. a4 Kd5 47. Kd3 Ng4 48. Rb2 Rh8 49. a5 c4+ 50. Ke2 Ke4
+51. Rf7 bxa5 52. Rb8 a4 53. Rc8 Bf6 54. Rxc4+ Kf5 55. Ra7 a3 56. Rxa3 Rb8
+57. Rb4 Rc8 58. c4 Be7 59. c5 e4 60. Ra7 Bf6 61. Rh7 Kg6 62. Rd7 Kf5 63.
+Rd5+ Be5 64. Rb6 e3 65. Kf3 Nf6 66. Rd3 Rxc5 67. Bxe3 Rc2 68. Rd8 Rc3 69.
+Ke2 Rc2+ 70. Kd1 Rc3 71. Bf2 Ne4 72. Rf8+ Kg5 73. Rb5 Rd3+ 74. Ke2 Rd5 75.
+Rxd5 Nc3+ 76. Kf3 Nxd5 77. Ra8 Kf5 78. Ra5 Ke6 79. Be1 Nf6 80. Rb5 Nd5 81.
+Bd2 Bg7 82. Bc1 Be5 83. Bb2 Bc7 84. Rc5 Bd6 85. Rc1 Ne7 86. Re1+ Kf5 87.
+Ra1 Nc6 88. Ra6 Be5 89. Rxc6 Bxb2 90. Rc5+ Kg6 91. Kf4 1-0
+
+[Event "?"]
+[Site "URS"]
+[Date "1966.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bc4 O-O 9. O-O Nc6 10. Re1 Bf6 11. Ne4 b6 12. a3 Bb7 13. Qd3 Rc8 14.
+Nfg5 Bxg5 15. Bxg5 f6 16. Bd2 Qd7 17. Rad1 Nce7 18. Ba2 Rfe8 19. Bb1 Ng6
+20. Qg3 f5 21. Qd6 Rcd8 22. Qxd7 Rxd7 23. Ng5 Rde7 24. Ba2 h6 25. Nf3 Rc7
+26. Rc1 Rxc1 27. Rxc1 Rc8 28. Rxc8+ Bxc8 29. h4 Bb7 1/2-1/2
+
+[Event "Moskva tt"]
+[Site "?"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nd7 7. Bc4 e6
+8. O-O Ngf6 9. Ng5 h6 10. Nh3 Bd6 11. Nf4 Bxf4 12. Bxf4 Nd5 13. Bc1 Qh4 14.
+Bd3 Bxd3 15. Qxd3 O-O-O 16. Rd1 N7f6 17. c4 Nc7 18. b4 Rd7 19. Bb2 Rhd8 20.
+Qe2 Qg4 21. f3 Qg6 22. a4 h5 23. b5 h4 24. bxc6 bxc6 25. Ne4 Nxe4 26. fxe4
+h3 27. g3 f5 28. e5 c5 29. dxc5 Rxd1+ 30. Rxd1 Rxd1+ 31. Qxd1 Qe8 32. Qd6
+Kb7 33. c6+ Qxc6 34. Qxc6+ Kxc6 35. Bd4 a5 36. Bc3 Na6 37. Bxa5 Nc5 38. Bb4
+Nxa4 39. g4 fxg4 40. Kf2 Nb2 41. Kg3 Nxc4 42. Kxg4 Nxe5+ 43. Kxh3 Kd5 44.
+Kh4 Kc4 45. Bd6 Nf7 46. Bc7 g6 47. Kg4 Kd5 48. h4 Ke4 49. h5 Ne5+ 1/2-1/2
+
+[Event "URS-ch"]
+[Site "?"]
+[Date "1973.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rhg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "2"]
+[White "Petrosian, Tigran V."]
+[Black "Kuzmin,G"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O dxc4 8.
+Bxc4 a6 9. a3 Ba5 10. dxc5 Bxc3 11. bxc3 Qa5 12. a4 Nbd7 13. c6 bxc6 14.
+Qc2 c5 15. e4 Qc7 16. Re1 Ng4 17. Kh1 Re8 18. h3 Ngf6 19. e5 Nd5 20. Ng5
+Nf8 21. f4 Bb7 22. Ne4 Ng6 23. Qf2 Nb6 24. Bf1 Bxe4 25. Rxe4 Qc6 26. Qc2
+Nd5 27. a5 Red8 28. Kh2 Rab8 29. Rea4 Nge7 30. Bd3 Nf5 31. Bxf5 exf5 32.
+Qxf5 Nxc3 33. Rc4 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "10"]
+[White "Petrosian, Tigran V."]
+[Black "Smyslov,V"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 b6 6. Ne2 Nc6 7. O-O cxd4 8.
+exd4 Bb7 9. d5 Ne5 10. Bf4 Nxd3 11. Qxd3 exd5 12. cxd5 O-O 13. a3 Bxc3 14.
+Nxc3 Re8 15. Bd6 Ng4 16. Qg3 Nh6 17. Rfe1 Nf5 18. Qf4 Qf6 19. Be5 Qg6 20.
+Qa4 a6 21. Bf4 b5 22. Qb4 Rec8 23. Qe4 h5 24. Qd3 Rc4 25. Re4 Nh4 26. Bg3
+Rxe4 27. Nxe4 Nxg2 28. Kxg2 h4 29. Rd1 hxg3 30. hxg3 Rc8 31. f3 f5 1/2-1/2
+
+[Event "?"]
+[Site "Tilburg"]
+[Date "1982.??.??"]
+[Round "10"]
+[White "Petrosian,Tigran"]
+[Black "Browne,Walter"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Nc3 Bb4 5. e3 O-O 6. Bd3 Bb7 7. O-O d5 8.
+a3 Bd6 9. cxd5 exd5 10. b4 a6 11. Qb3 Qe7 12. Rb1 Nbd7 13. a4 Ne4 14. Bb2
+Ndf6 15. b5 a5 16. Rbd1 Nxc3 17. Bxc3 Ne4 18. Bb2 Rad8 19. Ne5 Kh8 20. Qc2
+f6 21. Nf3 Bc8 22. Ne1 f5 23. g3 Rf6 24. Nf3 Rdf8 25. Ne5 Rh6 26. f3 Ng5
+27. Qg2 Nh3+ 28. Kh1 g5 29. g4 Qf6 30. Rd2 Rh4 31. Rc2 Qg7 32. gxf5 Bxf5
+33. Bxf5 Rxf5 34. Bc3 Rh6 35. Ng4 Rh5 36. Be1 Qe7 37. Bg3 Rf7 38. Rfc1 Kg7
+39. Rc6 Kf8 40. Bxd6 cxd6 41. Qg3 Rh4 42. Qxd6 1-0
+
+[Event "?"]
+[Site "Lone"]
+[Date "1978.??.??"]
+[Round "?"]
+[White "Portisch, Lajos"]
+[Black "Petrosian, Tigran"]
+[Result "0-1"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 b6 5. Bd3 Bb7 6. Nf3 O-O 7. O-O d5 8.
+a3 Bd6 9. b4 dxc4 10. Bxc4 Nbd7 11. Bb2 a5 12. b5 e5 13. Re1 e4 14. Nd2 Qe7
+15. Be2 Rad8 16. Qc2 Rfe8 17. f3 exf3 18. Bxf3 Bxf3 19. Nxf3 Ne4 20. Nxe4
+Qxe4 21. Qxe4 Rxe4 22. Nd2 Ree8 23. e4 Nc5 24. Nc4 Nxe4 25. Rac1 Bf8 26.
+Ne5 Nd6 27. a4 f6 28. Nf3 Rxe1+ 29. Nxe1 Rd7 30. Nf3 Nf5 31. Kf2 h5 32. Rc2
+g5 33. Rc4 Bd6 34. g3 Kf7 35. Ng1 Ne7 36. Ne2 Nd5 37. Bc1 Kg6 38. Rc2 Kf5
+39. Kf3 g4+ 40. Kf2 Rh7 41. Rd2 h4 42. Kg2 Ke4 43. Rd1 Ne3+ 44. Bxe3 Kxe3
+45. Nc3 h3+ 0-1
+
+[Event "?"]
+[Site "Milano"]
+[Date "1975.??.??"]
+[Round "1"]
+[White "Petrosian, Tigran"]
+[Black "Karpov, Anatoly"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 c5 6. Nf3 d5 7. O-O cxd4 8.
+exd4 dxc4 9. Bxc4 b6 10. Bg5 Bb7 11. Qe2 Bxc3 12. bxc3 Nbd7 13. Bd3 Qc7 14.
+c4 Ng4 15. Be4 Bxe4 16. Qxe4 Ngf6 17. Qd3 h6 18. Bxf6 Nxf6 19. a4 Rac8 20.
+Rfc1 Rfd8 21. h3 e5 22. Nxe5 Qxe5 23. dxe5 Rxd3 24. exf6 Rd4 25. a5 gxf6
+26. axb6 axb6 27. Rab1 Rcxc4 28. Rxc4 Rxc4 29. Rxb6 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1971.??.??"]
+[Round "1"]
+[White "Petrosian, Tigran"]
+[Black "Kortchnoi, Viktor"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 6. a3 Bxc3+ 7. bxc3
+O-O 8. Bg5 c5 9. e3 Nbd7 10. Bd3 Qa5 11. Ne2 b6 12. O-O Ba6 13. Bxa6 Qxa6
+14. Bxf6 Nxf6 15. Nf4 Qc4 16. Qa2 Qxa2 17. Rxa2 Rac8 18. a4 Rfd8 19. Rb1
+Ne4 20. Ne2 Nd6 21. h4 Nc4 22. Nf4 Kf8 23. g4 g6 24. Kg2 h6 25. Rd1 g5 26.
+hxg5 hxg5 27. Ne2 Nd6 28. Ng3 cxd4 29. Rxd4 Ne4 30. Nxe4 dxe4 31. Rxe4 Rxc3
+32. a5 Rdc8 33. axb6 axb6 34. Rb2 R3c4 35. Rxc4 Rxc4 1/2-1/2
+
+[Event "?"]
+[Site "Wch"]
+[Date "1963.??.??"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Botvinnik, Mikhail"]
+[Result "0-1"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 6. Bg5 h6 7. Bxf6 Qxf6
+8. a3 Bxc3+ 9. Qxc3 c6 10. e3 O-O 11. Ne2 Re8 12. Ng3 g6 13. f3 h5 14. Be2
+Nd7 15. Kf2 h4 16. Nf1 Nf8 17. Nd2 Re7 18. Rhe1 Bf5 19. h3 Rae8 20. Nf1 Ne6
+21. Qd2 Ng7 22. Rad1 Nh5 23. Rc1 Qd6 24. Rc3 Ng3 25. Kg1 Nh5 26. Bd1 Re6
+27. Qf2 Qe7 28. Bb3 g5 29. Bd1 Bg6 30. g4 hxg3 31. Nxg3 Nf4 32. Qh2 c5 33.
+Qd2 c4 34. Ba4 b5 35. Bc2 Nxh3+ 36. Kf1 Qf6 37. Kg2 Nf4+ 38. exf4 Rxe1 39.
+fxg5 Qe6 40. f4 Re2+ 0-1
+
+[Event "?"]
+[Site "Curacao ct"]
+[Date "1962.??.??"]
+[Round "3"]
+[White "Petrosian, Tigran V."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nf3 b6 4. Nc3 Bb4 5. e3 c5 6. Bd3 d5 7. dxc5 bxc5 8.
+O-O O-O 9. Ne2 Bb7 10. b3 Nbd7 11. Bb2 Qe7 12. Ng3 g6 13. cxd5 exd5 14. a3
+Ba5 15. b4 cxb4 16. Qa4 Bb6 17. axb4 Ng4 18. Rfe1 Nde5 19. Nxe5 Nxe5 20.
+Rad1 Nxd3 21. Rxd3 Rfc8 22. b5 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "20"]
+[White "Petrosian, Tigran V."]
+[Black "Spassky, Boris"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 c5 6. Nf3 d5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 dxc4 10. Bxc4 Qc7 11. Bd3 e5 12. Qc2 Bg4 13. Nxe5 Nxe5 14.
+dxe5 Qxe5 15. f3 Bd7 16. a4 Rfe8 17. e4 c4 18. Be2 Be6 19. Be3 Qc7 20. Rab1
+Nd7 21. Rb5 b6 22. Rfb1 Qc6 23. Bd4 f6 24. Qa2 Kh8 25. Bf1 h6 26. h3 Rab8
+27. a5 Rb7 28. axb6 axb6 29. Qf2 Ra8 30. Qb2 Rba7 31. Bxb6 Ra2 32. Qb4 Rc2
+33. Bf2 Qc7 34. Qe7 Bxh3 35. gxh3 Rxf2 36. Kxf2 Qh2+ 37. Bg2 Ne5 38. Rb8+
+Rxb8 39. Rxb8+ Kh7 40. Rd8 Ng6 41. Qe6 1-0
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1969.??.??"]
+[Round "10"]
+[White "Petrosian, Tigran V."]
+[Black "Spassky, Boris"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 b6 6. Ne2 d5 7. O-O dxc4 8.
+Bxc4 Bb7 9. f3 c5 10. a3 cxd4 11. axb4 dxc3 12. Nxc3 Nc6 13. b5 Ne5 14. Be2
+Qc7 15. e4 Rfd8 16. Qe1 Qc5+ 17. Qf2 Qe7 18. Ra3 Ne8 19. Bf4 Ng6 20. Be3
+Nd6 21. Rfa1 Nc8 22. Bf1 f5 23. exf5 exf5 24. Ra4 Re8 25. Bd2 Qc5 26. Qxc5
+bxc5 27. Rc4 Re5 28. Na4 a6 29. Nxc5 axb5 30. Nxb7 Rxa1 31. Rxc8+ Kf7 32.
+Nd8+ Ke7 33. Nc6+ Kd7 34. Nxe5+ Kxc8 35. Nxg6 hxg6 36. Bc3 Rb1 37. Kf2 b4
+38. Bxg7 1-0
+
+[Event "?"]
+[Site "Milano"]
+[Date "1975.??.??"]
+[Round "2"]
+[White "Ljubojevic, Ljubomir"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. a3 Be7 6. Nf3 O-O 7. e3 b6 8.
+cxd5 exd5 9. b4 Re8 10. Bd3 Bb7 11. O-O Bd6 12. Bb2 a6 13. Ne5 c5 14. bxc5
+bxc5 15. Rab1 Qc7 16. h3 c4 1/2-1/2
+
+[Event "32nd ol"]
+[Site "Yerevan ARM"]
+[Date "1996.09.17"]
+[Round "02"]
+[White "Gostisa,L"]
+[Black "Petrosian,A"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. Nf3 e6 3. g3 d5 4. Bg2 Nbd7 5. O-O b5 6. b3 Bb7 7. c4 bxc4 8.
+bxc4 dxc4 9. Qa4 c5 10. Ba3 Qc7 11. Qxc4 Rc8 12. Rc1 Qb8 1/2-1/2
+
+[Event "?"]
+[Site "Belgrade"]
+[Date "1954.??.??"]
+[Round "?"]
+[White "Janosevic"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 e6 5. Nc3 Nf6 6. Bg5 Be7 7. Nf3 O-O 8.
+Rc1 a6 9. cxd5 exd5 10. Be2 Nc6 11. Ne5 Na5 12. O-O h6 13. Bh4 Bf5 14. Bf3
+Be6 15. Re1 Nc6 16. Ng6 fxg6 17. Rxe6 g5 18. Bg3 Qd7 19. Re1 Rae8 20. Be5
+Kh8 21. Qb3 g4 22. Bxd5 Nxd5 23. Nxd5 Bg5 24. Rcd1 Na5 25. Nb6 Qd8 26. Qa4
+Qxb6 27. Bxg7+ Kxg7 28. Rxe8 Nc6 29. Rxf8 Kxf8 30. d5 Ne5 31. d6 Qxb2 32.
+d7 Nf7 33. Qxg4 Qxa2 34. Qb4+ Be7 35. d8=Q+ Nxd8 36. Rxd8+ Kf7 37. Qf4+ Kg7
+38. Qg4+ Kf6 39. Rd1 b5 40. h4 Qe6 41. Qh5 Kg7 42. Rd3 Bd6 43. Qd1 Bc5 44.
+Rg3+ Kf6 45. Qa1+ Kf5 46. Qb1+ Ke5 47. Rg6 Qf7 48. Qe1+ Kd5 49. Rxa6 Qf4
+50. Qd1+ Kc4 51. Ra2 Bd4 52. Qe2+ Kb4 53. Qe1+ Kb3 54. Qb1+ Kc4 55. Rc2+
+Bc3 56. Re2 Bd4 57. Qc2+ Kd5 58. Qb3+ Kc5 59. g3 Qf6 60. Rc2+ Kb6 61. Kg2
+Qf5 62. Re2 Kc5 63. Qc2+ Qxc2 64. Rxc2+ Kd5 65. f4 b4 66. Kf3 b3 67. Rc1 b2
+68. Rd1 h5 69. g4 hxg4+ 70. Kxg4 Ke4 71. h5 Be3 72. Rb1 Bc1 73. h6 Bxf4 74.
+Re1+ 1-0
+
diff --git a/test/outfiles/test-e-out.pgn b/test/outfiles/test-e-out.pgn
new file mode 100644 (file)
index 0000000..37f76b6
--- /dev/null
@@ -0,0 +1,110 @@
+[Event "?"]
+[Site "Sarajevo"]
+[Date "1972"]
+[Round "?"]
+[White "Petrosian,T"]
+[Black "Hort"]
+[Result "1-0"]
+[ECO "A13"]
+[Opening "English"]
+[Variation "Wimpey system"]
+
+1. Nf3 c5 2. b3 d5 3. e3 Nf6 4. Bb2 e6 5. c4 Nc6 6. cxd5 exd5 7. Be2 Be7 8.
+O-O O-O 9. d4 Bg4 10. dxc5 Bxc5 11. Nc3 Rc8 12. Rc1 Be7 13. Nd4 Bxe2 14.
+Ncxe2 Qd7 15. Nf4 Rfd8 16. Qd3 Ne4 17. Nxc6 bxc6 18. Rc2 Bf8 19. Rfc1 Qb7
+20. Qe2 Re8 21. Qg4 g6 22. Qd1 Bd6 23. Nxd5 Rcd8 24. Rxc6 Qb8 25. f4 Re6
+26. Qd4 1-0
+
+[Event "?"]
+[Site "Buenos Aires m"]
+[Date "1971"]
+[Round "6"]
+[White "Petrosian,T"]
+[Black "Fischer,R"]
+[Result "0-1"]
+[ECO "A04"]
+[Opening "Reti opening"]
+
+1. Nf3 c5 2. b3 d5 3. Bb2 f6 4. c4 d4 5. d3 e5 6. e3 Ne7 7. Be2 Nec6 8.
+Nbd2 Be7 9. O-O O-O 10. e4 a6 11. Ne1 b5 12. Bg4 Bxg4 13. Qxg4 Qc8 14. Qe2
+Nd7 15. Nc2 Rb8 16. Rfc1 Qe8 17. Ba3 Bd6 18. Ne1 g6 19. cxb5 axb5 20. Bb2
+Nb6 21. Nef3 Ra8 22. a3 Na5 23. Qd1 Qf7 24. a4 bxa4 25. bxa4 c4 26. dxc4
+Nbxc4 27. Nxc4 Nxc4 28. Qe2 Nxb2 29. Qxb2 Rfb8 30. Qa2 Bb4 31. Qxf7+ Kxf7
+32. Rc7+ Ke6 33. g4 Bc3 34. Ra2 Rc8 35. Rxc8 Rxc8 36. a5 Ra8 37. a6 Ra7 38.
+Kf1 g5 39. Ke2 Kd6 40. Kd3 Kc5 41. Ng1 Kb5 42. Ne2 Ba5 43. Rb2+ Kxa6 44.
+Rb1 Rc7 45. Rb2 Be1 46. f3 Ka5 47. Rc2 Rb7 48. Ra2+ Kb5 49. Rb2+ Bb4 50.
+Ra2 Rc7 51. Ra1 Rc8 52. Ra7 Ba5 53. Rd7 Bb6 54. Rd5+ Bc5 55. Nc1 Ka4 56.
+Rd7 Bb4 57. Ne2 Kb3 58. Rb7 Ra8 59. Rxh7 Ra1 60. Nxd4+ exd4 61. Kxd4 Rd1+
+62. Ke3 Bc5+ 63. Ke2 Rh1 64. h4 Kc4 65. h5 Rh2+ 66. Ke1 Kd3 0-1
+
+[Event "Tilburg Grandmaster Tournament"]
+[Site "Tilburg, NED"]
+[Date "1982.09.??"]
+[Round "2"]
+[White "Karpov, Anatoly"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+[ECO "B17"]
+[Opening "Caro-Kann"]
+[Variation "Steinitz variation"]
+
+1. e4 c6 2. d4 d5 3. Nd2 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a3 a4 10. Ba2 h6 11. N5f3 c5 12. c3 Bd7 13. Ne5 cxd4 14. cxd4
+Be7 15. Ngf3 O-O 16. O-O Be8 17. Bd2 Nbd5 18. Rfc1 Qb6 19. Bc4 Bc6 20. Re1
+Nc7 21. Nxc6 bxc6 22. Bf4 Ncd5 23. Be5 Rfd8 24. Rad1 Bd6 25. Rd2 Bxe5 26.
+dxe5 Nd7 27. g3 Nf8 28. Red1 Rd7 29. Qe4 Rb7 30. Rc2 Rab8 31. Rdd2 Ne7 32.
+Kg2 Qa5 33. h4 Rd7 34. Be2 Rd5 35. Rd4 Rxd4 36. Qxd4 Nd5 37. Rxc6 Qa8 38.
+Rc4 Qb7 39. Rc2 Nb6 40. Bb5 Ng6 41. Qd6 Qa8 42. Bc6 1-0
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "15"]
+[White "Tal,M"]
+[Black "Petrosian,T"]
+[Result "0-1"]
+[ECO "B17"]
+[Opening "Caro-Kann"]
+[Variation "Steinitz variation"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rdg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "2"]
+[White "Petrosian,T"]
+[Black "Kuzmin,G"]
+[Result "1/2-1/2"]
+[ECO "E54"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3, Gligoric system with 7...dc"]
+
+1. c4 Nf6 2. d4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O dxc4 8.
+Bxc4 a6 9. a3 Ba5 10. dxc5 Bxc3 11. bxc3 Qa5 12. a4 Nbd7 13. c6 bxc6 14.
+Qc2 c5 15. e4 Qc7 16. Re1 Ng4 17. Kh1 Re8 18. h3 Ngf6 19. e5 Nd5 20. Ng5
+Nf8 21. f4 Bb7 22. Ne4 Ng6 23. Qf2 Nb6 24. Bf1 Bxe4 25. Rxe4 Qc6 26. Qc2
+Nd5 27. a5 Red8 28. Kh2 Rab8 29. Rea4 Nge7 30. Bd3 Nf5 31. Bxf5 exf5 32.
+Qxf5 Nxc3 33. Rc4 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "10"]
+[White "Petrosian,T"]
+[Black "Smyslov,V"]
+[Result "1/2-1/2"]
+[ECO "E41"]
+[Opening "Nimzo-Indian"]
+[Variation "4.e3 c5"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 b6 6. Ne2 Nc6 7. O-O cxd4 8.
+exd4 Bb7 9. d5 Ne5 10. Bf4 Nxd3 11. Qxd3 exd5 12. cxd5 O-O 13. a3 Bxc3 14.
+Nxc3 Re8 15. Bd6 Ng4 16. Qg3 Nh6 17. Rfe1 Nf5 18. Qf4 Qf6 19. Be5 Qg6 20.
+Qa4 a6 21. Bf4 b5 22. Qb4 Rec8 23. Qe4 h5 24. Qd3 Rc4 25. Re4 Nh4 26. Bg3
+Rxe4 27. Nxe4 Nxg2 28. Kxg2 h4 29. Rd1 hxg3 30. hxg3 Rc8 31. f3 f5 1/2-1/2
+
diff --git a/test/outfiles/test-evaluation-out.pgn b/test/outfiles/test-evaluation-out.pgn
new file mode 100644 (file)
index 0000000..f51e289
--- /dev/null
@@ -0,0 +1,10 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 { -0.10 } 1... e5 { -1.30 } 2. g4 { -0.90 } 2... Qh4# { -3.90 } 0-1
+
diff --git a/test/outfiles/test-f-out.pgn b/test/outfiles/test-f-out.pgn
new file mode 100644 (file)
index 0000000..0221248
--- /dev/null
@@ -0,0 +1,29 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 Qh4# 0-1
+
diff --git a/test/outfiles/test-fencomments-out.pgn b/test/outfiles/test-fencomments-out.pgn
new file mode 100644 (file)
index 0000000..2cf6123
--- /dev/null
@@ -0,0 +1,86 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 { rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq - 0 1 } 1...
+e5 { rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR w KQkq e6 0 2 } 2. Bb2
+{ rnbqkbnr/pppp1ppp/8/4p3/8/1P6/PBPPPPPP/RN1QKBNR b KQkq - 1 2 } 2... d6 {
+rnbqkbnr/ppp2ppp/3p4/4p3/8/1P6/PBPPPPPP/RN1QKBNR w KQkq - 0 3 } 3. d4 {
+rnbqkbnr/ppp2ppp/3p4/4p3/3P4/1P6/PBP1PPPP/RN1QKBNR b KQkq d3 0 3 } 3...
+exd4 { rnbqkbnr/ppp2ppp/3p4/8/3p4/1P6/PBP1PPPP/RN1QKBNR w KQkq - 0 4 } 4.
+Qxd4 { rnbqkbnr/ppp2ppp/3p4/8/3Q4/1P6/PBP1PPPP/RN2KBNR b KQkq - 0 4 } 4...
+Nc6 { r1bqkbnr/ppp2ppp/2np4/8/3Q4/1P6/PBP1PPPP/RN2KBNR w KQkq - 1 5 } 5.
+Qd2 { r1bqkbnr/ppp2ppp/2np4/8/8/1P6/PBPQPPPP/RN2KBNR b KQkq - 2 5 } 5...
+Nf6 { r1bqkb1r/ppp2ppp/2np1n2/8/8/1P6/PBPQPPPP/RN2KBNR w KQkq - 3 6 } 6.
+Nc3 { r1bqkb1r/ppp2ppp/2np1n2/8/8/1PN5/PBPQPPPP/R3KBNR b KQkq - 4 6 } 6...
+Be6 { r2qkb1r/ppp2ppp/2npbn2/8/8/1PN5/PBPQPPPP/R3KBNR w KQkq - 5 7 } 7. e4
+{ r2qkb1r/ppp2ppp/2npbn2/8/4P3/1PN5/PBPQ1PPP/R3KBNR b KQkq e3 0 7 } 7... d5
+{ r2qkb1r/ppp2ppp/2n1bn2/3p4/4P3/1PN5/PBPQ1PPP/R3KBNR w KQkq - 0 8 } 8.
+exd5 { r2qkb1r/ppp2ppp/2n1bn2/3P4/8/1PN5/PBPQ1PPP/R3KBNR b KQkq - 0 8 }
+8... Bxd5 { r2qkb1r/ppp2ppp/2n2n2/3b4/8/1PN5/PBPQ1PPP/R3KBNR w KQkq - 0 9 }
+9. Qe3+ { r2qkb1r/ppp2ppp/2n2n2/3b4/8/1PN1Q3/PBP2PPP/R3KBNR b KQkq - 1 9 }
+9... Be7 { r2qk2r/ppp1bppp/2n2n2/3b4/8/1PN1Q3/PBP2PPP/R3KBNR w KQkq - 2 10
+} 10. Nf3 { r2qk2r/ppp1bppp/2n2n2/3b4/8/1PN1QN2/PBP2PPP/R3KB1R b KQkq - 3
+10 } 10... O-O { r2q1rk1/ppp1bppp/2n2n2/3b4/8/1PN1QN2/PBP2PPP/R3KB1R w KQ -
+5 11 } 11. Be2 { r2q1rk1/ppp1bppp/2n2n2/3b4/8/1PN1QN2/PBP1BPPP/R3K2R b KQ -
+6 11 } 11... Re8 { r2qr1k1/ppp1bppp/2n2n2/3b4/8/1PN1QN2/PBP1BPPP/R3K2R w KQ
+- 7 12 } 12. O-O-O { r2qr1k1/ppp1bppp/2n2n2/3b4/8/1PN1QN2/PBP1BPPP/2KR3R b
+- - 9 12 } 12... Bb4 { r2qr1k1/ppp2ppp/2n2n2/3b4/1b6/1PN1QN2/PBP1BPPP/2KR3R
+w - - 10 13 } 13. Qd3 {
+r2qr1k1/ppp2ppp/2n2n2/3b4/1b6/1PNQ1N2/PBP1BPPP/2KR3R b - - 11 13 } 13...
+Bxc3 { r2qr1k1/ppp2ppp/2n2n2/3b4/8/1PbQ1N2/PBP1BPPP/2KR3R w - - 0 14 } 14.
+Bxc3 { r2qr1k1/ppp2ppp/2n2n2/3b4/8/1PBQ1N2/P1P1BPPP/2KR3R b - - 0 14 }
+14... Qe7 { r3r1k1/ppp1qppp/2n2n2/3b4/8/1PBQ1N2/P1P1BPPP/2KR3R w - - 1 15 }
+15. Rhe1 { r3r1k1/ppp1qppp/2n2n2/3b4/8/1PBQ1N2/P1P1BPPP/2KRR3 b - - 2 15 }
+15... Ne4 { r3r1k1/ppp1qppp/2n5/3b4/4n3/1PBQ1N2/P1P1BPPP/2KRR3 w - - 3 16 }
+16. Bb2 { r3r1k1/ppp1qppp/2n5/3b4/4n3/1P1Q1N2/PBP1BPPP/2KRR3 b - - 4 16 }
+16... Rad8 { 3rr1k1/ppp1qppp/2n5/3b4/4n3/1P1Q1N2/PBP1BPPP/2KRR3 w - - 5 17
+} 17. Qe3 { 3rr1k1/ppp1qppp/2n5/3b4/4n3/1P2QN2/PBP1BPPP/2KRR3 b - - 6 17 }
+17... b6 { 3rr1k1/p1p1qppp/1pn5/3b4/4n3/1P2QN2/PBP1BPPP/2KRR3 w - - 0 18 }
+18. Bb5 { 3rr1k1/p1p1qppp/1pn5/1B1b4/4n3/1P2QN2/PBP2PPP/2KRR3 b - - 1 18 }
+18... Qe6 { 3rr1k1/p1p2ppp/1pn1q3/1B1b4/4n3/1P2QN2/PBP2PPP/2KRR3 w - - 2 19
+} 19. Nd4 { 3rr1k1/p1p2ppp/1pn1q3/1B1b4/3Nn3/1P2Q3/PBP2PPP/2KRR3 b - - 3 19
+} 19... Nxd4 { 3rr1k1/p1p2ppp/1p2q3/1B1b4/3nn3/1P2Q3/PBP2PPP/2KRR3 w - - 0
+20 } 20. Rxd4 { 3rr1k1/p1p2ppp/1p2q3/1B1b4/3Rn3/1P2Q3/PBP2PPP/2K1R3 b - - 0
+20 } 20... c5 { 3rr1k1/p4ppp/1p2q3/1Bpb4/3Rn3/1P2Q3/PBP2PPP/2K1R3 w - c6 0
+21 } 21. Rxe4 { 3rr1k1/p4ppp/1p2q3/1Bpb4/4R3/1P2Q3/PBP2PPP/2K1R3 b - - 0 21
+} 21... Bxe4 { 3rr1k1/p4ppp/1p2q3/1Bp5/4b3/1P2Q3/PBP2PPP/2K1R3 w - - 0 22 }
+22. Bxe8 { 2 minutes to time-control at move 36. } {
+3rB1k1/p4ppp/1p2q3/2p5/4b3/1P2Q3/PBP2PPP/2K1R3 b - - 0 22 } 22... Rxe8 {
+4r1k1/p4ppp/1p2q3/2p5/4b3/1P2Q3/PBP2PPP/2K1R3 w - - 0 23 } 23. f3 {
+4r1k1/p4ppp/1p2q3/2p5/4b3/1P2QP2/PBP3PP/2K1R3 b - - 0 23 } 23... Bd5 {
+4r1k1/p4ppp/1p2q3/2pb4/8/1P2QP2/PBP3PP/2K1R3 w - - 1 24 } 24. Qxe6 {
+4r1k1/p4ppp/1p2Q3/2pb4/8/1P3P2/PBP3PP/2K1R3 b - - 0 24 } 24... Rxe6 {
+6k1/p4ppp/1p2r3/2pb4/8/1P3P2/PBP3PP/2K1R3 w - - 0 25 } 25. Rxe6 {
+6k1/p4ppp/1p2R3/2pb4/8/1P3P2/PBP3PP/2K5 b - - 0 25 } 25... Bxe6 {
+6k1/p4ppp/1p2b3/2p5/8/1P3P2/PBP3PP/2K5 w - - 0 26 } 26. Kd2 {
+6k1/p4ppp/1p2b3/2p5/8/1P3P2/PBPK2PP/8 b - - 1 26 } 26... Kf8 {
+5k2/p4ppp/1p2b3/2p5/8/1P3P2/PBPK2PP/8 w - - 2 27 } 27. Be5 {
+5k2/p4ppp/1p2b3/2p1B3/8/1P3P2/P1PK2PP/8 b - - 3 27 } 27... b5 {
+5k2/p4ppp/4b3/1pp1B3/8/1P3P2/P1PK2PP/8 w - - 0 28 } 28. Bb8 $2 {
+1B3k2/p4ppp/4b3/1pp5/8/1P3P2/P1PK2PP/8 b - - 1 28 } (28. Bd6+ { wins } {
+5k2/p4ppp/3Bb3/1pp5/8/1P3P2/P1PK2PP/8 b - - 1 28 }) 28... a6 {
+1B3k2/5ppp/p3b3/1pp5/8/1P3P2/P1PK2PP/8 w - - 0 29 } 29. Ba7 {
+5k2/B4ppp/p3b3/1pp5/8/1P3P2/P1PK2PP/8 b - - 1 29 } 29... c4 {
+5k2/B4ppp/p3b3/1p6/2p5/1P3P2/P1PK2PP/8 w - - 0 30 } 30. Kc3 {
+5k2/B4ppp/p3b3/1p6/2p5/1PK2P2/P1P3PP/8 b - - 1 30 } 30... Ke7 {
+8/B3kppp/p3b3/1p6/2p5/1PK2P2/P1P3PP/8 w - - 2 31 } 31. Kd4 {
+8/B3kppp/p3b3/1p6/2pK4/1P3P2/P1P3PP/8 b - - 3 31 } 31... Kd6 {
+8/B4ppp/p2kb3/1p6/2pK4/1P3P2/P1P3PP/8 w - - 4 32 } 32. Bc5+ {
+8/5ppp/p2kb3/1pB5/2pK4/1P3P2/P1P3PP/8 b - - 5 32 } 32... Kd7 {
+8/3k1ppp/p3b3/1pB5/2pK4/1P3P2/P1P3PP/8 w - - 6 33 } 33. Ba7 {
+8/B2k1ppp/p3b3/1p6/2pK4/1P3P2/P1P3PP/8 b - - 7 33 } 33... Kd6 {
+8/B4ppp/p2kb3/1p6/2pK4/1P3P2/P1P3PP/8 w - - 8 34 } 34. Bc5+ {
+8/5ppp/p2kb3/1pB5/2pK4/1P3P2/P1P3PP/8 b - - 9 34 } 34... Kd7 {
+8/3k1ppp/p3b3/1pB5/2pK4/1P3P2/P1P3PP/8 w - - 10 35 } 35. Kc3 {
+8/3k1ppp/p3b3/1pB5/2p5/1PK2P2/P1P3PP/8 b - - 11 35 } 35... g6 {
+8/3k1p1p/p3b1p1/1pB5/2p5/1PK2P2/P1P3PP/8 w - - 0 36 } 36. Bd4 {
+8/3k1p1p/p3b1p1/1p6/2pB4/1PK2P2/P1P3PP/8 b - - 1 36 } 36... f5 { Time
+control. } { 8/3k3p/p3b1p1/1p3p2/2pB4/1PK2P2/P1P3PP/8 w - f6 0 37 } 1/2-1/2
+
diff --git a/test/outfiles/test-l-out.pgn b/test/outfiles/test-l-out.pgn
new file mode 100644 (file)
index 0000000..5e5267d
--- /dev/null
@@ -0,0 +1,580 @@
+[Event "Milwaukee Northwestern"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Kampars, N."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 e6 6. d4 Nd7 7. Bd3 dxe4
+8. Nxe4 Ngf6 9. O-O Nxe4 10. Qxe4 Nf6 11. Qe3 Nd5 12. Qf3 Qf6 13. Qxf6 Nxf6
+14. Rd1 O-O-O 15. Be3 Nd5 16. Bg5 Be7 17. Bxe7 Nxe7 18. Be4 Nd5 19. g3 Nf6
+20. Bf3 Kc7 21. Kf1 Rhe8 22. Be2 e5 23. dxe5 Rxe5 24. Bc4 Rxd1+ 25. Rxd1
+Re7 26. Bb3 Ne4 27. Rd4 Nd6 28. c3 f6 29. Bc2 h6 30. Bd3 Nf7 31. f4 Rd7 32.
+Rxd7+ Kxd7 33. Kf2 Nd6 34. Kf3 f5 35. Ke3 c5 36. Be2 Ke6 37. Bd3 1/2-1/2
+
+[Event "US Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Addison, William G."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. Qe2+
+Qe7 8. Qxe7+ Kxe7 9. d4 Bf5 10. Bb3 Re8 11. Be3 Kf8 12. O-O-O Nd7 13. c4
+Rad8 14. Bc2 Bxc2 15. Kxc2 f5 16. Rhe1 f4 17. Bd2 Nf6 18. Ne5 g5 19. f3 Nh5
+20. Ng4 Kg7 21. Bc3 Kg6 22. Rxe8 Rxe8 23. c5 Bb8 24. d5 cxd5 25. Rxd5 f5
+26. Ne5+ Bxe5 27. Rxe5 Nf6 28. Rxe8 Nxe8 29. Be5 Kh5 30. Kd3 g4 31. b4 a6
+32. a4 gxf3 33. gxf3 Kh4 34. b5 axb5 35. a5 Kh3 36. c6 1-0
+
+[Event "West Orange Open"]
+[Site "?"]
+[Date "1957"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Goldsmith, Julius"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d6 3. d4 Nd7 4. Nf3 e5 5. Bc4 Be7 6. dxe5 Nxe5 7. Nxe5 dxe5
+8. Qh5 g6 9. Qxe5 Nf6 10. Bg5 Bd7 11. O-O-O O-O 12. Rxd7 Qxd7 13. Bxf6 Bxf6
+14. Qxf6 Rae8 15. f3 Qc7 16. h4 Qe5 17. Qxe5 Rxe5 18. Rd1 Re7 19. Rd6 Kg7
+20. a3 f5 21. Kd2 fxe4 22. Nxe4 Rf4 23. h5 gxh5 24. Rd8 h4 25. Rg8+ Kh6 26.
+Ke3 Rf5 27. Rg4 Rh5 28. Kf2 Rg7 29. Rxg7 Kxg7 30. Bf1 Rd5 31. Bd3 h6 32.
+Ke3 Rh5 33. Nd6 h3 34. gxh3 Rxh3 35. Nxb7 Rh5 36. b4 Re5+ 37. Kf4 Re7 38.
+Nd8 c5 39. bxc5 Kf6 40. c6 Rc7 41. Be4 Ke7 42. Nb7 Kf6 43. Nd6 Re7 44. c7
+1-0
+
+[Event "Bad Portoroz Interzonal"]
+[Site "?"]
+[Date "1958"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cardoso, Rudolfo T."]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Bg4 5. h3 Bxf3 6. Qxf3 Nd7 7. Ng5
+Ngf6 8. Qb3 e6 9. Qxb7 Nd5 10. Ne4 Nb4 11. Kd1 f5 12. c3 Rb8 13. Qxa7 fxe4
+14. cxb4 Bxb4 15. Qd4 O-O 16. Bc4 Nc5 17. Qxd8 Rbxd8 18. Rf1 Rd4 19. b3
+Bxd2 20. Ke2 Bxc1 21. Raxc1 Rfd8 22. Rfd1 Kf8 23. Rxd4 Rxd4 24. Rd1 Rxd1
+25. Kxd1 Ke7 26. Kd2 Kd6 27. Kc3 Nd7 28. Kd4 Nf6 29. a4 c5+ 30. Ke3 g5 31.
+Be2 Kc6 32. Bc4 e5 33. a5 h6 34. Kd2 h5 35. Ke3 h4 36. Be2 Kb7 37. Bc4 Kc6
+38. Ke2 Kb7 39. Kd2 Kc6 40. Ke3 Kb7 41. Kd2 Kc7 42. g4 Kc6 43. Kc3 Ne8 44.
+b4 Nd6 45. Bf1 cxb4+ 46. Kxb4 Nc8 47. Bg2 Kd5 48. a6 Na7 49. Ka5 Kc5 50.
+Bxe4 Nb5 51. Bg2 Na7 52. Ka4 Nb5 53. Kb3 Kb6 54. Kc4 Kxa6 55. Kd5 Kb6 56.
+Kxe5 Kc7 57. Kf6 Nc3 58. Kxg5 Nd1 59. f4 Kd6 60. Kxh4 Ke6 61. Kg5 Kf7 62.
+f5 1-0
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Weinstein, Raymond"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Be7 8.
+Bg2 dxe4 9. dxe4 e5 10. O-O Nbd7 11. Nd1 O-O 12. Ne3 g6 13. Rd1 Qc7 14. Ng4
+h5 15. Nxf6+ Nxf6 16. Bg5 Nh7 17. Bh6 Rfd8 18. Bf1 Bg5 19. Bxg5 Nxg5 20.
+Qe3 Qe7 21. h4 Ne6 22. Bc4 b5 23. Bxe6 Qxe6 24. Qc5 Qc4 25. Qxc4 bxc4 26.
+b3 Rd4 27. Rxd4 exd4 28. Kf1 Re8 29. f3 Re5 30. Rd1 c5 31. c3 dxc3 32. Rc1
+f5 33. exf5 Rxf5 34. Rxc3 cxb3 35. Rxb3 c4 36. Ra3 Rc5 37. Ke2 c3 38. Kd1
+c2+ 39. Kc1 a5 40. Rb3 Kg7 41. Rb7+ Kf6 42. Rb6+ Kg7 43. g4 1/2-1/2
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Benko, Pal"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Bxd2+ 12. Nxd2 Qc5 13. Qd1 h5 14. h4
+Nbd7 15. Bg2 Ng4 16. O-O g5 17. b4 Qe7 18. Nf3 gxh4 19. Nxh4 Nde5 20. Qd2
+Rg8 21. Qf4 f6 22. bxa5 Rxa5 23. Rfb1 b5 24. Nf3 Ra4 25. Bh3 Nxf3+ 26. Qxf3
+Kd7 27. Kg2 Qg7 28. Rb4 Rga8 29. Rxa4 Rxa4 30. Bxg4 hxg4 31. Qf4 Ra8 32.
+Rh1 Rg8 33. a4 bxa4 34. Rb1 e5 35. Rb7+ Kd6 36. Rxg7 exf4 37. Rxg8 f3+ 38.
+Kh1 Kc5 39. Rb8 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 Nbd7 11. Bg2 a5 12. a3 Bxd2+ 13. Nxd2 Qc5 14. Qd1
+h5 15. Nf3 Qc3+ 16. Ke2 Qc5 17. Qd2 Ne5 18. b4 Nxf3 19. Bxf3 Qe5 20. Qf4
+Nd7 21. Qxe5 Nxe5 22. bxa5 Kd7 23. Rhb1 Kc7 24. Rb4 Rxa5 25. Bg2 g5 26. f4
+gxf4 27. gxf4 Ng6 28. Kf3 Rg8 29. Bf1 e5 30. fxe5 Nxe5+ 31. Ke2 c5 32. Rb3
+b6 33. Rab1 Rg6 34. h4 Ra6 35. Bh3 Rg3 36. Bf1 Rg4 37. Bh3 Rxh4 38. Rh1 Ra8
+39. Rbb1 Rg8 40. Rbf1 Rg3 41. Bf5 Rg2+ 42. Kd1 Rhh2 43. Rxh2 Rxh2 44. Rg1
+c4 45. dxc4 Nxc4 46. Rg7 Kd6 47. Rxf7 Ne3+ 48. Kc1 Rxc2+ 49. Kb1 Rh2 50.
+Rd7+ Ke5 51. Re7+ Kf4 52. Rd7 Nd1 53. Kc1 Nc3 54. Bh7 h4 55. Rf7+ Ke3 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. g4 Bh2+ 29. Kg2 Nxg4 30. Nd2 Ne3+ 0-1
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Olafsson, Fridrik"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Nf6 4. e5 Ne4 5. Ne2 Qb6 6. d4 c5 7. dxc5 Qxc5 8.
+Ned4 Nc6 9. Bb5 a6 10. Bxc6+ bxc6 11. O-O Qb6 12. e6 fxe6 13. Bf4 g6 14.
+Be5 Nf6 15. Ng5 Bh6 16. Ndxe6 Bxg5 17. Nxg5 O-O 18. Qd2 Bf5 19. Rae1 Rad8
+20. Bc3 Rd7 21. Ne6 Bxe6 22. Rxe6 d4 23. Bb4 Nd5 24. Ba3 Rf7 25. g3 Nc7 26.
+Re5 Nd5 27. Qd3 Nf6 28. Qc4 Ng4 29. Re6 Qb5 30. Qxb5 axb5 31. Rxc6 Ne5 32.
+Rc8+ Kg7 33. Bb4 Nf3+ 34. Kg2 e5 35. Rd1 g5 36. Bf8+ Rxf8 37. Rxf8 Kxf8 38.
+Kxf3 Kf7 39. c3 Ke6 40. cxd4 exd4 41. Ke4 Rf7 42. f3 1-0
+
+[Event "Yugoslavia Candidate Trn"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Smyslov, Vasily V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bh5 5. exd5 cxd5 6. Bb5+ Nc6 7. g4 Bg6
+8. Ne5 Rc8 9. h4 f6 10. Nxg6 hxg6 11. d4 e6 12. Qd3 Kf7 13. h5 gxh5 14.
+gxh5 Nge7 15. Be3 Nf5 16. Bxc6 Rxc6 17. Ne2 Qa5+ 18. c3 Qa6 19. Qc2 Bd6 20.
+Bf4 Bxf4 21. Nxf4 Rh6 22. Qe2 Qxe2+ 23. Kxe2 Rh8 24. Kd3 b5 25. Rhe1 b4 26.
+cxb4 Rc4 27. Nxe6 Rxh5 28. b3 Rh3+ 29. Kd2 Rcc3 30. Nf4 Rhf3 31. Re2 g5 32.
+Nxd5 Rcd3+ 33. Kc1 Rxd4 34. Ne3 Nxe3 35. fxe3 Rxb4 36. Kd2 g4 37. Rc1 Rb7
+38. Rg1 Rd7+ 39. Kc2 f5 40. e4 Kf6 41. exf5 g3 42. Re8 Rg7 43. Rf8+ Ke7 44.
+Ra8 Kd6 45. Rf8 Rf2+ 46. Kd3 g2 47. f6 Rg3+ 48. Kc4 Ke6 49. Re1+ Kf5 50. f7
+Rg7 51. Rg1 Kf6 52. a4 Rxf7 1/2-1/2
+
+[Event "?"]
+[Site "Yugoslavia, Bled"]
+[Date "1959.??.??"]
+[Round "02"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 g5 14. Nf3
+h6 15. h4 Rg8 16. a3 Qe7 17. hxg5 hxg5 18. Qd2 Nd7 19. c3 O-O-O 20. cxd4
+exd4 21. b4 Kb8 22. Rfc1 Nce5 23. Nxe5 Qxe5 24. Rc4 Rc8 25. Rac1 g4 26. Qb2
+Rgd8 27. a4 Qe7 28. Rb1 Ne5 29. Rxc5 Rxc5 30. bxc5 Nxd3 31. Qd2 Nxc5 32.
+Qf4+ Qc7 33. Qxg4 Nxa4 34. e5 Nc5 35. Qf3 d3 36. Qe3 d2 37. Bf3 Na4 38. Qe4
+Nc5 39. Qe2 a6 40. Kg2 Ka7 41. Qe3 Rd3 42. Qf4 Qd7 43. Qc4 b6 44. Rd1 a5
+45. Qf4 Rd4 46. Qh6 b5 47. Qe3 Kb6 48. Qh6+ Ne6 49. Qe3 Ka6 50. Be2 a4 51.
+Qc3 Kb6 52. Qe3 Nc5 53. Bf3 b4 54. Qh6+ Ne6 55. Qh8 Qd8 56. Qh7 Qd7 57. Qh8
+b3 58. Qb8+ Ka5 59. Qa8+ Kb5 60. Qb8+ Kc4 61. Qg8 Kc3 62. Bh5 Nd8 63. Bf3
+a3 64. Qf8 Kb2 65. Qh8 Ne6 66. Qa8 a2 67. Qa5 Qa4 68. Rxd2+ Ka3 0-1
+
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
+[Event "Zurich"]
+[Site "?"]
+[Date "1959"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Larsen, Bent"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nf3 d5 3. Nc3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Bc5 8.
+Be2 O-O 9. O-O Nbd7 10. Qg3 Bd4 11. Bh6 Ne8 12. Bg5 Ndf6 13. Bf3 Qd6 14.
+Bf4 Qc5 15. Rab1 dxe4 16. dxe4 e5 17. Bg5 Bxc3 18. bxc3 b5 19. c4 a6 20.
+Bd2 Qe7 21. Bb4 Nd6 22. Rfd1 Rfd8 23. cxb5 cxb5 24. Rd3 Qe6 25. Rbd1 Nb7
+26. Bc3 Rxd3 27. cxd3 Re8 28. Kh2 h6 29. d4 Nd6 30. Re1 Nc4 31. dxe5 Nxe5
+32. Bd1 Ng6 33. e5 Nd5 34. Bb3 Qc6 35. Bb2 Ndf4 36. Rd1 a5 37. Rd6 Qe4 38.
+Rd7 Ne6 39. Bd5 Qe2 40. Bc3 b4 41. axb4 axb4 42. Bxb4 Qxe5 43. Ba5 Qxg3+
+44. Kxg3 Re7 45. Rd6 Nef4 46. Bf3 Ne6 47. Bb6 Ne5 48. Bd5 Rd7 49. Rxd7 Nxd7
+50. Be3 Nf6 51. Bc6 g5 52. Kf3 Kg7 53. Ba4 Nd5 54. Bc1 h5 55. Bb2+ Kh6 56.
+Bb3 Ndf4 57. Bc2 Ng6 58. Kg3 Nef4 59. Be4 Nh4 60. Bf6 Nhg6 61. Kf3 Nh4+ 62.
+Kg3 Nhg6 63. Kh2 h4 64. Kg1 Nh5 65. Bc3 Ngf4 66. Kf1 Ng7 67. Bf6 Nfh5 68.
+Be5 f6 69. Bd6 f5 70. Bf3 Nf4 71. Ke1 Kg6 72. Kd2 Nge6 73. Be5 Nc5 74. Ke3
+Nce6 75. Bc6 Kf7 76. Kf3 Ke7 77. Bb7 Ng6 78. Bc3 Ngf4 79. Ba6 Nd5 80. Be5
+Nf6 81. Bd3 g4+ 82. Ke2 Nd7 83. Bh2 gxh3 84. gxh3 Kf6 85. Ke3 Ne5 86. Be2
+Ng6 87. Bf1 f4+ 88. Kf3 Ne5+ 89. Ke4 Ng5+ 90. Kxf4 Nef3 91. Bg3 hxg3 92.
+fxg3 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Foguelman, Alberto"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nh3 Nf6 7. Nf4 e5
+8. dxe5 Qxd1+ 9. Kxd1 Ng4 10. Nxg6 hxg6 11. Ne4 Nxe5 12. Be2 f6 13. c3 Nbd7
+14. Be3 O-O-O 15. Kc2 Nb6 16. h4 Nec4 17. Bf4 Nd5 18. Bg3 Nd6 19. Nxd6+
+Bxd6 20. Bxd6 Rxd6 21. g3 Kc7 22. c4 Nb4+ 23. Kc3 c5 24. a3 Re8 25. Bf1 Nc6
+26. Bd3 Ne5 27. Be4 Ng4 28. Bxg6 Re2 29. Rae1 Rxf2 30. Re7+ Kb6 31. Be4 Re2
+32. Rxb7+ Ka6 33. Re7 Kb6 34. b4 Nf2 35. Rb7+ Ka6 36. b5+ Ka5 37. Rxa7+ Kb6
+38. Ra6+ Kc7 39. b6+ Rxb6 40. Rxb6 Nxe4+ 41. Kd3 Kxb6 42. Rg1 Rd2+ 43. Kxe4
+Rd4+ 44. Kf5 Rxc4 45. Re1 Rc3 46. g4 Rf3+ 47. Kg6 Rxa3 48. Kxg7 Rg3 49. Re4
+f5 50. Re6+ Kb5 51. g5 Rg4 52. g6 Rxh4 53. Kf7 c4 54. g7 Rh7 55. Rg6 c3 56.
+Kf6 Rxg7 57. Rxg7 Kc4 58. Kxf5 c2 1/2-1/2
+
+[Event "Buenos Aires"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ivkov, Boris"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. c5 O-O 8.
+b4 b6 9. Bd3 bxc5 10. bxc5 Nc6 11. O-O Bd7 12. h3 Ne8 13. Bf4 Bf6 14. Bb5
+Nc7 15. Be2 Nxd4 16. Nxd4 e5 17. c6 Be8 18. Bg3 exd4 19. Bxc7 Qxc7 20. Nxd5
+Qd6 21. Nxf6+ Qxf6 22. c7 Rc8 23. Rc1 Bc6 24. Rc4 Rxc7 25. Bd3 Rd7 26. Qc2
+Bd5 27. Ra4 g6 28. Qc5 Rfd8 29. Bb5 Rd6 30. Rd1 Be6 31. Bd3 Rd5 32. Qxa7
+Bxh3 33. Be4 R5d7 34. Qa6 Qxa6 35. Rxa6 Be6 36. a4 d3 37. Rd2 Rd4 38. f3
+Bd5 39. Bxd5 R8xd5 40. Kf2 Rc4 41. a5 Ra4 42. Rc6 Ra3 43. Rc1 h5 44. Rcd1
+Kg7 45. a6 g5 46. a7 Rxa7 47. Rxd3 Ra2+ 48. Kg1 Rxd3 49. Rxd3 Kg6 50. Kh2
+Ra4 51. Rd5 g4 52. fxg4 hxg4 53. g3 Kf6 54. Rd7 Ke5 55. Kg2 f5 56. Rd2 Rc4
+57. Re2+ Kd4 58. Rf2 Rc5 59. Rf4+ Ke3 60. Kg1 1/2-1/2
+
+[Event "Leipzig Olympiad Final"]
+[Site "?"]
+[Date "1960"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Euwe, Max"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 Nc6 6. Nf3 Bg4 7. cxd5 Nxd5
+8. Qb3 Bxf3 9. gxf3 e6 10. Qxb7 Nxd4 11. Bb5+ Nxb5 12. Qc6+ Ke7 13. Qxb5
+Nxc3 14. bxc3 Qd7 15. Rb1 Rd8 16. Be3 Qxb5 17. Rxb5 Rd7 18. Ke2 f6 19. Rd1
+Rxd1 20. Kxd1 Kd7 21. Rb8 Kc6 22. Bxa7 g5 23. a4 Bg7 24. Rb6+ Kd5 25. Rb7
+Bf8 26. Rb8 Bg7 27. Rb5+ Kc6 28. Rb6+ Kd5 29. a5 f5 30. Bb8 Rc8 31. a6 Rxc3
+32. Rb5+ Kc4 33. Rb7 Bd4 34. Rc7+ Kd3 35. Rxc3+ Kxc3 36. Be5 1-0
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d4 dxe4 7. Qe3 Nbd7
+8. Nxe4 Nxe4 9. Qxe4 Nf6 10. Qd3 Qd5 11. c4 Qd6 12. Be2 e5 13. d5 e4 14.
+Qc2 Be7 15. dxc6 Qxc6 16. O-O O-O 17. Be3 Bc5 18. Qc3 b6 19. Rfd1 Rfd8 20.
+b4 Bxe3 21. fxe3 Qc7 22. Rd4 a5 23. a3 axb4 24. axb4 h5 25. Rad1 Rxd4 26.
+Qxd4 Qg3 27. Qxb6 Ra2 28. Bf1 h4 29. Qc5 Qf2+ 30. Kh1 g6 31. Qe5 Kg7 32. c5
+Qxe3 33. c6 Rc2 34. b5 Rc1 35. Rxc1 Qxc1 36. Kg1 e3 37. c7 e2 38. Qxe2 Qxc7
+39. Qf2 g5 40. b6 Qe5 41. b7 Nd7 42. Qd2 Nb8 43. Be2 Kf6 44. Bf3 Ke6 45.
+Bg4+ f5 46. Bd1 Kf6 47. Qd8+ Kg6 48. Qg8+ Kh6 49. Qf8+ Kg6 50. Qg8+ Kh6 51.
+Qf8+ Kg6 52. Qb4 Nc6 53. Qd2 Nd8 54. Bf3 Nxb7 55. Bxb7 Qa1+ 56. Kh2 Qe5+
+1/2-1/2
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "Stockholm Interzonal"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Barcza, Gedeon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. d4 Bd6 7. Bc4
+O-O 8. O-O Re8 9. Bb3 Nd7 10. Nh4 Nf8 11. Qd3 Bc7 12. Be3 Qe7 13. Nf5 Qe4
+14. Qxe4 Rxe4 15. Ng3 Re8 16. d5 cxd5 17. Bxd5 Bb6 18. Bxb6 axb6 19. a3 Ra5
+20. Rad1 Rc5 21. c3 Rc7 22. Bf3 Rd7 23. Rxd7 Nxd7 24. Nf5 Nc5 25. Nd6 Rd8
+26. Nxc8 Rxc8 27. Rd1 Kf8 28. Rd4 Rc7 29. h3 f5 30. Rb4 Nd7 31. Kf1 Ke7 32.
+Ke2 Kd8 33. Rb5 g6 34. Ke3 Kc8 35. Kd4 Kb8 36. Kd5 Rc6 37. Kd4 Re6 38. a4
+Kc7 39. a5 Rd6+ 40. Bd5 Kc8 41. axb6 f6 42. Ke3 Nxb6 43. Bg8 Kc7 44. Rc5+
+Kb8 45. Bxh7 Nd5+ 46. Kf3 Ne7 47. h4 b6 48. Rb5 Kb7 49. h5 Ka6 50. c4 gxh5
+51. Bxf5 Rd4 52. b3 Nc6 53. Ke3 Rd8 54. Be4 Na5 55. Bc2 h4 56. Rh5 Re8+ 57.
+Kd2 Rg8 58. Rxh4 b5 59. Rf4 bxc4 60. bxc4 Rxg2 61. Rxf6+ Ka7 62. Kc3 Rg4
+63. f4 Nb7 64. Kb4 1-0
+
+[Event "Varna Olympiad Final"]
+[Site "?"]
+[Date "1962"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Donner, Jan H."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bf4 Qa5+ 11. Bd2 Qc7 12. c4 Ngf6 13. Bc3 a5 14. O-O
+Bd6 15. Ne4 Nxe4 16. Qxe4 O-O 17. d5 Rfe8 18. dxc6 bxc6 19. Rad1 Bf8 20.
+Nd4 Ra6 21. Nf5 Nc5 22. Qe3 Na4 23. Be5 Qa7 24. Nxh6+ gxh6 25. Rd4 f5 26.
+Rfd1 Nc5 27. Rd8 Qf7 28. Rxe8 Qxe8 29. Bd4 Ne4 30. f3 e5 31. fxe4 exd4 32.
+Qg3+ Bg7 33. exf5 Qe3+ 34. Qxe3 dxe3 35. Rd8+ Kf7 36. Rd7+ Kf6 37. g4 Bf8
+38. Kg2 Bc5 39. Rh7 Ke5 40. Kf3 Kd4 41. Rxh6 Rb6 42. b3 a4 43. Re6 axb3 44.
+axb3 Kd3 0-1
+
+[Event "USA Championship"]
+[Site "?"]
+[Date "1963"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Steinmeyer, Robert H."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nf6 7. h4 h6 8.
+Bd3 Bxd3 9. Qxd3 e6 10. Bd2 Nbd7 11. O-O-O Qc7 12. c4 O-O-O 13. Bc3 Qf4+
+14. Kb1 Nc5 15. Qc2 Nce4 16. Ne5 Nxf2 17. Rdf1 1-0
+
+[Event "Skopje"]
+[Site "?"]
+[Date "1967"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Panov, Vasil"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nf6 5. Nxf6+ exf6 6. Bc4 Bd6 7. O-O
+O-O 8. d4 Be6 9. Bxe6 fxe6 10. Re1 Re8 11. c4 Na6 12. Bd2 Qd7 13. Bc3 Bb4
+14. Qb3 Bxc3 15. bxc3 Nc7 16. a4 b6 17. h3 Rab8 18. Re4 a6 19. Qc2 b5 20.
+axb5 axb5 21. cxb5 cxb5 22. Nd2 Ra8 23. Rae1 Qd5 24. Rh4 Qf5 25. Ne4 e5 26.
+Re3 h6 27. Rf3 Qh7 28. Nxf6+ gxf6 29. Rg3+ Kh8 30. Rg6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Cagan, Shimon"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. a3 Nbd7 8.
+g4 Bd6 9. g5 Ng8 10. h4 Ne7 11. h5 Qb6 12. Bh3 O-O-O 13. a4 a5 14. O-O Rhf8
+15. Kh1 f5 16. Qg2 g6 17. h6 Kb8 18. f4 Rfe8 19. e5 Bc5 20. Qf3 Nc8 21. Bg2
+Kc7 22. Ne2 Nb8 23. c3 Kd7 24. Bd2 Na6 25. Rfb1 Bf8 26. b4 axb4 27. cxb4
+Bxb4 28. a5 Qc5 29. d4 Qf8 30. Bxb4 Nxb4 31. Qc3 Na6 32. Rxb7+ Nc7 33. Nc1
+Re7 34. a6 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Czerniak, Moshe"]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 g6 7. Nf3 Bg7 8.
+Nbd2 Nh5 9. Be3 O-O 10. O-O f5 11. Nb3 Qd6 12. Re1 f4 13. Bd2 Bg4 14. Be2
+Rae8 15. Nc1 Bxf3 16. Bxf3 e5 17. Qb3 exd4 18. Nd3 Rd8 19. c4 dxc4 20.
+Qxc4+ Kh8 21. Re6 Qb8 22. Rae1 Rc8 23. Bxc6 Rxc6 24. Rxc6 bxc6 25. Qxc6 Qc8
+26. Qxc8 Rxc8 27. Kf1 Bh6 28. Rc1 Rxc1+ 29. Bxc1 g5 30. b4 Kg8 31. b5 Kf7
+32. Ba3 Bf8 33. Ne5+ Ke6 34. Bxf8 Kxe5 35. Bc5 Nf6 36. Bxa7 Ne4 37. f3 Nd2+
+38. Ke2 Nc4 39. b6 Na5 40. b7 Nxb7 41. Kd3 h5 42. Bxd4+ Kd5 43. h3 Nd8 44.
+a4 Ne6 45. Bb6 g4 46. hxg4 hxg4 47. fxg4 1-0
+
+[Event "Nathania"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Yanofsky, Daniel A."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. Be2 Na6 9. Bg5 Qb6 10. Qxb6 axb6 11. a3 Rd8 12. Bxf6 Bxf6 13. Rd1 Bf5
+14. Bc4 Rac8 15. Bb3 b5 16. Nf3 b4 17. axb4 Nxb4 18. Ke2 Bc2 19. Bxc2 Nxc2
+20. Kd3 Nb4+ 21. Ke4 Rd6 22. Ne5 Bg7 23. g4 f5+ 24. gxf5 gxf5+ 25. Kf4 Rf8
+26. Rhg1 Nxd5+ 27. Nxd5 Rxd5 28. Nf3 Kh8 29. Rge1 Bf6 30. Ne5 e6 31. h4 Rc8
+32. Nf7+ Kg7 33. Ng5 Bxg5+ 34. Kxg5 Rc6 35. Re5 Rcd6 36. Rxd5 Rxd5 37. f4
+Rb5 38. Rd2 Rb3 39. d5 h6+ 40. Kh5 exd5 41. Rxd5 Rxb2 42. Rd7+ Kf6 43. Rd6+
+Kf7 44. Rxh6 Rg2 45. Rb6 Rg4 46. Rxb7+ Kf6 1/2-1/2
+
+[Event "Vinkovci"]
+[Site "?"]
+[Date "1968"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Nf3 Nf6 5. c3 Bf5 6. Bb5+ Nbd7 7. Nh4 Bg6
+8. Bf4 e6 9. Nd2 Nh5 10. Nxg6 hxg6 11. Be3 Bd6 12. g3 a6 13. Bd3 Rc8 14.
+O-O Nb6 15. a4 Rc7 16. Qb3 Nc8 17. c4 dxc4 18. Nxc4 Nf6 19. Rac1 O-O 20.
+Bd2 Nd5 21. Be4 Be7 22. Na5 Ncb6 23. Bxd5 Nxd5 24. Nxb7 Qb8 25. Rxc7 Qxc7
+26. Rc1 Qb8 27. Rc4 Rd8 28. Bc3 Rd7 29. Na5 Qxb3 30. Rc8+ Kh7 31. Nxb3 Nb6
+32. Rc6 Nxa4 33. Rxa6 Nxc3 34. bxc3 Rc7 35. Nd2 Rxc3 36. Ra7 Rd3 37. Nf1
+Bf6 38. Rxf7 Rxd4 39. Kg2 g5 40. h3 Kg6 41. Rc7 Ra4 42. Nd2 Rd4 43. Nb3 Rd6
+44. Nc5 Kf5 45. Kf3 Rb6 46. Rd7 Rc6 47. Ne4 Ra6 48. Rd3 Be7 49. Rb3 Ra3 50.
+Rxa3 Bxa3 51. g4+ Kg6 52. Ke3 Bc1+ 53. Kd4 Bf4 54. Kc5 Kf7 55. Kb6 Ke8 56.
+Kc6 Ke7 1/2-1/2
+
+[Event "Palma de Mallorca"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hubner, Robert"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 d4 9. a4 c5 10. Nc4 Nbc6 11. c3 Be6 12. cxd4 Bxc4 13. dxc4 exd4 14. e5
+Qd7 15. h4 d3 16. Bd2 Rad8 17. Bc3 Nb4 18. Nd4 Rfe8 19. e6 fxe6 20. Nxe6
+Bxc3 21. bxc3 Nc2 22. Nxd8 Rxd8 23. Qd2 Nxa1 24. Rxa1 Kg7 25. Re1 Ng8 26.
+Bd5 Qxa4 27. Qxd3 Re8 28. Rxe8 Qxe8 29. Bxb7 Nf6 30. Qd6 Qd7 31. Qa6 Qf7
+32. Qxa7 Ne4 33. f3 Nd6 34. Qxc5 Nxb7 35. Qd4+ Kg8 36. Kf2 Qe7 37. Qd5+ Kf8
+38. h5 gxh5 39. Qxh5 Nc5 40. Qd5 Kg7 41. Qd4+ Kf7 42. Qd5+ Kg7 43. Qd4+ Kf7
+44. Qd5+ 1/2-1/2
+
+[Event "Siegen Olympiad Final"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Hort, Vlastimil"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. g3 Bg7 5. Bg2 e5 6. Ngf3 Ne7 7. O-O O-O 8.
+Re1 Nd7 9. b3 d4 10. Bb2 b5 11. c3 c5 12. Rc1 Bb7 13. cxd4 cxd4 14. Bh3 Nc6
+15. a3 Re8 16. Qe2 Rc8 17. Rc2 Ne7 18. Rec1 Rxc2 19. Rxc2 Nc6 20. Qd1 Nb6
+21. Qc1 Qf6 22. Bg2 Rc8 23. h4 Bf8 24. Bh3 Rc7 25. Nh2 Bc8 26. Bf1 Bd7 27.
+h5 Rc8 28. Be2 Nd8 29. Rxc8 Bxc8 30. Ndf3 Nc6 31. Nh4 b4 32. axb4 Nxb4 33.
+N4f3 a5 34. Qc7 Qd6 35. Qa7 Ba6 36. Ba3 Nc8 37. Qa8 Qb6 38. Bxb4 Bxb4 39.
+Qd5 Qc5 40. Qxe5 Qxe5 41. Nxe5 Nd6 42. hxg6 hxg6 43. Kf1 Bb5 44. Nhf3 Bc3
+45. Ne1 Nb7 46. Bd1 Nc5 47. f3 Kg7 48. Bc2 Kf6 49. Ng4+ Ke7 50. Nf2 Bd7 51.
+Nd1 Bb4 52. Nb2 Be6 53. Nc4 Bxc4 54. dxc4 Bxe1 55. Kxe1 g5 56. Ke2 Kd6 57.
+f4 gxf4 58. gxf4 f6 59. Kf3 Ke6 60. Ke2 Kd6 1/2-1/2
+
+[Event "Siegen Olympiad Prelim"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Ibrahimoglu, Ismet"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 g6 4. Ngf3 Bg7 5. g3 Nf6 6. Bg2 O-O 7. O-O Bg4 8.
+h3 Bxf3 9. Qxf3 Nbd7 10. Qe2 dxe4 11. dxe4 Qc7 12. a4 Rad8 13. Nb3 b6 14.
+Be3 c5 15. a5 e5 16. Nd2 Ne8 17. axb6 axb6 18. Nb1 Qb7 19. Nc3 Nc7 20. Nb5
+Qc6 21. Nxc7 Qxc7 22. Qb5 Ra8 23. c3 Rxa1 24. Rxa1 Rb8 25. Ra6 Bf8 26. Bf1
+Kg7 27. Qa4 Rb7 28. Bb5 Nb8 29. Ra8 Bd6 30. Qd1 Nc6 31. Qd2 h5 32. Bh6+ Kh7
+33. Bg5 Rb8 34. Rxb8 Nxb8 35. Bf6 Nc6 36. Qd5 Na7 37. Be8 Kg8 38. Bxf7+
+Qxf7 39. Qxd6 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
+[Event "Zabreb"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Marovic, Drazen"]
+[Result "1-0"]
+
+1. e4 c6 2. d3 d5 3. Nd2 Nd7 4. Ngf3 Qc7 5. exd5 cxd5 6. d4 g6 7. Bd3 Bg7
+8. O-O e6 9. Re1 Ne7 10. Nf1 Nc6 11. c3 O-O 12. Bg5 e5 13. Ne3 Nb6 14. dxe5
+Nxe5 15. Bf4 f6 16. a4 Qf7 17. a5 Nbc4 18. Bxc4 dxc4 19. Bxe5 fxe5 20. Qe2
+h6 21. Nxc4 Bg4 22. Ncxe5 Bxe5 23. Nxe5 Bxe2 24. Nxf7 Rxf7 25. Rxe2 Rd8 26.
+Rae1 Rd5 27. b4 Rc7 28. Re3 Kf7 29. h4 Rd2 30. Rf3+ Kg7 31. Re6 Rf7 32.
+Rxf7+ Kxf7 33. Re5 Rd1+ 34. Kh2 b6 35. axb6 axb6 36. f3 Rd3 37. Rb5 Rxc3
+38. Rxb6 h5 39. Rb7+ Kf6 40. b5 Rb3 41. b6 Rb4 42. Kg3 Rb2 43. Rb8 Kg7 44.
+f4 Rb3+ 45. Kf2 Kf6 46. Ke2 Kg7 47. Kd2 Rg3 48. Rc8 1-0
+
+[Event "?"]
+[Site "Stockholm"]
+[Date "1962.??.??"]
+[Round "4"]
+[White "Fischer, Robert J."]
+[Black "Portisch, Lajos"]
+[Result "1-0"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Neg5 Nd5 7. d4 h6
+8. Ne4 N7b6 9. Bb3 Bf5 10. Ng3 Bh7 11. O-O e6 12. Ne5 Nd7 13. c4 N5f6 14.
+Bf4 Nxe5 15. Bxe5 Bd6 16. Qe2 O-O 17. Rad1 Qe7 18. Bxd6 Qxd6 19. f4 c5 20.
+Qe5 Qxe5 21. dxe5 Ne4 22. Rd7 Nxg3 23. hxg3 Be4 24. Ba4 Rad8 25. Rfd1 Rxd7
+26. Rxd7 g5 27. Bd1 Bc6 28. Rd6 Rc8 29. Kf2 Kf8 30. Bf3 Bxf3 31. gxf3 gxf4
+32. gxf4 Ke7 33. f5 exf5 34. Rxh6 Rd8 35. Ke2 Rg8 36. Kf2 Rd8 37. Ke3 Rd1
+38. b3 Re1+ 39. Kf4 Re2 40. Kxf5 Rxa2 41. f4 Re2 42. Rh3 Re1 43. Rd3 Rb1
+44. Re3 Rb2 45. e6 a6 46. exf7+ Kxf7 47. Ke5 Rd2 48. Rc3 b6 49. f5 Rd1 50.
+Rh3 b5 51. Rh7+ Kg8 52. Rb7 bxc4 53. bxc4 Rd4 54. Ke6 Re4+ 55. Kd5 Rf4 56.
+Kxc5 Rxf5+ 57. Kd6 Rf6+ 58. Ke5 Rf7 59. Rb6 Rc7 60. Kd5 Kf7 61. Rxa6 Ke7
+62. Re6+ Kd8 63. Rd6+ Ke7 64. c5 Rc8 65. c6 Rc7 66. Rh6 Kd8 67. Rh8+ Ke7
+68. Ra8 1-0
+
+[Event "?"]
+[Site "Yugoslavia ct"]
+[Date "1959.??.??"]
+[Round "2"]
+[White "Fischer, Robert J."]
+[Black "Keres, Paul"]
+[Result "0-1"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Qb6 10. b3 a5 11. a3 Be7 12. Bg2 a4 13. b4 Nbd7 14. O-O c5
+15. Ra2 O-O 16. bxc5 Bxc5 17. Qe2 e5 18. f4 Rfc8 19. h4 Rc6 20. Bh3 Qc7 21.
+fxe5 Nxe5 22. Bf4 Bd6 23. h5 Ra5 24. h6 Ng6 25. Qf3 Rh5 26. Bg4 Nxf4 27.
+Bxh5 N4xh5 28. Kg2 Ng4 29. Nd2 Ne3+ 0-1
+
diff --git a/test/outfiles/test-long-line-log.txt b/test/outfiles/test-long-line-log.txt
new file mode 100644 (file)
index 0000000..bacfc82
--- /dev/null
@@ -0,0 +1,6 @@
+Processing infiles/test-long-line.pgn
+String length 139 is too long for the line length of 75:
+only-a-fool-would-play-this-move-and-only-someone-wanting-to-test-how-the-program-copes-with-very-long-lines-would-type-a-comment-like-this
+? - ? ? ? ????.??.?? 
+? - ? ? ? ????.??.?? 
+1 game matched out of 1.
diff --git a/test/outfiles/test-long-line-out.pgn b/test/outfiles/test-long-line-out.pgn
new file mode 100644 (file)
index 0000000..7d83f61
--- /dev/null
@@ -0,0 +1,12 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 {
+only-a-fool-would-play-this-move-and-only-someone-wanting-to-test-how-the-program-copes-with-very-long-lines-would-type-a-comment-like-this
+} 2... Qh4# 0-1
+
diff --git a/test/outfiles/test-markmatches-out.pgn b/test/outfiles/test-markmatches-out.pgn
new file mode 100644 (file)
index 0000000..cbd848c
--- /dev/null
@@ -0,0 +1,66 @@
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Vidarsson, Jon G"]
+[Black "Gislason, Gudmundur"]
+[Result "1-0"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 { MATCH } 6...
+e6 7. f3 b5 8. g4 h6 9. Rg1 b4 10. Nce2 e5 11. Nb3 d5 12. Ng3 Bb7 13. h4 d4
+14. Bf2 Qc7 15. Bd3 Nc6 16. g5 hxg5 17. hxg5 Nd7 18. g6 f6 19. Qe2 Nd8 20.
+Nf5 Ne6 21. Bc4 Nf4 22. Bf7+ Kd8 23. Qd2 Rh2 24. O-O-O d3 25. Bb6 Qxb6 26.
+Qxh2 Rc8 27. Rd2 a5 28. Kb1 a4 29. Nc1 dxc2+ 30. Rxc2 Rxc2 31. Kxc2 Nc5 32.
+Rd1+ Kc7 33. Qd2 Nfe6 34. Kb1 Kb8 35. Nd3 b3 36. Nxc5 Bxc5 37. Ka1 1-0
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Stefansson, Hannes"]
+[Black "Olafsson, Helgi"]
+[Result "1/2-1/2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 { MATCH } 6...
+e6 7. f3 Nbd7 8. g4 h6 9. Qd2 b5 10. O-O-O b4 11. Nce2 d5 12. Nf4 dxe4 13.
+Ndxe6 fxe6 14. Bc4 Qc7 15. Bxe6 Ne5 16. Bb3 Bd7 17. fxe4 Bc5 18. Bxc5 Qxc5
+19. Nd3 Nxd3+ 20. Qxd3 O-O-O 21. e5 Bb5 22. Qf5+ Nd7 23. Rd5 Qe3+ 24. Kb1
+Rhf8 25. Qg6 Nc5 26. Qxg7 Nxb3 27. axb3 Bc6 28. Rxd8+ Rxd8 29. Rf1 Be4 30.
+Qf6 Qe2 31. Qe6+ Rd7 32. Rc1 Kc7 33. h4 a5 34. g5 hxg5 35. hxg5 Rd1 36.
+Qe7+ Kb6 37. Qe6+ Kc7 38. Qe7+ Kb6 39. Qe6+ Bc6 40. Rxd1 Qxd1+ 41. Ka2 Qxc2
+42. Qd6 Qc5 43. Qb8+ Bb7 44. g6 a4 45. Qd8+ Ka7 46. Qd7 Kb6 47. Qd8+ Ka6
+48. Qd3+ Ka5 49. Qd8+ Ka6 50. Qd3+ Ka7 51. Qd7 Kb6 1/2-1/2
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Vidarsson, Jon G"]
+[Black "Gislason, Gudmundur"]
+[Result "1-0"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 { MATCH } 6...
+e6 7. f3 b5 8. g4 h6 9. Rg1 b4 10. Nce2 e5 11. Nb3 d5 12. Ng3 Bb7 13. h4 d4
+14. Bf2 Qc7 15. Bd3 Nc6 16. g5 hxg5 17. hxg5 Nd7 18. g6 f6 19. Qe2 Nd8 20.
+Nf5 Ne6 21. Bc4 Nf4 22. Bf7+ Kd8 23. Qd2 Rh2 24. O-O-O d3 25. Bb6 Qxb6 26.
+Qxh2 Rc8 27. Rd2 a5 28. Kb1 a4 29. Nc1 dxc2+ 30. Rxc2 Rxc2 31. Kxc2 Nc5 32.
+Rd1+ Kc7 33. Qd2 Nfe6 34. Kb1 Kb8 35. Nd3 b3 36. Nxc5 Bxc5 37. Ka1 1-0
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Stefansson, Hannes"]
+[Black "Olafsson, Helgi"]
+[Result "1/2-1/2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 { MATCH } 6...
+e6 7. f3 Nbd7 8. g4 h6 9. Qd2 b5 10. O-O-O b4 11. Nce2 d5 12. Nf4 dxe4 13.
+Ndxe6 fxe6 14. Bc4 Qc7 15. Bxe6 Ne5 16. Bb3 Bd7 17. fxe4 Bc5 18. Bxc5 Qxc5
+19. Nd3 Nxd3+ 20. Qxd3 O-O-O 21. e5 Bb5 22. Qf5+ Nd7 23. Rd5 Qe3+ 24. Kb1
+Rhf8 25. Qg6 Nc5 26. Qxg7 Nxb3 27. axb3 Bc6 28. Rxd8+ Rxd8 29. Rf1 Be4 30.
+Qf6 Qe2 31. Qe6+ Rd7 32. Rc1 Kc7 33. h4 a5 34. g5 hxg5 35. hxg5 Rd1 36.
+Qe7+ Kb6 37. Qe6+ Kc7 38. Qe7+ Kb6 39. Qe6+ Bc6 40. Rxd1 Qxd1+ 41. Ka2 Qxc2
+42. Qd6 Qc5 43. Qb8+ Bb7 44. g6 a4 45. Qd8+ Ka7 46. Qd7 Kb6 47. Qd8+ Ka6
+48. Qd3+ Ka5 49. Qd8+ Ka6 50. Qd3+ Ka7 51. Qd7 Kb6 1/2-1/2
+
diff --git a/test/outfiles/test-n-matched.pgn b/test/outfiles/test-n-matched.pgn
new file mode 100644 (file)
index 0000000..3e65834
--- /dev/null
@@ -0,0 +1,66 @@
+[Event "?"]
+[Site "Buenos Aires m"]
+[Date "1971"]
+[Round "6"]
+[White "Petrosian, Tigran V."]
+[Black "Fischer, Robert J."]
+[Result "0-1"]
+
+1. Nf3 c5 2. b3 d5 3. Bb2 f6 4. c4 d4 5. d3 e5 6. e3 Ne7 7. Be2 Nec6 8.
+Nbd2 Be7 9. O-O O-O 10. e4 a6 11. Ne1 b5 12. Bg4 Bxg4 13. Qxg4 Qc8 14. Qe2
+Nd7 15. Nc2 Rb8 16. Rfc1 Qe8 17. Ba3 Bd6 18. Ne1 g6 19. cxb5 axb5 20. Bb2
+Nb6 21. Nef3 Ra8 22. a3 Na5 23. Qd1 Qf7 24. a4 bxa4 25. bxa4 c4 26. dxc4
+Nbxc4 27. Nxc4 Nxc4 28. Qe2 Nxb2 29. Qxb2 Rfb8 30. Qa2 Bb4 31. Qxf7+ Kxf7
+32. Rc7+ Ke6 33. g4 Bc3 34. Ra2 Rc8 35. Rxc8 Rxc8 36. a5 Ra8 37. a6 Ra7 38.
+Kf1 g5 39. Ke2 Kd6 40. Kd3 Kc5 41. Ng1 Kb5 42. Ne2 Ba5 43. Rb2+ Kxa6 44.
+Rb1 Rc7 45. Rb2 Be1 46. f3 Ka5 47. Rc2 Rb7 48. Ra2+ Kb5 49. Rb2+ Bb4 50.
+Ra2 Rc7 51. Ra1 Rc8 52. Ra7 Ba5 53. Rd7 Bb6 54. Rd5+ Bc5 55. Nc1 Ka4 56.
+Rd7 Bb4 57. Ne2 Kb3 58. Rb7 Ra8 59. Rxh7 Ra1 60. Nxd4+ exd4 61. Kxd4 Rd1+
+62. Ke3 Bc5+ 63. Ke2 Rh1 64. h4 Kc4 65. h5 Rh2+ 66. Ke1 Kd3 0-1
+
+[Event "Bled"]
+[Site "?"]
+[Date "1961"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Nf3 Ngf6 6. Nxf6+ Nxf6 7. Bc4
+Bf5 8. Qe2 e6 9. Bg5 Bg4 10. O-O-O Be7 11. h3 Bxf3 12. Qxf3 Nd5 13. Bxe7
+Qxe7 14. Kb1 Rd8 15. Qe4 b5 16. Bd3 a5 17. c3 Qd6 18. g3 b4 19. c4 Nf6 20.
+Qe5 c5 21. Qg5 h6 22. Qxc5 Qxc5 23. dxc5 Ke7 24. c6 Rd6 25. Rhe1 Rxc6 26.
+Re5 Ra8 27. Be4 Rd6 28. Bxa8 Rxd1+ 29. Kc2 Rf1 30. Rxa5 Rxf2+ 31. Kb3 Rh2
+32. c5 Kd8 33. Rb5 Rxh3 34. Rb8+ Kc7 35. Rb7+ Kc6 36. Kc4 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
diff --git a/test/outfiles/test-n-unmatched.pgn b/test/outfiles/test-n-unmatched.pgn
new file mode 100644 (file)
index 0000000..dffda11
--- /dev/null
@@ -0,0 +1,450 @@
+[Event "?"]
+[Site "Sarajevo"]
+[Date "1972"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Hort"]
+[Result "1-0"]
+
+1. Nf3 c5 2. b3 d5 3. e3 Nf6 4. Bb2 e6 5. c4 Nc6 6. cxd5 exd5 7. Be2 Be7 8.
+O-O O-O 9. d4 Bg4 10. dxc5 Bxc5 11. Nc3 Rc8 12. Rc1 Be7 13. Nd4 Bxe2 14.
+Ncxe2 Qd7 15. Nf4 Rfd8 16. Qd3 Ne4 17. Nxc6 bxc6 18. Rc2 Bf8 19. Rfc1 Qb7
+20. Qe2 Re8 21. Qg4 g6 22. Qd1 Bd6 23. Nxd5 Rcd8 24. Rxc6 Qb8 25. f4 Re6
+26. Qd4 1-0
+
+[Event "?"]
+[Site "USSR 26/2"]
+[Date "1978"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Balashov,Y"]
+[Result "1-0"]
+
+1. b3 e5 2. Bb2 Nc6 3. c4 Nf6 4. e3 d5 5. cxd5 Nxd5 6. a3 Bd6 7. Qc2 O-O 8.
+Nf3 Qe7 9. Bd3 Kh8 10. Be4 Nb6 11. Bxc6 bxc6 12. d3 Bd7 13. Nbd2 f5 14. e4
+fxe4 15. dxe4 Rf4 16. Qc3 Re8 17. O-O c5 18. Kh1 Bc6 19. Rae1 Nd7 20. Ng1
+Nf6 21. f3 Nh5 22. g4 1-0
+
+[Event "?"]
+[Site "Tilburg 32/3"]
+[Date "1981"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Sosonko,G"]
+[Result "1-0"]
+
+1. c4 e5 2. b3 Nf6 3. Bb2 Nc6 4. e3 Be7 5. a3 O-O 6. Qc2 d5 7. cxd5 Nxd5 8.
+Nf3 Bf6 9. d3 g6 10. Nbd2 Bg7 11. Rc1 g5 12. Nc4 Qe7 13. b4 a6 14. Nfd2 f5
+15. Be2 g4 16. Nb3 Kh8 17. Nca5 Nxa5 18. Nxa5 Qf7 19. O-O c6 20. Nc4 Qe7
+21. Rfe1 Bd7 22. Bf1 Nc7 23. Nb6 Rad8 24. Qc5 Qxc5 25. Rxc5 Ne6 26. Rxe5
+Bxe5 27. Bxe5+ Kg8 28. d4 Be8 29. Nc4 b5 30. Nd6 Bd7 31. Rc1 Ng5 32. Nb7
+Rc8 33. Bd3 Ra8 34. Kf1 Be6 35. Bf4 Nf7 36. Ke2 Bd5 37. Bxf5 Ne5 38. Bxe5
+Rxf5 39. Nd6 Rff8 40. e4 Bc4+ 41. Nxc4 bxc4 42. Rxc4 a5 43. Bd6 Rfe8 44. e5
+axb4 45. Bxb4 1-0
+
+[Event "Tilburg Grandmaster Tournament"]
+[Site "Tilburg, NED"]
+[Date "1982.09.??"]
+[Round "2"]
+[White "Karpov, Anatoly"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nd2 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a3 a4 10. Ba2 h6 11. N5f3 c5 12. c3 Bd7 13. Ne5 cxd4 14. cxd4
+Be7 15. Ngf3 O-O 16. O-O Be8 17. Bd2 Nbd5 18. Rfc1 Qb6 19. Bc4 Bc6 20. Re1
+Nc7 21. Nxc6 bxc6 22. Bf4 Ncd5 23. Be5 Rfd8 24. Rad1 Bd6 25. Rd2 Bxe5 26.
+dxe5 Nd7 27. g3 Nf8 28. Red1 Rd7 29. Qe4 Rb7 30. Rc2 Rab8 31. Rdd2 Ne7 32.
+Kg2 Qa5 33. h4 Rd7 34. Be2 Rd5 35. Rd4 Rxd4 36. Qxd4 Nd5 37. Rxc6 Qa8 38.
+Rc4 Qb7 39. Rc2 Nb6 40. Bb5 Ng6 41. Qd6 Qa8 42. Bc6 1-0
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "15"]
+[White "Tal,M"]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rdg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Tilburg"]
+[Date "1982.??.??"]
+[Round "7"]
+[White "Nunn,John"]
+[Black "Petrosian,Tigran"]
+[Result "1-0"]
+
+1. e4 c6 2. c4 d5 3. exd5 cxd5 4. cxd5 Nf6 5. Nc3 Nxd5 6. Nf3 Nxc3 7. bxc3
+g6 8. d4 Bg7 9. Bd3 Nc6 10. O-O O-O 11. Re1 Bg4 12. Be4 Rc8 13. Bg5 Re8 14.
+Rb1 Qd7 15. h3 Bxf3 16. Bxf3 b6 17. Bg4 f5 18. Be2 h6 19. Bc1 Kh7 20. d5
+1-0
+
+[Event "?"]
+[Site "Bled"]
+[Date "1961.??.??"]
+[Round "17"]
+[White "Keres, Paul"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. N1e2 e6 7. h4 h6 8.
+Nf4 Bh7 9. c3 Nf6 10. Bd3 Bxd3 11. Nxd3 Bd6 12. Qf3 Nbd7 13. Bf4 Bxf4 14.
+Qxf4 Qb8 15. Qf3 Qd6 16. O-O-O Qd5 17. Qxd5 cxd5 18. f4 Ne4 19. Nxe4 dxe4
+20. Ne5 Rd8 21. h5 1/2-1/2
+
+[Event "?"]
+[Site "Piatgorsky Cup"]
+[Date "1963.??.??"]
+[Round "1"]
+[White "Keres, Paul"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Bc4 e6 7. N1e2 Nf6
+8. Nf4 Bd6 9. Bb3 Nbd7 10. Qf3 Qc7 11. h4 O-O-O 12. h5 Bf5 13. Nxf5 Qa5+
+14. c3 Qxf5 15. Qd3 Qxd3 16. Nxd3 h6 17. Rh4 Rhe8 18. Be3 Nd5 19. O-O-O
+Nxe3 20. fxe3 Nf6 21. Rf1 Re7 22. Nf2 Bg3 23. Rh3 Bd6 24. Bc2 e5 25. Nd3
+exd4 26. exd4 Re2 27. g4 Rde8 28. Bd1 R2e3 29. Rxe3 Rxe3 30. Rf3 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "1"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+Bd3 Bxd3 9. Qxd3 Qc7 10. Bd2 e6 11. O-O-O O-O-O 12. c4 Ngf6 13. Kb1 c5 14.
+Bc3 cxd4 15. Nxd4 a6 16. Nf3 Bc5 17. Qe2 Bd6 18. Ne4 Be7 19. Nxf6 Bxf6 20.
+Bxf6 Nxf6 21. Ne5 Rxd1+ 22. Rxd1 Rd8 23. Rxd8+ Kxd8 24. Qd3+ Ke7 25. Qd4 h5
+26. a3 Nd7 27. Nxd7 Qxd7 28. Qc5+ Qd6 29. Qg5+ Ke8 30. Qe3 Qc6 31. Qg3 g6
+32. b3 Qe4+ 33. Kb2 e5 34. Qe3 Qxg2 35. Qxe5+ Kf8 36. Qh8+ Ke7 37. Qe5+
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "3"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bc4 Nf6 9. O-O O-O 10. Qe2 Nc6 11. Be3 Na5 12. Bd3 b6 13. Bg5 Bb7 14.
+Rad1 Rc8 15. Rfe1 h6 16. Bc1 Bb4 17. Bd2 Bxc3 18. bxc3 Qd5 19. Qf1 Qxa2 20.
+Ne5 Nb3 21. Re2 Nxd2 22. Rexd2 Qd5 23. c4 Qd6 24. Qe2 Rfd8 25. h3 Nd7 26.
+Ng4 h5 27. Ne3 g6 28. Ra2 Ra8 29. Qc2 Kg7 30. Be4 Bxe4 31. Qxe4 Nf6 32. Qh4
+Rd7 33. Rad2 Rad8 34. Rd3 a6 35. Qg5 Ne4 36. Qh4 Nf6 37. Rb3 Qc7 38. d5 Qe5
+39. Rxb6 exd5 40. Nxd5 Nxd5 41. cxd5 Rxd5 42. Qxd8 Rxd8 43. Rxd8 Qe1+
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "5"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 g6 6. Qb3 Bg7 7. cxd5 O-O
+8. g3 Na6 9. Bg2 Qb6 10. Qxb6 axb6 11. Nge2 Nb4 12. O-O Rd8 13. d6 Rxd6 14.
+Bf4 Rd7 15. Rfd1 Nbd5 16. Be5 Bh6 17. a3 e6 18. Nxd5 Nxd5 19. Rd3 Bg5 20.
+Bxd5 exd5 21. h4 Bd8 22. Rc1 Re7 23. Nf4 Be6 24. Rdc3 Bd7 25. Nxd5 Re6 26.
+Bc7 Kg7 27. Bxd8 Rxd8 28. Ne3 b5 29. d5 Rb6 30. Nc2 h6 31. Nb4 g5 32. hxg5
+hxg5 33. Kg2 Rf6 34. Re3 Rh8 35. Nd3 Rd6 36. Ne5 Bh3+ 37. Kf3 Rxd5 38. Rc7
+Be6 39. Rxb7 Rc5 40. Ra7 Bd5+ 41. Kg4 Rc2 42. Kxg5 Rxf2 43. Nd3 Rf3 44.
+Rae7 Rxe3 45. Rxe3 f6+ 46. Kf4 Kf7 47. Nb4 Bc4 48. Rc3 Rh2 49. b3 Be6 50.
+Nd3 Ra2 51. Rc7+ Kg6 52. Nc5 Bf7 53. Rb7 Rxa3 54. Rxb5 Ra1 55. Ne4 Rf1+ 56.
+Ke3 Re1+ 57. Kf3 Rf1+ 58. Ke2 Rb1 59. Nd2 Rg1 60. Kf2 Rc1 61. b4 Rc2 62.
+Ke3 Rc3+ 63. Kf4 Rd3 64. Nf3 Bd5 65. Nh4+ Kf7 66. Rb8 Rd4+ 67. Ke3 Re4+ 68.
+Kf2 Ke7 69. Ng6+ Kd7 70. Nf4 Bc6 71. Nd3 Kc7 72. Rf8 Bb5 73. Nf4 Kd7 74.
+Rf7+ Ke8 75. Rb7 Rxb4 76. Nd5 Rb2+ 77. Ke3 Rb3+ 78. Kf4 Bc4 79. Nxf6+ Kf8
+1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "9"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bd3 Nc6 9. O-O O-O 10. Re1 Bf6 11. Be4 Nce7 12. Qc2 g6 13. Bh6 Bg7 14.
+Bg5 f6 15. Bd2 Bd7 16. Qb3 Bc6 17. Bxd5 exd5 18. Ne4 Rf7 19. Nc5 Nf5 20. h3
+Bf8 21. Ne6 Qd7 22. Nxf8 Rfxf8 23. Bb4 Rfe8 24. Rxe8+ Rxe8 25. Re1 Rxe1+
+26. Bxe1 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "13"]
+[White "Spassky, Boris"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. h4 h6 7. Nf3 Nd7 8.
+h5 Bh7 9. Bd3 Bxd3 10. Qxd3 Qc7 11. Bd2 e6 12. Qe2 Ngf6 13. O-O-O O-O-O 14.
+Ne5 Nxe5 15. dxe5 Nd7 16. f4 Be7 17. Ne4 Nc5 18. Nc3 f6 19. exf6 Bxf6 20.
+Qc4 Qb6 21. b4 Na6 22. Ne4 Nc7 23. Rhe1 Rd4 24. Qb3 Qb5 25. c3 Rxe4 26.
+Rxe4 Qxh5 27. Qc4 Qf5 28. Qe2 h5 29. Be1 Re8 30. g3 a5 31. bxa5 Qxa5 32.
+Qc2 Qf5 33. Ra4 g5 34. fxg5 Bxg5+ 35. Kb1 Qxc2+ 36. Kxc2 e5 37. Re4 Nd5 38.
+Bf2 Nf6 39. Ra4 Kc7 40. Bc5 Nd5 41. Re4 b6 42. Bg1 Bd8 43. Rf1 Nf6 44. Re2
+c5 45. Rf5 Kd6 46. a4 Kd5 47. Kd3 Ng4 48. Rb2 Rh8 49. a5 c4+ 50. Ke2 Ke4
+51. Rf7 bxa5 52. Rb8 a4 53. Rc8 Bf6 54. Rxc4+ Kf5 55. Ra7 a3 56. Rxa3 Rb8
+57. Rb4 Rc8 58. c4 Be7 59. c5 e4 60. Ra7 Bf6 61. Rh7 Kg6 62. Rd7 Kf5 63.
+Rd5+ Be5 64. Rb6 e3 65. Kf3 Nf6 66. Rd3 Rxc5 67. Bxe3 Rc2 68. Rd8 Rc3 69.
+Ke2 Rc2+ 70. Kd1 Rc3 71. Bf2 Ne4 72. Rf8+ Kg5 73. Rb5 Rd3+ 74. Ke2 Rd5 75.
+Rxd5 Nc3+ 76. Kf3 Nxd5 77. Ra8 Kf5 78. Ra5 Ke6 79. Be1 Nf6 80. Rb5 Nd5 81.
+Bd2 Bg7 82. Bc1 Be5 83. Bb2 Bc7 84. Rc5 Bd6 85. Rc1 Ne7 86. Re1+ Kf5 87.
+Ra1 Nc6 88. Ra6 Be5 89. Rxc6 Bxb2 90. Rc5+ Kg6 91. Kf4 1-0
+
+[Event "?"]
+[Site "URS"]
+[Date "1966.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 Nf6 5. Nc3 e6 6. Nf3 Be7 7. cxd5 Nxd5
+8. Bc4 O-O 9. O-O Nc6 10. Re1 Bf6 11. Ne4 b6 12. a3 Bb7 13. Qd3 Rc8 14.
+Nfg5 Bxg5 15. Bxg5 f6 16. Bd2 Qd7 17. Rad1 Nce7 18. Ba2 Rfe8 19. Bb1 Ng6
+20. Qg3 f5 21. Qd6 Rcd8 22. Qxd7 Rxd7 23. Ng5 Rde7 24. Ba2 h6 25. Nf3 Rc7
+26. Rc1 Rxc1 27. Rxc1 Rc8 28. Rxc8+ Bxc8 29. h4 Bb7 1/2-1/2
+
+[Event "Moskva tt"]
+[Site "?"]
+[Date "1961.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Bf5 5. Ng3 Bg6 6. Nf3 Nd7 7. Bc4 e6
+8. O-O Ngf6 9. Ng5 h6 10. Nh3 Bd6 11. Nf4 Bxf4 12. Bxf4 Nd5 13. Bc1 Qh4 14.
+Bd3 Bxd3 15. Qxd3 O-O-O 16. Rd1 N7f6 17. c4 Nc7 18. b4 Rd7 19. Bb2 Rhd8 20.
+Qe2 Qg4 21. f3 Qg6 22. a4 h5 23. b5 h4 24. bxc6 bxc6 25. Ne4 Nxe4 26. fxe4
+h3 27. g3 f5 28. e5 c5 29. dxc5 Rxd1+ 30. Rxd1 Rxd1+ 31. Qxd1 Qe8 32. Qd6
+Kb7 33. c6+ Qxc6 34. Qxc6+ Kxc6 35. Bd4 a5 36. Bc3 Na6 37. Bxa5 Nc5 38. Bb4
+Nxa4 39. g4 fxg4 40. Kf2 Nb2 41. Kg3 Nxc4 42. Kxg4 Nxe5+ 43. Kxh3 Kd5 44.
+Kh4 Kc4 45. Bd6 Nf7 46. Bc7 g6 47. Kg4 Kd5 48. h4 Ke4 49. h5 Ne5+ 1/2-1/2
+
+[Event "URS-ch"]
+[Site "?"]
+[Date "1973.??.??"]
+[Round "?"]
+[White "Tal, Mikhail N."]
+[Black "Petrosian, Tigran V."]
+[Result "0-1"]
+
+1. e4 c6 2. d4 d5 3. Nc3 dxe4 4. Nxe4 Nd7 5. Bc4 Ngf6 6. Ng5 e6 7. Qe2 Nb6
+8. Bb3 a5 9. a4 h6 10. N5f3 c5 11. Bf4 Bd6 12. Be5 O-O 13. O-O-O c4 14.
+Bxc4 Nxa4 15. Nh3 Nb6 16. g4 a4 17. g5 hxg5 18. Nhxg5 a3 19. b3 Bb4 20.
+Rhg1 a2 21. Kb2 Nxc4+ 22. Qxc4 Nd5 23. Ne4 f6 24. Bf4 Ba3+ 25. Ka1 Nxf4 26.
+h4 Rf7 27. Rg4 Qa5 0-1
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "2"]
+[White "Petrosian, Tigran V."]
+[Black "Kuzmin,G"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O dxc4 8.
+Bxc4 a6 9. a3 Ba5 10. dxc5 Bxc3 11. bxc3 Qa5 12. a4 Nbd7 13. c6 bxc6 14.
+Qc2 c5 15. e4 Qc7 16. Re1 Ng4 17. Kh1 Re8 18. h3 Ngf6 19. e5 Nd5 20. Ng5
+Nf8 21. f4 Bb7 22. Ne4 Ng6 23. Qf2 Nb6 24. Bf1 Bxe4 25. Rxe4 Qc6 26. Qc2
+Nd5 27. a5 Red8 28. Kh2 Rab8 29. Rea4 Nge7 30. Bd3 Nf5 31. Bxf5 exf5 32.
+Qxf5 Nxc3 33. Rc4 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1973.??.??"]
+[Round "10"]
+[White "Petrosian, Tigran V."]
+[Black "Smyslov,V"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 b6 6. Ne2 Nc6 7. O-O cxd4 8.
+exd4 Bb7 9. d5 Ne5 10. Bf4 Nxd3 11. Qxd3 exd5 12. cxd5 O-O 13. a3 Bxc3 14.
+Nxc3 Re8 15. Bd6 Ng4 16. Qg3 Nh6 17. Rfe1 Nf5 18. Qf4 Qf6 19. Be5 Qg6 20.
+Qa4 a6 21. Bf4 b5 22. Qb4 Rec8 23. Qe4 h5 24. Qd3 Rc4 25. Re4 Nh4 26. Bg3
+Rxe4 27. Nxe4 Nxg2 28. Kxg2 h4 29. Rd1 hxg3 30. hxg3 Rc8 31. f3 f5 1/2-1/2
+
+[Event "?"]
+[Site "Tilburg"]
+[Date "1982.??.??"]
+[Round "10"]
+[White "Petrosian,Tigran"]
+[Black "Browne,Walter"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Nc3 Bb4 5. e3 O-O 6. Bd3 Bb7 7. O-O d5 8.
+a3 Bd6 9. cxd5 exd5 10. b4 a6 11. Qb3 Qe7 12. Rb1 Nbd7 13. a4 Ne4 14. Bb2
+Ndf6 15. b5 a5 16. Rbd1 Nxc3 17. Bxc3 Ne4 18. Bb2 Rad8 19. Ne5 Kh8 20. Qc2
+f6 21. Nf3 Bc8 22. Ne1 f5 23. g3 Rf6 24. Nf3 Rdf8 25. Ne5 Rh6 26. f3 Ng5
+27. Qg2 Nh3+ 28. Kh1 g5 29. g4 Qf6 30. Rd2 Rh4 31. Rc2 Qg7 32. gxf5 Bxf5
+33. Bxf5 Rxf5 34. Bc3 Rh6 35. Ng4 Rh5 36. Be1 Qe7 37. Bg3 Rf7 38. Rfc1 Kg7
+39. Rc6 Kf8 40. Bxd6 cxd6 41. Qg3 Rh4 42. Qxd6 1-0
+
+[Event "?"]
+[Site "Lone"]
+[Date "1978.??.??"]
+[Round "?"]
+[White "Portisch, Lajos"]
+[Black "Petrosian, Tigran"]
+[Result "0-1"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 b6 5. Bd3 Bb7 6. Nf3 O-O 7. O-O d5 8.
+a3 Bd6 9. b4 dxc4 10. Bxc4 Nbd7 11. Bb2 a5 12. b5 e5 13. Re1 e4 14. Nd2 Qe7
+15. Be2 Rad8 16. Qc2 Rfe8 17. f3 exf3 18. Bxf3 Bxf3 19. Nxf3 Ne4 20. Nxe4
+Qxe4 21. Qxe4 Rxe4 22. Nd2 Ree8 23. e4 Nc5 24. Nc4 Nxe4 25. Rac1 Bf8 26.
+Ne5 Nd6 27. a4 f6 28. Nf3 Rxe1+ 29. Nxe1 Rd7 30. Nf3 Nf5 31. Kf2 h5 32. Rc2
+g5 33. Rc4 Bd6 34. g3 Kf7 35. Ng1 Ne7 36. Ne2 Nd5 37. Bc1 Kg6 38. Rc2 Kf5
+39. Kf3 g4+ 40. Kf2 Rh7 41. Rd2 h4 42. Kg2 Ke4 43. Rd1 Ne3+ 44. Bxe3 Kxe3
+45. Nc3 h3+ 0-1
+
+[Event "?"]
+[Site "Milano"]
+[Date "1975.??.??"]
+[Round "1"]
+[White "Petrosian, Tigran"]
+[Black "Karpov, Anatoly"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 c5 6. Nf3 d5 7. O-O cxd4 8.
+exd4 dxc4 9. Bxc4 b6 10. Bg5 Bb7 11. Qe2 Bxc3 12. bxc3 Nbd7 13. Bd3 Qc7 14.
+c4 Ng4 15. Be4 Bxe4 16. Qxe4 Ngf6 17. Qd3 h6 18. Bxf6 Nxf6 19. a4 Rac8 20.
+Rfc1 Rfd8 21. h3 e5 22. Nxe5 Qxe5 23. dxe5 Rxd3 24. exf6 Rd4 25. a5 gxf6
+26. axb6 axb6 27. Rab1 Rcxc4 28. Rxc4 Rxc4 29. Rxb6 1/2-1/2
+
+[Event "?"]
+[Site "Moscow"]
+[Date "1971.??.??"]
+[Round "1"]
+[White "Petrosian, Tigran"]
+[Black "Kortchnoi, Viktor"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 6. a3 Bxc3+ 7. bxc3
+O-O 8. Bg5 c5 9. e3 Nbd7 10. Bd3 Qa5 11. Ne2 b6 12. O-O Ba6 13. Bxa6 Qxa6
+14. Bxf6 Nxf6 15. Nf4 Qc4 16. Qa2 Qxa2 17. Rxa2 Rac8 18. a4 Rfd8 19. Rb1
+Ne4 20. Ne2 Nd6 21. h4 Nc4 22. Nf4 Kf8 23. g4 g6 24. Kg2 h6 25. Rd1 g5 26.
+hxg5 hxg5 27. Ne2 Nd6 28. Ng3 cxd4 29. Rxd4 Ne4 30. Nxe4 dxe4 31. Rxe4 Rxc3
+32. a5 Rdc8 33. axb6 axb6 34. Rb2 R3c4 35. Rxc4 Rxc4 1/2-1/2
+
+[Event "?"]
+[Site "Wch"]
+[Date "1963.??.??"]
+[Round "?"]
+[White "Petrosian, Tigran V."]
+[Black "Botvinnik, Mikhail"]
+[Result "0-1"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. cxd5 exd5 6. Bg5 h6 7. Bxf6 Qxf6
+8. a3 Bxc3+ 9. Qxc3 c6 10. e3 O-O 11. Ne2 Re8 12. Ng3 g6 13. f3 h5 14. Be2
+Nd7 15. Kf2 h4 16. Nf1 Nf8 17. Nd2 Re7 18. Rhe1 Bf5 19. h3 Rae8 20. Nf1 Ne6
+21. Qd2 Ng7 22. Rad1 Nh5 23. Rc1 Qd6 24. Rc3 Ng3 25. Kg1 Nh5 26. Bd1 Re6
+27. Qf2 Qe7 28. Bb3 g5 29. Bd1 Bg6 30. g4 hxg3 31. Nxg3 Nf4 32. Qh2 c5 33.
+Qd2 c4 34. Ba4 b5 35. Bc2 Nxh3+ 36. Kf1 Qf6 37. Kg2 Nf4+ 38. exf4 Rxe1 39.
+fxg5 Qe6 40. f4 Re2+ 0-1
+
+[Event "?"]
+[Site "Curacao ct"]
+[Date "1962.??.??"]
+[Round "3"]
+[White "Petrosian, Tigran V."]
+[Black "Keres, Paul"]
+[Result "1/2-1/2"]
+
+1. c4 Nf6 2. d4 e6 3. Nf3 b6 4. Nc3 Bb4 5. e3 c5 6. Bd3 d5 7. dxc5 bxc5 8.
+O-O O-O 9. Ne2 Bb7 10. b3 Nbd7 11. Bb2 Qe7 12. Ng3 g6 13. cxd5 exd5 14. a3
+Ba5 15. b4 cxb4 16. Qa4 Bb6 17. axb4 Ng4 18. Rfe1 Nde5 19. Nxe5 Nxe5 20.
+Rad1 Nxd3 21. Rxd3 Rfc8 22. b5 1/2-1/2
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1966.??.??"]
+[Round "20"]
+[White "Petrosian, Tigran V."]
+[Black "Spassky, Boris"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 c5 6. Nf3 d5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 dxc4 10. Bxc4 Qc7 11. Bd3 e5 12. Qc2 Bg4 13. Nxe5 Nxe5 14.
+dxe5 Qxe5 15. f3 Bd7 16. a4 Rfe8 17. e4 c4 18. Be2 Be6 19. Be3 Qc7 20. Rab1
+Nd7 21. Rb5 b6 22. Rfb1 Qc6 23. Bd4 f6 24. Qa2 Kh8 25. Bf1 h6 26. h3 Rab8
+27. a5 Rb7 28. axb6 axb6 29. Qf2 Ra8 30. Qb2 Rba7 31. Bxb6 Ra2 32. Qb4 Rc2
+33. Bf2 Qc7 34. Qe7 Bxh3 35. gxh3 Rxf2 36. Kxf2 Qh2+ 37. Bg2 Ne5 38. Rb8+
+Rxb8 39. Rxb8+ Kh7 40. Rd8 Ng6 41. Qe6 1-0
+
+[Event "?"]
+[Site "Moscow-Wch"]
+[Date "1969.??.??"]
+[Round "10"]
+[White "Petrosian, Tigran V."]
+[Black "Spassky, Boris"]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 b6 6. Ne2 d5 7. O-O dxc4 8.
+Bxc4 Bb7 9. f3 c5 10. a3 cxd4 11. axb4 dxc3 12. Nxc3 Nc6 13. b5 Ne5 14. Be2
+Qc7 15. e4 Rfd8 16. Qe1 Qc5+ 17. Qf2 Qe7 18. Ra3 Ne8 19. Bf4 Ng6 20. Be3
+Nd6 21. Rfa1 Nc8 22. Bf1 f5 23. exf5 exf5 24. Ra4 Re8 25. Bd2 Qc5 26. Qxc5
+bxc5 27. Rc4 Re5 28. Na4 a6 29. Nxc5 axb5 30. Nxb7 Rxa1 31. Rxc8+ Kf7 32.
+Nd8+ Ke7 33. Nc6+ Kd7 34. Nxe5+ Kxc8 35. Nxg6 hxg6 36. Bc3 Rb1 37. Kf2 b4
+38. Bxg7 1-0
+
+[Event "?"]
+[Site "Milano"]
+[Date "1975.??.??"]
+[Round "2"]
+[White "Ljubojevic, Ljubomir"]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 d5 5. a3 Be7 6. Nf3 O-O 7. e3 b6 8.
+cxd5 exd5 9. b4 Re8 10. Bd3 Bb7 11. O-O Bd6 12. Bb2 a6 13. Ne5 c5 14. bxc5
+bxc5 15. Rab1 Qc7 16. h3 c4 1/2-1/2
+
+[Event "32nd ol"]
+[Site "Yerevan ARM"]
+[Date "1996.09.17"]
+[Round "02"]
+[White "Gostisa,L"]
+[Black "Petrosian,A"]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. Nf3 e6 3. g3 d5 4. Bg2 Nbd7 5. O-O b5 6. b3 Bb7 7. c4 bxc4 8.
+bxc4 dxc4 9. Qa4 c5 10. Ba3 Qc7 11. Qxc4 Rc8 12. Rc1 Qb8 1/2-1/2
+
+[Event "?"]
+[Site "Belgrade"]
+[Date "1954.??.??"]
+[Round "?"]
+[White "Janosevic"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 e6 5. Nc3 Nf6 6. Bg5 Be7 7. Nf3 O-O 8.
+Rc1 a6 9. cxd5 exd5 10. Be2 Nc6 11. Ne5 Na5 12. O-O h6 13. Bh4 Bf5 14. Bf3
+Be6 15. Re1 Nc6 16. Ng6 fxg6 17. Rxe6 g5 18. Bg3 Qd7 19. Re1 Rae8 20. Be5
+Kh8 21. Qb3 g4 22. Bxd5 Nxd5 23. Nxd5 Bg5 24. Rcd1 Na5 25. Nb6 Qd8 26. Qa4
+Qxb6 27. Bxg7+ Kxg7 28. Rxe8 Nc6 29. Rxf8 Kxf8 30. d5 Ne5 31. d6 Qxb2 32.
+d7 Nf7 33. Qxg4 Qxa2 34. Qb4+ Be7 35. d8=Q+ Nxd8 36. Rxd8+ Kf7 37. Qf4+ Kg7
+38. Qg4+ Kf6 39. Rd1 b5 40. h4 Qe6 41. Qh5 Kg7 42. Rd3 Bd6 43. Qd1 Bc5 44.
+Rg3+ Kf6 45. Qa1+ Kf5 46. Qb1+ Ke5 47. Rg6 Qf7 48. Qe1+ Kd5 49. Rxa6 Qf4
+50. Qd1+ Kc4 51. Ra2 Bd4 52. Qe2+ Kb4 53. Qe1+ Kb3 54. Qb1+ Kc4 55. Rc2+
+Bc3 56. Re2 Bd4 57. Qc2+ Kd5 58. Qb3+ Kc5 59. g3 Qf6 60. Rc2+ Kb6 61. Kg2
+Qf5 62. Re2 Kc5 63. Qc2+ Qxc2 64. Rxc2+ Kd5 65. f4 b4 66. Kf3 b3 67. Rc1 b2
+68. Rd1 h5 69. g4 hxg4+ 70. Kxg4 Ke4 71. h5 Be3 72. Rb1 Bc1 73. h6 Bxf4 74.
+Re1+ 1-0
+
diff --git a/test/outfiles/test-nochecks-out.pgn b/test/outfiles/test-nochecks-out.pgn
new file mode 100644 (file)
index 0000000..e012556
--- /dev/null
@@ -0,0 +1,29 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "0-1"]
+
+1. f3 e5 2. g4 Qh4 0-1
+
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3 Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3 14.
+Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4 20.
+Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36. }
+22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6 { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5 Kd7 33. Ba7 Kd6 34. Bc5 Kd7 35. Kc3 g6 36. Bd4 f5 { Time control. }
+1/2-1/2
+
diff --git a/test/outfiles/test-nomovenumbers-out.pgn b/test/outfiles/test-nomovenumbers-out.pgn
new file mode 100644 (file)
index 0000000..a39bf80
--- /dev/null
@@ -0,0 +1,17 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+b3 e5 Bb2 d6 d4 exd4 Qxd4 Nc6 Qd2 Nf6 Nc3 Be6 e4 d5 exd5 Bxd5 Qe3+ Be7 Nf3
+O-O Be2 Re8 O-O-O Bb4 Qd3 Bxc3 Bxc3 Qe7 Rhe1 Ne4 Bb2 Rad8 Qe3 b6 Bb5 Qe6
+Nd4 Nxd4 Rxd4 c5 Rxe4 Bxe4 Bxe8 { 2 minutes to time-control at move 36. }
+Rxe8 f3 Bd5 Qxe6 Rxe6 Rxe6 Bxe6 Kd2 Kf8 Be5 b5 Bb8 $2 (Bd6+ { wins }) a6
+Ba7 c4 Kc3 Ke7 Kd4 Kd6 Bc5+ Kd7 Ba7 Kd6 Bc5+ Kd7 Kc3 g6 Bd4 f5 { Time
+control } 1/2-1/2
+
diff --git a/test/outfiles/test-noresults-out.pgn b/test/outfiles/test-noresults-out.pgn
new file mode 100644 (file)
index 0000000..4e6c3d5
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control
+}
+
diff --git a/test/outfiles/test-notags-out.pgn b/test/outfiles/test-notags-out.pgn
new file mode 100644 (file)
index 0000000..33b34b5
--- /dev/null
@@ -0,0 +1,11 @@
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control
+} 1/2-1/2
+
diff --git a/test/outfiles/test-o-out.pgn b/test/outfiles/test-o-out.pgn
new file mode 100644 (file)
index 0000000..2198839
--- /dev/null
@@ -0,0 +1,15 @@
+[Event "?"]
+[Site "?"]
+[Date "????.??.??"]
+[Round "?"]
+[White "?"]
+[Black "?"]
+[Result "1/2-1/2"]
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6
+Bxe6 26. Kd2 Kf8 27. Be5 b5 28. Bb8 a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 1/2-1/2
+
diff --git a/test/outfiles/test-plylimit-out.pgn b/test/outfiles/test-plylimit-out.pgn
new file mode 100644 (file)
index 0000000..c0e3024
--- /dev/null
@@ -0,0 +1,12 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 *
+
diff --git a/test/outfiles/test-r-log.txt b/test/outfiles/test-r-log.txt
new file mode 100644 (file)
index 0000000..382d2fe
--- /dev/null
@@ -0,0 +1,15 @@
+Processing infiles/test-r.txt
+No king move possible to f2.
+File infiles/test-r.txt: Line number: 1
+Failed to make move 3. Kf2 in the game:
+rnb.kbnr
+pppp.ppp
+........
+....p...
+......Pq
+.....P..
+PPPPP..P
+RNBQKBNR
+
+
+0 games matched out of 1.
diff --git a/test/outfiles/test-s-out.pgn b/test/outfiles/test-s-out.pgn
new file mode 100644 (file)
index 0000000..cdcf62b
--- /dev/null
@@ -0,0 +1,49 @@
+[Event "?"]
+[Site "Zuerich"]
+[Date "1953.??.??"]
+[Round "?"]
+[White "Reshevsky, Samuel"]
+[Black "Petrosjan, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 d5 6. Nf3 c5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 b6 10. cxd5 exd5 11. Bb2 c4 12. Bc2 Bg4 13. Qe1 Ne4 14. Nd2
+Nxd2 15. Qxd2 Bh5 16. f3 Bg6 17. e4 Qd7 18. Rae1 dxe4 19. fxe4 Rfe8 20. Qf4
+b5 21. Bd1 Re7 22. Bg4 Qe8 23. e5 a5 24. Re3 Rd8 25. Rfe1 Re6 26. a4 Ne7
+27. Bxe6 fxe6 28. Qf1 Nd5 29. Rf3 Bd3 30. Rxd3 cxd3 31. Qxd3 b4 32. cxb4
+axb4 33. a5 Ra8 34. Ra1 Qc6 35. Bc1 Qc7 36. a6 Qb6 37. Bd2 b3 38. Qc4 h6
+39. h3 b2 40. Rb1 Kh8 41. Be1 1/2-1/2
+
+[Event "?"]
+[Site "Zuerich"]
+[Date "1953.??.??"]
+[Round "?"]
+[White "Smyslov, V."]
+[Black "Petrosjan, Tigran V."]
+[Result "1/2-1/2"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 O-O 5. Bd3 d5 6. Nf3 c5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 b6 10. cxd5 exd5 11. Bb2 c4 12. Bc2 Bg4 13. Qe1 Ne4 14. Nd2
+Nxd2 15. Qxd2 Bh5 16. f3 Bg6 17. e4 Qd7 18. Rae1 f5 19. exd5 Qxd5 20. a4
+Rfe8 21. Qg5 Qf7 22. Ba3 h6 23. Qg3 Rxe1 24. Rxe1 Re8 25. Rxe8+ Qxe8 26.
+Kf2 Na5 27. Qf4 Nb3 28. Bxf5 Bxf5 29. Qxf5 Qxa4 30. Qf8+ Kh7 31. Qf5+ Kg8
+32. Qe6+ Kh7 33. Qe4+ Kg8 34. Qa8+ Kh7 35. Qe4+ Kg8 36. Qd5+ Kh7 37. Be7
+Nc1 38. Qf5+ Kg8 39. Qf8+ Kh7 40. Qf5+ Kg8 41. d5 Qa2+ 42. Kg3 Qd2 43. d6
+Qe1+ 44. Kg4 Nd3 45. Qd5+ Kh7 46. d7 Qe5 47. Qxd3+ cxd3 48. d8=Q 1/2-1/2
+
+[Event "?"]
+[Site "Zuerich"]
+[Date "1953.??.??"]
+[Round "?"]
+[White "Taimanov, M."]
+[Black "Petrosjan, Tigran V."]
+[Result "1-0"]
+
+1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. e3 c5 5. Bd3 O-O 6. Nf3 d5 7. O-O Nc6 8.
+a3 Bxc3 9. bxc3 b6 10. cxd5 exd5 11. Ne5 Qc7 12. Nxc6 Qxc6 13. f3 Be6 14.
+Qe1 Nd7 15. e4 c4 16. Bc2 f5 17. e5 Rf7 18. a4 a5 19. f4 b5 20. axb5 Qxb5
+21. Ba3 Nb6 22. Qh4 Qe8 23. Rf3 Nc8 24. Ba4 Rd7 25. Rb1 Qd8 26. Bxd7 Qxd7
+27. Rg3 Na7 28. Be7 Bf7 29. Qg5 Bg6 30. h4 Nc6 31. Ba3 Nd8 32. h5 Ne6 33.
+Qh4 Bf7 34. h6 g6 35. Qf6 Qd8 36. Be7 Qc7 37. Rxg6+ hxg6 38. h7+ Kxh7 39.
+Qxf7+ Ng7 40. Kf2 1-0
+
diff --git a/test/outfiles/test-selectonly-out.pgn b/test/outfiles/test-selectonly-out.pgn
new file mode 100644 (file)
index 0000000..780491b
--- /dev/null
@@ -0,0 +1,17 @@
+[Event "?"]
+[Site "Yugoslavia, Zagreb"]
+[Date "1959.??.??"]
+[Round "16"]
+[White "Fischer, R."]
+[Black "Petrosian, T."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. Nc3 d5 3. Nf3 Bg4 4. h3 Bxf3 5. Qxf3 Nf6 6. d3 e6 7. g3 Bb4 8.
+Bd2 d4 9. Nb1 Bxd2+ 10. Nxd2 e5 11. Bg2 c5 12. O-O Nc6 13. Qe2 Qe7 14. f4
+O-O-O 15. a3 Ne8 16. b4 cxb4 17. Nc4 f6 18. fxe5 fxe5 19. axb4 Nc7 20. Na5
+Nb5 21. Nxc6 bxc6 22. Rf2 g6 23. h4 Kb7 24. h5 Qxb4 25. Rf7+ Kb6 26. Qf2 a5
+27. c4 Nc3 28. Rf1 a4 29. Qf6 Qc5 30. Rxh7 Rdf8 31. Qxg6 Rxh7 32. Qxh7
+Rxf1+ 33. Bxf1 a3 34. h6 a2 35. Qg8 a1=Q 36. h7 Qd6 37. h8=Q Qa7 38. g4 Kc5
+39. Qf8 Qae7 40. Qa8 Kb4 41. Qh2 Kb3 42. Qa1 Qa3 43. Qxa3+ Kxa3 44. Qh6 Qf7
+45. Kg2 Kb3 46. Qd2 Qh7 47. Kg3 Qxe4 48. Qf2 Qh1 1/2-1/2
+
diff --git a/test/outfiles/test-stalemate-out.pgn b/test/outfiles/test-stalemate-out.pgn
new file mode 100644 (file)
index 0000000..2e1b53a
--- /dev/null
@@ -0,0 +1,18 @@
+[Event "?"]
+[Site "Lloyds Bank Masters"]
+[Date "1994.??.??"]
+[Round "1"]
+[White "Rix,S"]
+[Black "Thipsay,BP"]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. Nf3 Bg4 6. c3 e6 7. Bf4 Nf6 8.
+Nbd2 Bd6 9. Bxd6 Qxd6 10. O-O O-O 11. h3 Bh5 12. Re1 Rab8 13. Qe2 Rfc8 14.
+Qe3 Bxf3 15. Nxf3 b5 16. Rac1 b4 17. b3 bxc3 18. Rxc3 Nb4 19. Bb1 Rxc3 20.
+Qxc3 Ne4 21. Bxe4 dxe4 22. Rxe4 Nxa2 23. Qa5 Nc1 24. Qxa7 Nxb3 25. Ne5 Rf8
+26. Rf4 f5 27. h4 Nd2 28. Qc5 Rd8 29. Qxd6 Rxd6 30. g4 g6 31. Kg2 Ne4 32.
+gxf5 gxf5 33. Nf3 Nf6 34. Ng5 h6 35. Nxe6 Rxe6 36. Rxf5 Kg7 37. Kf3 Kg6 38.
+Re5 Rd6 39. h5+ Kf7 40. Ra5 Rxd4 41. Ra7+ Ke6 42. Rg7 Rh4 43. Ra7 Rxh5 44.
+Ra6+ Kf7 45. Kg3 Rg5+ 46. Kh4 Kg6 47. Ra4 Rf5 48. Kg3 Nh5+ 49. Kh3 Rxf2 50.
+Rg4+ Kf5 51. Rg5+ hxg5 1/2-1/2
+
diff --git a/test/outfiles/test-t-out.pgn b/test/outfiles/test-t-out.pgn
new file mode 100644 (file)
index 0000000..2c2c7f2
--- /dev/null
@@ -0,0 +1,31 @@
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. Bd3 Nc6 5. c3 Nf6 6. Bf4 Bg4 7. Qb3 Na5
+8. Qa4+ Bd7 9. Qc2 e6 10. Nf3 Qb6 11. a4 Rc8 12. Nbd2 Nc6 13. Qb1 Nh5 14.
+Be3 h6 15. Ne5 Nf6 16. h3 Bd6 17. O-O Kf8 18. f4 Be8 19. Bf2 Qc7 20. Bh4
+Ng8 21. f5 Nxe5 22. dxe5 Bxe5 23. fxe6 Bf6 24. exf7 Bxf7 25. Nf3 Bxh4 26.
+Nxh4 Nf6 27. Ng6+ Bxg6 28. Bxg6 Ke7 29. Qf5 Kd8 30. Rae1 Qc5+ 31. Kh1 Rf8
+32. Qe5 Rc7 33. b4 Qc6 34. c4 dxc4 35. Bf5 Rff7 36. Rd1+ Rfd7 37. Bxd7 Rxd7
+38. Qb8+ Ke7 39. Rde1+ 1-0
+
+[Event "USSR-World"]
+[Site "?"]
+[Date "1970"]
+[Round "?"]
+[White "Fischer, Robert J."]
+[Black "Petrosian, Tigran V."]
+[Result "1/2-1/2"]
+
+1. e4 c6 2. d4 d5 3. Nc3 g6 4. e5 Bg7 5. f4 h5 6. Nf3 Bg4 7. h3 Bxf3 8.
+Qxf3 e6 9. g3 Qb6 10. Qf2 Ne7 11. Bd3 Nd7 12. Ne2 O-O-O 13. c3 f6 14. b3
+Nf5 15. Rg1 c5 16. Bxf5 gxf5 17. Be3 Qa6 18. Kf1 cxd4 19. cxd4 Nb8 20. Kg2
+Nc6 21. Nc1 Rd7 22. Qd2 Qa5 23. Qxa5 Nxa5 24. Nd3 Nc6 25. Rac1 Rc7 26. Rc3
+b6 27. Rgc1 Kb7 28. Nb4 Rhc8 29. Rxc6 Rxc6 30. Rxc6 Rxc6 31. Nxc6 Kxc6 32.
+Kf3 1/2-1/2
+
diff --git a/test/outfiles/test-totalplycount-out.pgn b/test/outfiles/test-totalplycount-out.pgn
new file mode 100644 (file)
index 0000000..7b00ea3
--- /dev/null
@@ -0,0 +1,20 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+[TotalPlyCount "73"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/outfiles/test-v-out.pgn b/test/outfiles/test-v-out.pgn
new file mode 100644 (file)
index 0000000..173830a
--- /dev/null
@@ -0,0 +1,66 @@
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Vidarsson, Jon G"]
+[Black "Gislason, Gudmundur"]
+[Result "1-0"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 b5 8.
+g4 h6 9. Rg1 b4 10. Nce2 e5 11. Nb3 d5 12. Ng3 Bb7 13. h4 d4 14. Bf2 Qc7
+15. Bd3 Nc6 16. g5 hxg5 17. hxg5 Nd7 18. g6 f6 19. Qe2 Nd8 20. Nf5 Ne6 21.
+Bc4 Nf4 22. Bf7+ Kd8 23. Qd2 Rh2 24. O-O-O d3 25. Bb6 Qxb6 26. Qxh2 Rc8 27.
+Rd2 a5 28. Kb1 a4 29. Nc1 dxc2+ 30. Rxc2 Rxc2 31. Kxc2 Nc5 32. Rd1+ Kc7 33.
+Qd2 Nfe6 34. Kb1 Kb8 35. Nd3 b3 36. Nxc5 Bxc5 37. Ka1 1-0
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Stefansson, Hannes"]
+[Black "Olafsson, Helgi"]
+[Result "1/2-1/2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 Nbd7 8.
+g4 h6 9. Qd2 b5 10. O-O-O b4 11. Nce2 d5 12. Nf4 dxe4 13. Ndxe6 fxe6 14.
+Bc4 Qc7 15. Bxe6 Ne5 16. Bb3 Bd7 17. fxe4 Bc5 18. Bxc5 Qxc5 19. Nd3 Nxd3+
+20. Qxd3 O-O-O 21. e5 Bb5 22. Qf5+ Nd7 23. Rd5 Qe3+ 24. Kb1 Rhf8 25. Qg6
+Nc5 26. Qxg7 Nxb3 27. axb3 Bc6 28. Rxd8+ Rxd8 29. Rf1 Be4 30. Qf6 Qe2 31.
+Qe6+ Rd7 32. Rc1 Kc7 33. h4 a5 34. g5 hxg5 35. hxg5 Rd1 36. Qe7+ Kb6 37.
+Qe6+ Kc7 38. Qe7+ Kb6 39. Qe6+ Bc6 40. Rxd1 Qxd1+ 41. Ka2 Qxc2 42. Qd6 Qc5
+43. Qb8+ Bb7 44. g6 a4 45. Qd8+ Ka7 46. Qd7 Kb6 47. Qd8+ Ka6 48. Qd3+ Ka5
+49. Qd8+ Ka6 50. Qd3+ Ka7 51. Qd7 Kb6 1/2-1/2
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Vidarsson, Jon G"]
+[Black "Gislason, Gudmundur"]
+[Result "1-0"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 b5 8.
+g4 h6 9. Rg1 b4 10. Nce2 e5 11. Nb3 d5 12. Ng3 Bb7 13. h4 d4 14. Bf2 Qc7
+15. Bd3 Nc6 16. g5 hxg5 17. hxg5 Nd7 18. g6 f6 19. Qe2 Nd8 20. Nf5 Ne6 21.
+Bc4 Nf4 22. Bf7+ Kd8 23. Qd2 Rh2 24. O-O-O d3 25. Bb6 Qxb6 26. Qxh2 Rc8 27.
+Rd2 a5 28. Kb1 a4 29. Nc1 dxc2+ 30. Rxc2 Rxc2 31. Kxc2 Nc5 32. Rd1+ Kc7 33.
+Qd2 Nfe6 34. Kb1 Kb8 35. Nd3 b3 36. Nxc5 Bxc5 37. Ka1 1-0
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Stefansson, Hannes"]
+[Black "Olafsson, Helgi"]
+[Result "1/2-1/2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 Nbd7 8.
+g4 h6 9. Qd2 b5 10. O-O-O b4 11. Nce2 d5 12. Nf4 dxe4 13. Ndxe6 fxe6 14.
+Bc4 Qc7 15. Bxe6 Ne5 16. Bb3 Bd7 17. fxe4 Bc5 18. Bxc5 Qxc5 19. Nd3 Nxd3+
+20. Qxd3 O-O-O 21. e5 Bb5 22. Qf5+ Nd7 23. Rd5 Qe3+ 24. Kb1 Rhf8 25. Qg6
+Nc5 26. Qxg7 Nxb3 27. axb3 Bc6 28. Rxd8+ Rxd8 29. Rf1 Be4 30. Qf6 Qe2 31.
+Qe6+ Rd7 32. Rc1 Kc7 33. h4 a5 34. g5 hxg5 35. hxg5 Rd1 36. Qe7+ Kb6 37.
+Qe6+ Kc7 38. Qe7+ Kb6 39. Qe6+ Bc6 40. Rxd1 Qxd1+ 41. Ka2 Qxc2 42. Qd6 Qc5
+43. Qb8+ Bb7 44. g6 a4 45. Qd8+ Ka7 46. Qd7 Kb6 47. Qd8+ Ka6 48. Qd3+ Ka5
+49. Qd8+ Ka6 50. Qd3+ Ka7 51. Qd7 Kb6 1/2-1/2
+
diff --git a/test/outfiles/test-w1000-out.pgn b/test/outfiles/test-w1000-out.pgn
new file mode 100644 (file)
index 0000000..6038488
--- /dev/null
@@ -0,0 +1,12 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8. exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3 14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4 20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36. } 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5 28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6 32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control. } 1/2-1/2
+
diff --git a/test/outfiles/test-w60-out.pgn b/test/outfiles/test-w60-out.pgn
new file mode 100644 (file)
index 0000000..ca594e2
--- /dev/null
@@ -0,0 +1,21 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time
+pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3
+Be6 7. e4 d5 8. exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2
+Re8 12. O-O-O Bb4 13. Qd3 Bxc3 14. Bxc3 Qe7 15. Rhe1 Ne4 16.
+Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4 20. Rxd4 c5 21.
+Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36. }
+22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2
+Kf8 27. Be5 b5 28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29.
+Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6 32. Bc5+ Kd7 33. Ba7 Kd6 34.
+Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control. } 1/2-1/2
+
diff --git a/test/outfiles/test-w75-out.pgn b/test/outfiles/test-w75-out.pgn
new file mode 100644 (file)
index 0000000..b393197
--- /dev/null
@@ -0,0 +1,19 @@
+[Event "Dover vs Herne Bay, Minor League"]
+[Site "Margate Chess Club"]
+[Date "1994.10.10"]
+[Round ""]
+[White "Barnes, David J."]
+[Black "Horton, Mark"]
+[Result "1/2-1/2"]
+
+{ Game played inaccurately by White under extreme time pressure. }
+
+1. b3 e5 2. Bb2 d6 3. d4 exd4 4. Qxd4 Nc6 5. Qd2 Nf6 6. Nc3 Be6 7. e4 d5 8.
+exd5 Bxd5 9. Qe3+ Be7 10. Nf3 O-O 11. Be2 Re8 12. O-O-O Bb4 13. Qd3 Bxc3
+14. Bxc3 Qe7 15. Rhe1 Ne4 16. Bb2 Rad8 17. Qe3 b6 18. Bb5 Qe6 19. Nd4 Nxd4
+20. Rxd4 c5 21. Rxe4 Bxe4 22. Bxe8 { 2 minutes to time-control at move 36.
+} 22... Rxe8 23. f3 Bd5 24. Qxe6 Rxe6 25. Rxe6 Bxe6 26. Kd2 Kf8 27. Be5 b5
+28. Bb8 $2 (28. Bd6+ { wins }) 28... a6 29. Ba7 c4 30. Kc3 Ke7 31. Kd4 Kd6
+32. Bc5+ Kd7 33. Ba7 Kd6 34. Bc5+ Kd7 35. Kc3 g6 36. Bd4 f5 { Time control.
+} 1/2-1/2
+
diff --git a/test/outfiles/test-x-out.pgn b/test/outfiles/test-x-out.pgn
new file mode 100644 (file)
index 0000000..173830a
--- /dev/null
@@ -0,0 +1,66 @@
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Vidarsson, Jon G"]
+[Black "Gislason, Gudmundur"]
+[Result "1-0"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 b5 8.
+g4 h6 9. Rg1 b4 10. Nce2 e5 11. Nb3 d5 12. Ng3 Bb7 13. h4 d4 14. Bf2 Qc7
+15. Bd3 Nc6 16. g5 hxg5 17. hxg5 Nd7 18. g6 f6 19. Qe2 Nd8 20. Nf5 Ne6 21.
+Bc4 Nf4 22. Bf7+ Kd8 23. Qd2 Rh2 24. O-O-O d3 25. Bb6 Qxb6 26. Qxh2 Rc8 27.
+Rd2 a5 28. Kb1 a4 29. Nc1 dxc2+ 30. Rxc2 Rxc2 31. Kxc2 Nc5 32. Rd1+ Kc7 33.
+Qd2 Nfe6 34. Kb1 Kb8 35. Nd3 b3 36. Nxc5 Bxc5 37. Ka1 1-0
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Stefansson, Hannes"]
+[Black "Olafsson, Helgi"]
+[Result "1/2-1/2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 Nbd7 8.
+g4 h6 9. Qd2 b5 10. O-O-O b4 11. Nce2 d5 12. Nf4 dxe4 13. Ndxe6 fxe6 14.
+Bc4 Qc7 15. Bxe6 Ne5 16. Bb3 Bd7 17. fxe4 Bc5 18. Bxc5 Qxc5 19. Nd3 Nxd3+
+20. Qxd3 O-O-O 21. e5 Bb5 22. Qf5+ Nd7 23. Rd5 Qe3+ 24. Kb1 Rhf8 25. Qg6
+Nc5 26. Qxg7 Nxb3 27. axb3 Bc6 28. Rxd8+ Rxd8 29. Rf1 Be4 30. Qf6 Qe2 31.
+Qe6+ Rd7 32. Rc1 Kc7 33. h4 a5 34. g5 hxg5 35. hxg5 Rd1 36. Qe7+ Kb6 37.
+Qe6+ Kc7 38. Qe7+ Kb6 39. Qe6+ Bc6 40. Rxd1 Qxd1+ 41. Ka2 Qxc2 42. Qd6 Qc5
+43. Qb8+ Bb7 44. g6 a4 45. Qd8+ Ka7 46. Qd7 Kb6 47. Qd8+ Ka6 48. Qd3+ Ka5
+49. Qd8+ Ka6 50. Qd3+ Ka7 51. Qd7 Kb6 1/2-1/2
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Vidarsson, Jon G"]
+[Black "Gislason, Gudmundur"]
+[Result "1-0"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 b5 8.
+g4 h6 9. Rg1 b4 10. Nce2 e5 11. Nb3 d5 12. Ng3 Bb7 13. h4 d4 14. Bf2 Qc7
+15. Bd3 Nc6 16. g5 hxg5 17. hxg5 Nd7 18. g6 f6 19. Qe2 Nd8 20. Nf5 Ne6 21.
+Bc4 Nf4 22. Bf7+ Kd8 23. Qd2 Rh2 24. O-O-O d3 25. Bb6 Qxb6 26. Qxh2 Rc8 27.
+Rd2 a5 28. Kb1 a4 29. Nc1 dxc2+ 30. Rxc2 Rxc2 31. Kxc2 Nc5 32. Rd1+ Kc7 33.
+Qd2 Nfe6 34. Kb1 Kb8 35. Nd3 b3 36. Nxc5 Bxc5 37. Ka1 1-0
+
+[Event "Kopavogur International Tournament"]
+[Site "Kopavogur ICE"]
+[Date "1994.04.16"]
+[Round "8"]
+[White "Stefansson, Hannes"]
+[Black "Olafsson, Helgi"]
+[Result "1/2-1/2"]
+
+1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e6 7. f3 Nbd7 8.
+g4 h6 9. Qd2 b5 10. O-O-O b4 11. Nce2 d5 12. Nf4 dxe4 13. Ndxe6 fxe6 14.
+Bc4 Qc7 15. Bxe6 Ne5 16. Bb3 Bd7 17. fxe4 Bc5 18. Bxc5 Qxc5 19. Nd3 Nxd3+
+20. Qxd3 O-O-O 21. e5 Bb5 22. Qf5+ Nd7 23. Rd5 Qe3+ 24. Kb1 Rhf8 25. Qg6
+Nc5 26. Qxg7 Nxb3 27. axb3 Bc6 28. Rxd8+ Rxd8 29. Rf1 Be4 30. Qf6 Qe2 31.
+Qe6+ Rd7 32. Rc1 Kc7 33. h4 a5 34. g5 hxg5 35. hxg5 Rd1 36. Qe7+ Kb6 37.
+Qe6+ Kc7 38. Qe7+ Kb6 39. Qe6+ Bc6 40. Rxd1 Qxd1+ 41. Ka2 Qxc2 42. Qd6 Qc5
+43. Qb8+ Bb7 44. g6 a4 45. Qd8+ Ka7 46. Qd7 Kb6 47. Qd8+ Ka6 48. Qd3+ Ka5
+49. Qd8+ Ka6 50. Qd3+ Ka7 51. Qd7 Kb6 1/2-1/2
+
diff --git a/test/outfiles/test-z-out.pgn b/test/outfiles/test-z-out.pgn
new file mode 100644 (file)
index 0000000..8a7b929
--- /dev/null
@@ -0,0 +1,22 @@
+[Event "?"]
+[Site "Belgrade"]
+[Date "1954.??.??"]
+[Round "?"]
+[White "Janosevic"]
+[Black "Petrosian, Tigran V."]
+[Result "1-0"]
+
+1. e4 c6 2. d4 d5 3. exd5 cxd5 4. c4 e6 5. Nc3 Nf6 6. Bg5 Be7 7. Nf3 O-O 8.
+Rc1 a6 9. cxd5 exd5 10. Be2 Nc6 11. Ne5 Na5 12. O-O h6 13. Bh4 Bf5 14. Bf3
+Be6 15. Re1 Nc6 16. Ng6 fxg6 17. Rxe6 g5 18. Bg3 Qd7 19. Re1 Rae8 20. Be5
+Kh8 21. Qb3 g4 22. Bxd5 Nxd5 23. Nxd5 Bg5 24. Rcd1 Na5 25. Nb6 Qd8 26. Qa4
+Qxb6 27. Bxg7+ Kxg7 28. Rxe8 Nc6 29. Rxf8 Kxf8 30. d5 Ne5 31. d6 Qxb2 32.
+d7 Nf7 33. Qxg4 Qxa2 34. Qb4+ Be7 35. d8=Q+ Nxd8 36. Rxd8+ Kf7 37. Qf4+ Kg7
+38. Qg4+ Kf6 39. Rd1 b5 40. h4 Qe6 41. Qh5 Kg7 42. Rd3 Bd6 43. Qd1 Bc5 44.
+Rg3+ Kf6 45. Qa1+ Kf5 46. Qb1+ Ke5 47. Rg6 Qf7 48. Qe1+ Kd5 49. Rxa6 Qf4
+50. Qd1+ Kc4 51. Ra2 Bd4 52. Qe2+ Kb4 53. Qe1+ Kb3 54. Qb1+ Kc4 55. Rc2+
+Bc3 56. Re2 Bd4 57. Qc2+ Kd5 58. Qb3+ Kc5 59. g3 Qf6 60. Rc2+ Kb6 61. Kg2
+Qf5 62. Re2 Kc5 63. Qc2+ Qxc2 64. Rxc2+ Kd5 65. f4 b4 66. Kf3 b3 67. Rc1 b2
+68. Rd1 h5 69. g4 hxg4+ 70. Kxg4 Ke4 71. h5 Be3 72. Rb1 Bc1 73. h6 Bxf4 74.
+Re1+ 1-0
+
diff --git a/test/runtests b/test/runtests
new file mode 100755 (executable)
index 0000000..962bf22
--- /dev/null
@@ -0,0 +1,428 @@
+#!/bin/bash
+# Script to run a battery of tests of the basic functionality of pgn-extract
+# Copyright (C) David J. Barnes, 2013
+
+# Location of the file of ECO classifications.
+ECO_FILE="../eco.pgn"
+export ECO_FILE
+
+# Location of the test input files
+INPUT="infiles"
+
+# Test template:
+# 
+#     + Input file containing games with 
+#     - Input file(s):
+#     - Resulting output ...
+#     - Expected output: ...
+#     - Command: pgn-extract ...
+
+# No flags:
+#     + No input file.
+#     - Input file(s): N/A
+#     - Example input:
+#       f3 e5 g4 Qh4 0-1
+#     - Resulting output should be that the game input on standard input is
+#       formatted as PGN on standard output.
+#     - Expected output: 
+#       Contents of fools-mate.pgn on standard output.
+../pgn-extract < $INPUT/fools-mate.txt
+
+# No flags:
+#     + Single input file
+#     - Input file(s): fools-mate.txt
+#     - Resulting output should be the input formatted as PGN on standard output.
+#     - Expected output: Contents of fools-mate.pgn should appear on standard output.
+../pgn-extract $INPUT/fools-mate.txt
+
+# -7 / --seven
+#     + Input file with games having tags additional to the seven tag roster.
+#     - Input file(s): test-7.pgn
+#     - Game output should have only the tags of the seven tag roster.
+#     - Expected output: test-7-out.pgn
+../pgn-extract -7 -otest-7-out.pgn $INPUT/test-7.pgn
+
+# -a / --append
+#     + Input file containing games in any accepted format.
+#     - Input file(s): test-a.txt
+#     - Resulting output should contain two versions of the input game
+#       formatted in PGN. The --output command is run first to create
+#       a new file, then the -a version to append to that file.
+#     - Expected output: test-a-out.pgn
+../pgn-extract --output test-a-out.pgn $INPUT/test-a.txt
+../pgn-extract -atest-a-out.pgn $INPUT/test-a.txt
+
+../pgn-extract --output test-a-out.pgn $INPUT/test-a.txt
+../pgn-extract --append test-a-out.pgn $INPUT/test-a.txt
+
+# -A
+#     + Input file containing games and a file of arguments.
+#     - Input file(s): fischer.pgn, petrosian.pgn, arglist.txt
+#     - Resulting output should be files separating the unique and
+#       duplicated games in the input files.
+#     - Expected output: test-A-unique.pgn, test-A-dupes.pgn
+../pgn-extract -A$INPUT/argslist.txt
+
+# -b
+#     + Input file containing games of different length.
+#     - Input file(s): fischer.pgn
+#     - Resulting output: games whose number of moves is within
+#       the specified bounds.
+# 
+#     - Expected output: 45 moves or more: fischer-bl45-out.pgn
+../pgn-extract -bl45 -ofischer-bl45-out.pgn $INPUT/fischer.pgn
+
+#     - Expected output: 45 moves or less: fischer-bu45-out.pgn
+../pgn-extract -bu45 -ofischer-bu45-out.pgn $INPUT/fischer.pgn
+
+#     - Expected output: exactly 30 moves: fischer-b30-out.pgn
+../pgn-extract -b30 -ofischer-b30-out.pgn $INPUT/fischer.pgn
+
+# 
+# -c / --checkfile
+#     + Input files containing games.
+#     - Input file(s): fischer.pgn, petrosian.pgn
+#     - Resulting output should contain matched games that do not already occur in
+#       the check file.
+#     - Expected output: test-c-out.pgn
+../pgn-extract -c$INPUT/petrosian.pgn -D -TpPetrosian -otest-c-out.pgn $INPUT/fischer.pgn
+../pgn-extract -c$INPUT/clist.txt -D -TpPetrosian -otest-c-out.pgn $INPUT/fischer.pgn
+
+# -C / --nocomments
+#     + Input file containing games with comments
+#     - Input file(s): test-C.pgn
+#     - Resulting output should have all comments removed.
+#     - Expected output: test-C-out.pgn
+../pgn-extract -C -otest-C-out.pgn $INPUT/test-C.pgn
+
+# -d / --duplicates
+#     + Input file containing games with duplicates and non-duplicates.
+#     - Input file(s): fischer.pgn, $INPUT/petrosian.pgn
+#     - Resulting output should be files separating the unique and
+#       duplicated games in the input files.
+#     - Expected output: test-d-unique.pgn, test-d-dupes.pgn
+../pgn-extract -dtest-d-dupes.pgn -otest-d-unique.pgn $INPUT/fischer.pgn $INPUT/petrosian.pgn
+
+# -D / --noduplicates
+#     + Input file containing games with duplicates and non-duplicates.
+#     - Input file(s): fischer.pgn, $INPUT/petrosian.pgn
+#     - Resulting output should be a file containing the combined input
+#       with duplicate games removed.
+#     - Expected output: test-D-unique.pgn
+../pgn-extract -D -otest-D-unique.pgn $INPUT/fischer.pgn $INPUT/petrosian.pgn
+../pgn-extract --noduplicates -otest-D-unique.pgn $INPUT/fischer.pgn $INPUT/petrosian.pgn
+
+# -e
+#     + Input file containing games without ECO classifications.
+#     - Input file(s): test-e.pgn and eco.pgn in the test folder.
+#     - Resulting output should have ECO classification added to the tags.
+#     - Expected output: test-e-out.pgn
+../pgn-extract -e -otest-e-out.pgn $INPUT/test-e.pgn
+../pgn-extract -e$ECO_FILE -otest-e-out.pgn $INPUT/test-e.pgn
+
+# -E
+#     + Input file containing games.
+#     - Input file(s): test-E.pgn and eco.pgn if -e flag is used.
+#     - Resulting output should be separate files for each ECO classification
+#       at the level of the initial letter (A-E).
+#     - Expected output: A.pgn, B.pgn, E.pgn
+../pgn-extract -e -E1 $INPUT/test-E.pgn
+
+# -f
+#     + Input files containing games.
+#     - Input file(s): test-f1.pgn, test-f2.pgn, files.txt
+#     - Resulting output should be the combination of the input files.
+#     - Expected output: test-f-out.pgn
+../pgn-extract -f$INPUT/files.txt -otest-f-out.pgn
+
+# -F:
+#     + Input file containing games without a trailing FEN comment.
+#     - Input file(s): test-F.pgn
+#     - Resulting output should have a comment at the end containing
+#       the FEN description of the final position.
+#     - Expected output: test-F-out.pgn
+../pgn-extract -F -otest-F-out.pgn $INPUT/test-F.pgn
+
+# 
+# -h / -? / --help
+#     + No input required.
+#     - Input file(s): N/A
+#     - Resulting output should be a description of how to use pgn-extract
+#     - Expected output: N/A
+../pgn-extract -h
+# ../pgn-extract -?
+# ../pgn-extract --help
+
+# -l
+#     + Input file containing games.
+#     - Input file(s): fischer.pgn
+#     - Resulting output: List of games parsed written to log.txt
+#     - Expected output: log.txt
+../pgn-extract -llog.txt -otest-l-out.pgn $INPUT/fischer.pgn
+
+# -L
+#     + Input file containing games.
+#     - Input file(s): test-L1.pgn, test-L2.pgn
+#     - Resulting output should be that log.txt contains the combined
+#       logs from two runs of pgn-extract.
+#     - Expected output: log.txt
+../pgn-extract -llog.txt -r $INPUT/test-L1.pgn
+../pgn-extract -Llog.txt -r $INPUT/test-L2.pgn
+
+# -M / --checkmate
+#     + Input file containing games.
+#     - Input file(s): test-checkmate.pgn
+#     - Resulting output should contain only those games that end in checkmate.
+#     - Expected output: test-checkmate-out.pgn
+../pgn-extract --checkmate -otest-checkmate-out.pgn $INPUT/test-checkmate.pgn
+
+# -n
+#     + Input file containing games.
+#     - Input file(s): petrosian.pgn
+#     - Resulting output should be separate files containing matched
+#       and non-matched games.
+#     - Expected output: test-n-matched.pgn, test-n-unmatched.pgn
+../pgn-extract -TpFischer -otest-n-matched.pgn -ntest-n-unmatched.pgn $INPUT/petrosian.pgn
+
+# -N / --nonags
+#     + Input file containing games with NAGs.
+#     - Input file(s): test-N.pgn
+#     - Resulting output should have all NAGs removed.
+#     - Expected output: test-N-out.pgn
+../pgn-extract -N -otest-N-out.pgn $INPUT/test-N.pgn
+
+# 
+# -o / --output
+#     + Input file containing games in any accepted format.
+#     - Input file(s): test-o.txt
+#     - Resulting output should contain the input game formatted in PGN.
+#     - Expected output: test-o-out.pgn
+../pgn-extract -otest-o-out.pgn $INPUT/test-o.txt
+../pgn-extract --output test-o-out.pgn $INPUT/test-o.txt
+
+# -P
+#     + Input file containing games with different sequences for the same
+#       opening.
+#     - Input file(s): test-P.pgn, Pvars.txt
+#     - Resulting output should be games whose opening move exactly match
+#       the sequence specified in Pvars.txt
+#     - Expected output: test-P-out.pgn
+../pgn-extract -P -v$INPUT/Pvars.txt -otest-P-out.pgn $INPUT/test-P.pgn
+
+# -r
+#     + Input file containing games in any accepted format.
+#     - Input file(s): test-r.text
+#     - Resulting output should contain tag summary lines for the games
+#       matched and a report of any errors.
+#     - Expected output: test-r-log.text
+../pgn-extract -r -Ltest-r-log.txt $INPUT/test-r.txt
+
+# -R
+#     + Input file containing games.
+#     - Input file(s): test-R.pgn, roster.txt
+#     - Resulting output should contain games with their tag roster in
+#       the order specified in roster.txt
+#     - Expected output: test-R-out.pgn
+../pgn-extract -R$INPUT/roster.txt --output test-R-out.pgn $INPUT/test-R.pgn
+
+# -s
+#     + Input file containing games.
+#     - Input file(s): test-s.pgn
+#     - Resulting output should be silent, with games written to the output file.
+#     - Expected output: test-s-out.pgn
+../pgn-extract -s -o test-s-out.pgn $INPUT/test-s.pgn
+
+# -S
+#     + Input file containing games whose players' names have slight
+#       sound variations from anglesized versions.
+#     - Input file(s): test-S.pgn
+#     - Resulting output should be games that match by ignoring slight
+#       soundex differences.
+#     - Expected output: test-S-out.pgn
+../pgn-extract -S -TpPetrosian -otest-S-out.pgn $INPUT/test-S.pgn
+
+# -t
+#     + Input file containing games and a file of tag criteria.
+#     - Input file(s): test-t.pgn, taglist.txt
+#     - Resulting output should be only those games whose tags match
+#       all of the criteria.
+#     - Expected output: test-t-out.pgn
+../pgn-extract -t$INPUT/taglist.txt -otest-t-out.pgn $INPUT/test-t.pgn
+
+# -T
+#     + Input file containing games with tag information.
+#     - Input file(s): fischer.pgn, test-Ta.pgn (and eco.pgn for -Te test.)
+#     - Resulting output should contain only those games whose tag information
+#       matches that specified.
+#     - Expected output: test-Ta-out.pgn, test-Tb-out.pgn, test-Td-out.pgn,
+#                        test-Te-out.pgn, test-Tp-out.pgn, test-Tw-out.pgn
+../pgn-extract -Td1970 -otest-Td-out.pgn $INPUT/fischer.pgn
+../pgn-extract -TbPetrosian -otest-Tb-out.pgn $INPUT/fischer.pgn
+../pgn-extract -e -TeB14 -otest-Te-out.pgn $INPUT/fischer.pgn
+../pgn-extract -TpPetrosian -otest-Tp-out.pgn $INPUT/fischer.pgn
+../pgn-extract -Tr0-1 -otest-Tr-out.pgn $INPUT/fischer.pgn
+../pgn-extract -TwFischer -otest-Tw-out.pgn $INPUT/fischer.pgn
+../pgn-extract -TaBarnes -otest-Ta-out.pgn $INPUT/test-Ta.pgn
+
+# -U / --nounique
+#     + Input file containing games with duplicates and non-duplicates.
+#     - Input file(s): fischer.pgn, petrosian.pgn
+#     - Resulting output should be a file containing just the duplicate games.
+#     - Expected output: test-U-unique.pgn
+../pgn-extract -U -otest-U-unique.pgn $INPUT/fischer.pgn $INPUT/petrosian.pgn
+../pgn-extract --nounique -otest-U-unique.pgn $INPUT/fischer.pgn $INPUT/petrosian.pgn
+
+# -v
+#     + Input file containing games.
+#     - Input file(s): najdorf.pgn, vvars.txt
+#     - Resulting output should be only those games whose opening moves
+#       textually match (in any order) the moves in vars.txt.
+#     - Expected output: test-v-out.pgn
+../pgn-extract -v$INPUT/vvars.txt -otest-v-out.pgn $INPUT/najdorf.pgn
+
+# -V
+#     + Input file containing games with variations
+#     - Input file(s): test-V.pgn
+#     - Resulting output should have all variations removed.
+#     - Expected output: test-V-out.pgn
+../pgn-extract -V -otest-V-out.pgn $INPUT/test-V.pgn
+
+# -w / --linelength
+#     + Input file containing games.
+#     - Input file(s): test-w.pgn
+#     - Resulting output Games formatted up to the specified line length.
+#       The default is 75.
+#     - Expected output: test-w60-out.pgn, test-w75-out.pgn, test-w1000-out.pgn
+../pgn-extract -w60 -otest-w60-out.pgn $INPUT/test-w.pgn
+../pgn-extract -w75 -otest-w75-out.pgn $INPUT/test-w.pgn
+../pgn-extract -w1000 -otest-w1000-out.pgn $INPUT/test-w.pgn
+
+../pgn-extract --linelength 60 -otest-w60-out.pgn $INPUT/test-w.pgn
+../pgn-extract --linelength 75 -otest-w75-out.pgn $INPUT/test-w.pgn
+../pgn-extract --linelength 1000 -otest-w1000-out.pgn $INPUT/test-w.pgn
+
+# -W
+#     + Input file containing games.
+#     - Input file(s): test-W.pgn
+#     - Resulting output should be games formatted in the specified notation:
+#       halg (hyphenated long algebraic), lalg (non-hyphenated long algebraic),
+#       elalg (enhanced long algebraic), uci (UCI-compatible output),
+#      and alternative piece letters.
+#     - Expected output: test-Whalg-out.pgn, test-Wlalg-out.pgn,
+#                        test-elalg-out.pgn, test-Wdeutsch-out.pgn,
+#                       test-Wuci-out.pgn
+../pgn-extract -Whalg -otest-Whalg-out.pgn $INPUT/test-W.pgn
+../pgn-extract -Wlalg -otest-Wlalg-out.pgn $INPUT/test-W.pgn
+../pgn-extract -Welalg -otest-Welalg-out.pgn $INPUT/test-W.pgn
+../pgn-extract -WsanBSLTDK -otest-Wdeutsch-out.pgn $INPUT/test-W.pgn
+../pgn-extract -Wuci -otest-Wuci-out.pgn $INPUT/test-W.pgn
+
+# -x
+#     + Input file containing games.
+#     - Input file(s): najdorf.pgn, xvars.txt
+#     - Resulting output should be only those games which match
+#       the result of reaching the opening sequence in vars.txt.
+#     - Expected output: test-x-out.pgn
+../pgn-extract -x$INPUT/xvars.txt -otest-x-out.pgn $INPUT/najdorf.pgn
+
+# -Z
+#     + Input file containing games with duplicates and non-duplicates.
+#     - Input file(s): fischer.pgn, petrosian.pgn
+#     - Resulting output should be files separating the unique and
+#       duplicated games in the input files.
+#     - Expected output: test-Z-unique.pgn, test-Z-dupes.pgn
+../pgn-extract -Z -dtest-Z-dupes.pgn -otest-Z-unique.pgn $INPUT/fischer.pgn $INPUT/petrosian.pgn
+
+# -z
+#     + Input file containing games.
+#     - Input file(s): petrosian.pgn, zmatch.txt
+#     - Resulting output should be games whose material balance matches that
+#       specified in zmatch.txt
+#     - Expected output: test-z-out.pgn
+../pgn-extract -z$INPUT/zmatch.txt -otest-z-out.pgn $INPUT/petrosian.pgn
+
+# -#
+#     + Input file containing games.
+#     - Input file(s): test-hash.pgn
+#     - Resulting output The input file split in to separate sub-files,
+#       each containing 10 games, except the last which may contain fewer.
+#     - Expected output: 1.pgn, 2.pgn
+../pgn-extract -#20 $INPUT/test-hash.pgn
+
+# --evaluation
+#     + Input file containing games.
+#     - Input file(s): test-evaluation.pgn
+#     - Resulting output should include an evaluation value in a comment
+#       after every move.
+#     - Expected output: test-evaluation-out.pgn
+../pgn-extract --evaluation -otest-evaluation-out.pgn $INPUT/test-evaluation.pgn
+
+# --fencomments
+#     + Input file containing games.
+#     - Input file(s): test-fencomments.pgn
+#     - Resulting output should have a comment after every move containing a
+#       FEN description of the position after that move.
+#     - Expected output: test-fencomments-out.pgn
+../pgn-extract --fencomments -otest-fencomments-out.pgn $INPUT/test-fencomments.pgn
+
+# --markmatches
+#     + Input file containing games.
+#     - Input file(s): najdorf.pgn, xvars.txt
+#     - Resulting output should be only those games which match
+#       the result of reaching the opening sequence in vars.txt.
+#       The point of each match is marked with the comment { MATCH }
+#     - Expected output: test-markmatches-out.pgn
+../pgn-extract --markmatches MATCH -x$INPUT/xvars.txt -otest-markmatches-out.pgn $INPUT/najdorf.pgn
+
+# --nochecks
+#     + Input file containing games with moves involving moves that give check
+#       and/or mate.
+#     - Input file(s): test-nochecks.pgn
+#     - Resulting output should contain games with no check indicators after moves.
+#     - Expected output: test-nochecks-out.pgn
+../pgn-extract --nochecks -otest-nochecks-out.pgn $INPUT/test-nochecks.pgn
+
+# --nomovenumbers
+#     + Input file containing games with move numbers.
+#     - Input file(s): test-nomovenumbers.pgn
+#     - Resulting output should contain games with no move numbers.
+#     - Expected output: test-nomovenumbers-out.pgn
+../pgn-extract -otest-no-movenumbers-out.pgn --nomovenumbers $INPUT/test-nomovenumbers.pgn
+
+# --noresults
+#     + Input file containing games with results.
+#     - Input file(s): test-noresults.pgn
+#     - Resulting output should contain games with no results.
+#     - Expected output: test-noresults-out.pgn
+../pgn-extract -otest-no-results-out.pgn --noresults $INPUT/test-noresults.pgn
+
+# --notags
+#     + Input file containing games with tag information.
+#     - Input file(s): test-notags.pgn
+#     - Resulting output should contain games with no tag information.
+#     - Expected output: test-notags-out.pgn
+../pgn-extract -otest-no-tags-out.pgn --notags $INPUT/test-notags.pgn
+
+# --plylimit
+#     + Input file containing games.
+#     - Input file(s): test-plylimit.pgn
+#     - Resulting output should contain games whose number of moves (plies) are
+#       limited at the specified ply limit.
+#     - Expected output: test-plylimit-out.pgn
+../pgn-extract --plylimit 10 -otest-plylimit-out.pgn $INPUT/test-plylimit.pgn
+
+# --stalemate
+#     + Input file containing games.
+#     - Input file(s): test-stalemate.pgn
+#     - Resulting output should contain only those games that end in stalemate.
+#     - Expected output: test-stalemate-out.pgn
+../pgn-extract --stalemate -otest-stalemate-out.pgn $INPUT/test-stalemate.pgn
+
+# Test on a file with a string too long to be output within the
+# defined line length.
+#     + Input file containing a game with a very long comment.
+#     + Input file(s): test-long-line.pgn
+#     + Resulting output should contain the game properly formatted and
+#       the log file should contain an error message reporting the problem.
+#     + Expected output: test-long-line-out.pgn, test-long-line-log.txt
+../pgn-extract -otest-long-line-out.pgn -ltest-long-line-log.txt $INPUT/test-long-line.pgn
diff --git a/test/tests.txt b/test/tests.txt
new file mode 100644 (file)
index 0000000..2b9b1ef
--- /dev/null
@@ -0,0 +1,407 @@
+Now slightly out-of-date version of what is in Makefile.
+
+Template:
+
+    + Input file containing games with 
+    - Input file(s):
+    - Resulting output ...
+    - Expected output: ...
+    - Command: pgn-extract 
+
+No flags:
+
+    + No input file.
+    - Input file(s): N/A
+    - Example input:
+      f3 e5 g4 Qh4 0-1
+    - Resulting output should be that the game input on standard input is
+      formatted as PGN on standard output.
+    - Expected output: 
+      Contents of fools-mate.pgn on standard output.
+    - Command: pgn-extract < fools-mate.txt
+
+    + Single input file
+    - Input file(s): fools-mate.txt
+    - Resulting output should be the input formatted as PGN on standard output.
+    - Expected output: Contents of fools-mate.pgn should appear on standard output.
+    - Command: pgn-extract fools-mate.txt
+
+-7 / --seven
+    + Input file with games having tags additional to the seven tag roster.
+    - Input file(s): test-7.pgn
+    - Game output should have only the tags of the seven tag roster.
+    - Expected output: test-7-out.pgn
+    - Command: pgn-extract -7 -otest-7-out.pgn test-7.pgn
+
+-a / --append
+    + Input file containing games in any accepted format.
+    - Input file(s): test-a.txt
+    - Resulting output should contain two versions of the input game
+      formatted in PGN. The --output command is run first to create
+      a new file, then the -a version to append to that file.
+    - Expected output: test-a-out.pgn
+    - Command: pgn-extract --output test-a-out.pgn test-a.txt
+              pgn-extract -atest-a-out.pgn test-a.txt
+
+    - Command: pgn-extract --output test-a-out.pgn test-a.txt
+              pgn-extract --append test-a-out.pgn test-a.txt
+
+-A
+    + Input file containing games and a file of arguments.
+    - Input file(s): fischer.pgn, petrosian.pgn, arglist.txt
+    - Resulting output should be files separating the unique and
+      duplicated games in the input files.
+    - Expected output: test-A-unique.pgn, test-A-dupes.pgn
+    - Command: pgn-extract -Aargslist.txt
+
+-b
+    + Input file containing games of different length.
+    - Input file(s): fischer.pgn
+    - Resulting output: games whose number of moves is within
+      the specified bounds.
+
+    - Expected output: 45 moves or more: fischer-bl45-out.pgn
+    - Command: pgn-extract -bl45 -ofischer-bl45-out.pgn fischer.pgn
+
+    - Expected output: 45 moves or less: fischer-bu45-out.pgn
+    - Command: pgn-extract -bu45 -ofischer-bu45-out.pgn fischer.pgn
+
+    - Expected output: exactly 30 moves: fischer-b30-out.pgn
+    - Command: pgn-extract -b30 -ofischer-b30-out.pgn fischer.pgn
+
+
+-c / --checkfile
+    + Input files containing games.
+    - Input file(s): fischer.pgn, petrosian.pgn
+    - Resulting output should contain matched games that do not already occur in
+      the check file.
+    - Expected output: test-c-out.pgn
+    - Command: pgn-extract -cpetrosian.pgn -D -TpPetrosian -otest-c-out.pgn fischer.pgn
+    - Command: pgn-extract -cclist.txt -D -TpPetrosian -otest-c-out.pgn fischer.pgn
+
+-C / --nocomments
+    + Input file containing games with comments
+    - Input file(s): test-C.pgn
+    - Resulting output should have all comments removed.
+    - Expected output: test-C-out.pgn
+    - Command: pgn-extract -C -otest-C-out.pgn test-C.pgn
+
+-d / --duplicates
+    + Input file containing games with duplicates and non-duplicates.
+    - Input file(s): fischer.pgn, petrosian.pgn
+    - Resulting output should be files separating the unique and
+      duplicated games in the input files.
+    - Expected output: test-d-unique.pgn, test-d-dupes.pgn
+    - Command: pgn-extract -dtest-d-dupes.pgn -otest-d-unique.pgn fischer.pgn petrosian.pgn
+
+-D / --noduplicates
+    + Input file containing games with duplicates and non-duplicates.
+    - Input file(s): fischer.pgn, petrosian.pgn
+    - Resulting output should be a file containing the combined input
+      with duplicate games removed.
+    - Expected output: test-D-unique.pgn
+    - Command: pgn-extract -D -otest-D-unique.pgn fischer.pgn petrosian.pgn
+    - Command: pgn-extract --noduplicates -otest-D-unique.pgn fischer.pgn petrosian.pgn
+
+-e
+    + Input file containing games without ECO classifications.
+    - Input file(s): test-e.pgn and eco.pgn in the test folder.
+    - Resulting output should have ECO classification added to the tags.
+    - Expected output: test-e-out.pgn
+    - Command: pgn-extract -e -otest-e-out.pgn test-e.pgn
+    - Command: pgn-extract -eeco.pgn -otest-e-out.pgn test-e.pgn
+
+-E
+    + Input file containing games.
+    - Input file(s): test-E.pgn and eco.pgn if -e flag is used.
+    - Resulting output should be separate files for each ECO classification
+      at the level of the initial letter (A-E).
+    - Expected output: A.pgn, B.pgn, E.pgn
+    - Command: pgn-extract -e -E1 test-E.pgn
+
+-f
+    + Input files containing games.
+    - Input file(s): test-f1.pgn, test-f2.pgn, files.txt
+    - Resulting output should be the combination of the input files.
+    - Expected output: test-f-out.pgn
+    - Command: pgn-extract -ffiles.txt -otest-f-out.pgn
+
+-F:
+    + Input file containing games without a trailing FEN comment.
+    - Input file(s): test-F.pgn
+    - Resulting output should have a comment at the end containing
+      the FEN description of the final position.
+    - Expected output: test-F-out.pgn
+    - Command: pgn-extract -F -otest-F-out.pgn test-F.pgn
+
+
+-h / -? / --help
+    + No input required.
+    - Input file(s): N/A
+    - Resulting output should be a description of how to use pgn-extract
+    - Expected output: N/A
+    - Command: pgn-extract -h
+    - Command: pgn-extract -?
+    - Command: pgn-extract --help
+
+-l
+    + Input file containing games.
+    - Input file(s): fischer.pgn
+    - Resulting output: List of games parsed written to log.txt
+    - Expected output: log.txt
+    - Command: pgn-extract -llog.txt -otest-l-out.pgn fischer.pgn
+
+-L
+    + Input file containing games.
+    - Input file(s): test-L1.pgn, test-L2.pgn
+    - Resulting output should be that log.txt contains the combined
+      logs from two runs of pgn-extract.
+    - Expected output: log.txt
+    - Command: pgn-extract -llog.txt -r test-L1.pgn
+               pgn-extract -Llog.txt -r test-L2.pgn
+
+-M / --checkmate
+    + Input file containing games.
+    - Input file(s): test-checkmate.pgn
+    - Resulting output should contain only those games that end in checkmate.
+    - Expected output: test-checkmate-out.pgn
+    - Command: pgn-extract --checkmate -otest-checkmate-out.pgn test-checkmate.pgn
+
+-n
+    + Input file containing games.
+    - Input file(s): petrosian.pgn
+    - Resulting output should be separate files containing matched
+      and non-matched games.
+    - Expected output: test-n-matched.pgn, test-n-unmatched.pgn
+    - Command: pgn-extract -TpFischer -otest-n-matched.pgn -ntest-n-unmatched.pgn petrosian.pgn
+
+-N / --nonags
+    + Input file containing games with NAGs.
+    - Input file(s): test-N.pgn
+    - Resulting output should have all NAGs removed.
+    - Expected output: test-N-out.pgn
+    - Command: pgn-extract -N -otest-N-out.pgn test-N.pgn
+
+
+-o / --output
+    + Input file containing games in any accepted format.
+    - Input file(s): test-o.txt
+    - Resulting output should contain the input game formatted in PGN.
+    - Expected output: test-o-out.pgn
+    - Command: pgn-extract -otest-o-out.pgn test-o.txt
+    - Command: pgn-extract --output test-o-out.pgn test-o.txt
+
+-P
+    + Input file containing games with different sequences for the same
+      opening.
+    - Input file(s): test-P.pgn, Pvars.txt
+    - Resulting output should be games whose opening move exactly match
+      the sequence specified in Pvars.txt
+    - Expected output: test-P-out.pgn
+    - Command: pgn-extract -P -vPvars.txt -otest-P-out.pgn test-P.pgn
+
+-r
+    + Input file containing games in any accepted format.
+    - Input file(s): test-r.text
+    - Resulting output should contain tag summary lines for the games
+      matched and a report of any errors.
+    - Expected output: test-r-log.text
+    - Command: pgn-extract -r -Ltest-r-log.txt test-r.txt
+
+-R
+    + Input file containing games.
+    - Input file(s): test-R.pgn, roster.txt
+    - Resulting output should contain games with their tag roster in
+      the order specified in roster.txt
+    - Expected output: test-R-out.pgn
+    - Command: pgn-extract -Rroster.txt --output test-R-out.pgn test-R.pgn
+
+-s
+    + Input file containing games.
+    - Input file(s): test-s.pgn
+    - Resulting output should be silent, with games written to the output file.
+    - Expected output: test-s-out.pgn
+    - Command: pgn-extract -s -o test-s-out.pgn test-s.pgn
+
+-S
+    + Input file containing games whose players' names have slight
+      sound variations from anglesized versions.
+    - Input file(s): test-S.pgn
+    - Resulting output should be games that match by ignoring slight
+      soundex differences.
+    - Expected output: test-S-out.pgn
+    - Command: pgn-extract -S -TpPetrosian -otest-S-out.pgn test-S.pgn
+
+-t
+    + Input file containing games and a file of tag criteria.
+    - Input file(s): test-t.pgn, taglist.txt
+    - Resulting output should be only those games whose tags match
+      all of the criteria.
+    - Expected output: test-t-out.pgn
+    - Command: pgn-extract -ttaglist.txt -otest-t-out.pgn test-t.pgn
+
+-T
+    + Input file containing games with tag information.
+    - Input file(s): fischer.pgn, test-Ta.pgn (and eco.pgn for -Te test.)
+    - Resulting output should contain only those games whose tag information
+      matches that specified.
+    - Expected output: test-Ta-out.pgn, test-Tb-out.pgn, test-Td-out.pgn,
+                       test-Te-out.pgn, test-Tp-out.pgn, test-Tw-out.pgn
+    - Command: pgn-extract -Td1970 -otest-Td-out.pgn fischer.pgn
+    - Command: pgn-extract -TbPetrosian -otest-Tb-out.pgn fischer.pgn
+    - Command: pgn-extract -e -TeB14 -otest-Te-out.pgn fischer.pgn
+    - Command: pgn-extract -TpPetrosian -otest-Tp-out.pgn fischer.pgn
+    - Command: pgn-extract -Tr0-1 -otest-Tr-out.pgn fischer.pgn
+    - Command: pgn-extract -TwFischer -otest-Tw-out.pgn fischer.pgn
+    - Command: pgn-extract -TaBarnes -otest-Ta-out.pgn test-Ta.pgn
+
+-U / --nounique
+    + Input file containing games with duplicates and non-duplicates.
+    - Input file(s): fischer.pgn, petrosian.pgn
+    - Resulting output should be a file containing just the duplicate games.
+    - Expected output: test-U-unique.pgn
+    - Command: pgn-extract -U -otest-U-unique.pgn fischer.pgn petrosian.pgn
+    - Command: pgn-extract --nounique -otest-U-unique.pgn fischer.pgn petrosian.pgn
+
+-v
+    + Input file containing games.
+    - Input file(s): najdorf.pgn, vvars.txt
+    - Resulting output should be only those games whose opening moves
+      textually match (in any order) the moves in vars.txt.
+    - Expected output: test-v-out.pgn
+    - Command: pgn-extract -vvvars.txt -otest-v-out.pgn najdorf.pgn
+
+-V
+    + Input file containing games with variations
+    - Input file(s): test-V.pgn
+    - Resulting output should have all variations removed.
+    - Expected output: test-V-out.pgn
+    - Command: pgn-extract -V -otest-V-out.pgn test-V.pgn
+
+-w / --linelength
+    + Input file containing games.
+    - Input file(s): test-w.pgn
+    - Resulting output Games formatted up to the specified line length.
+      The default is 75.
+    - Expected output: test-w60-out.pgn, test-w75-out.pgn, test-w1000-out.pgn
+    - Command: pgn-extract -w60 -otest-w60-out.pgn test-w.pgn
+    - Command: pgn-extract -w75 -otest-w75-out.pgn test-w.pgn
+    - Command: pgn-extract -w1000 -otest-w1000-out.pgn test-w.pgn
+
+    - Command: pgn-extract --linelength 60 -otest-w60-out.pgn test-w.pgn
+    - Command: pgn-extract --linelength 75 -otest-w75-out.pgn test-w.pgn
+    - Command: pgn-extract --linelength 1000 -otest-w1000-out.pgn test-w.pgn
+
+-W
+    + Input file containing games.
+    - Input file(s): test-W.pgn
+    - Resulting output should be games formatted in the specified notation:
+      halg (hyphenated long algebraic), lalg (non-hyphenated long algebraic),
+      elalg (enhanced long algebraic), and alternative piece letters.
+    - Expected output: test-Whalg-out.pgn, test-Wlalg-out.pgn,
+                       test-elalg-out.pgn, test-Wdeutsch-out.pgn
+    - Command: pgn-extract -Whalg -otest-Whalg-out.pgn test-W.pgn
+    - Command: pgn-extract -Wlalg -otest-Wlalg-out.pgn test-W.pgn
+    - Command: pgn-extract -Welalg -otest-Welalg-out.pgn test-W.pgn
+    - Command: pgn-extract -WsanBSLTDK -otest-Wdeutsch-out.pgn test-W.pgn
+
+-x
+    + Input file containing games.
+    - Input file(s): najdorf.pgn, xvars.txt
+    - Resulting output should be only those games which match
+      the result of reaching the opening sequence in vars.txt.
+    - Expected output: test-x-out.pgn
+    - Command: pgn-extract -xxvars.txt -otest-x-out.pgn najdorf.pgn
+
+-Z
+    + Input file containing games with duplicates and non-duplicates.
+    - Input file(s): fischer.pgn, petrosian.pgn
+    - Resulting output should be files separating the unique and
+      duplicated games in the input files.
+    - Expected output: test-Z-unique.pgn, test-Z-dupes.pgn
+    - Command: pgn-extract -Z -dtest-Z-dupes.pgn -otest-Z-unique.pgn fischer.pgn petrosian.pgn
+
+-z
+    + Input file containing games.
+    - Input file(s): petrosian.pgn, zmatch.txt
+    - Resulting output should be games whose material balance matches that
+      specified in zmatch.txt
+    - Expected output: test-z-out.pgn
+    - Command: pgn-extract -zzmatch.txt -otest-z-out.pgn petrosian.pgn
+
+-#
+    + Input file containing games.
+    - Input file(s): test-hash.pgn
+    - Resulting output The input file split in to separate sub-files,
+      each containing 10 games, except the last which may contain fewer.
+    - Expected output: 1.pgn, 2.pgn
+    - Command: pgn-extract -#20 test-hash.pgn
+
+--evaluation
+    + Input file containing games.
+    - Input file(s): test-evaluation.pgn
+    - Resulting output should include an evaluation value in a comment
+      after every move.
+    - Expected output: test-evaluation-out.pgn
+    - Command: pgn-extract --evaluation -otest-evaluation-out.pgn test-evaluation.pgn
+
+--fencomments
+    + Input file containing games.
+    - Input file(s): test-fencomments.pgn
+    - Resulting output should have a comment after every move containing a
+      FEN description of the position after that move.
+    - Expected output: test-fencomments-out.pgn
+    - Command: pgn-extract --fencomments -otest-fencomments-out.pgn test-fencomments.pgn
+
+--markmatches
+    + Input file containing games.
+    - Input file(s): najdorf.pgn, xvars.txt
+    - Resulting output should be only those games which match
+      the result of reaching the opening sequence in vars.txt.
+      The point of each match is marked with the comment { MATCH }
+    - Expected output: test-markmatches-out.pgn
+    - Command: pgn-extract --markmatches MATCH -xxvars.txt -otest-markmatches-out.pgn najdorf.pgn
+
+--nochecks
+    + Input file containing games with moves involving moves that give check
+      and/or mate.
+    - Input file(s): test-nochecks.pgn
+    - Resulting output should contain games with no check indicators after moves.
+    - Expected output: test-nochecks-out.pgn
+    - Command: pgn-extract --nochecks -otest-nochecks-out.pgn test-nochecks.pgn
+
+--nomovenumbers
+    + Input file containing games with move numbers.
+    - Input file(s): test-nomovenumbers.pgn
+    - Resulting output should contain games with no move numbers.
+    - Expected output: test-nomovenumbers-out.pgn
+    - Command: pgn-extract -otest-no-movenumbers-out.pgn --nomovenumbers test-nomovenumbers.pgn
+
+--noresults
+    + Input file containing games with results.
+    - Input file(s): test-noresults.pgn
+    - Resulting output should contain games with no results.
+    - Expected output: test-noresults-out.pgn
+    - Command: pgn-extract -otest-no-results-out.pgn --noresults test-noresults.pgn
+
+--notags
+    + Input file containing games with tag information.
+    - Input file(s): test-notags.pgn
+    - Resulting output should contain games with no tag information.
+    - Expected output: test-notags-out.pgn
+    - Command: pgn-extract -otest-no-tags-out.pgn --notags test-notags.pgn
+
+--plylimit
+    + Input file containing games.
+    - Input file(s): test-plylimit.pgn
+    - Resulting output should contain games whose number of moves (plies) are
+      limited at the specified ply limit.
+    - Expected output: test-plylimit-out.pgn
+    - Command: pgn-extract --plylimit 10 -otest-plylimit-out.pgn test-plylimit.pgn
+
+--stalemate
+    + Input file containing games.
+    - Input file(s): test-stalemate.pgn
+    - Resulting output should contain only those games that end in stalemate.
+    - Expected output: test-stalemate-out.pgn
+    - Command: pgn-extract --stalemate -otest-stalemate-out.pgn test-stalemate.pgn
diff --git a/tokens.h b/tokens.h
new file mode 100644 (file)
index 0000000..df064de
--- /dev/null
+++ b/tokens.h
@@ -0,0 +1,56 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+        /* Define a type for lexical classification of tokens.
+         * Not all of these values are returned to the parser.
+         */
+typedef enum {
+    /* The first section of tokens contains those that are
+     * returned to the parser as complete token identifications.
+     */
+    EOF_TOKEN, TAG, STRING, COMMENT, NAG,
+    CHECK_SYMBOL, MOVE_NUMBER, RAV_START, RAV_END,
+    MOVE, TERMINATING_RESULT,
+    /* The remaining tokens are those that are used to
+     * perform the identification.  They are not handled by
+     * the parser.
+     */
+    WHITESPACE, TAG_START, TAG_END, DOUBLE_QUOTE,
+    COMMENT_START, COMMENT_END, ANNOTATE,
+    DOT, PERCENT, ESCAPE, ALPHA, DIGIT,
+    STAR, DASH, EOS, OPERATOR, NO_TOKEN, ERROR_TOKEN
+} TokenType;
+
+typedef union {
+    /* This string is used to retain tag and result information. */
+    char *token_string;
+    /* Move information. */
+    Move *move_details;
+    unsigned move_number;
+    StringList *nags;
+    Variation *variation_details;
+    CommentList *comment;
+    /* An index into the Game_Header.Tags array for tag strings. */
+    unsigned tag_index;
+} YYSTYPE;
+
+extern YYSTYPE yylval;
diff --git a/typedef.h b/typedef.h
new file mode 100644 (file)
index 0000000..9f7f270
--- /dev/null
+++ b/typedef.h
@@ -0,0 +1,285 @@
+/*
+ *  Program: pgn-extract: a Portable Game Notation (PGN) extractor.
+ *  Copyright (C) 1994-2014 David Barnes
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 1, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  David Barnes may be contacted as D.J.Barnes@kent.ac.uk
+ *  http://www.cs.kent.ac.uk/people/staff/djb/
+ *
+ */
+
+        /* Type definitions required by multiple files. */
+
+    /* Define a type to represent different output formats.
+     * Currently represented are:
+     *     SOURCE: the original source notation.
+     *           SAN: SAN.
+     *           CM: Chess Master input format.
+     *     LALG: Long-algebraic, e.g. e2e4.
+     *     HALG: Hyphenated long-algebraic, e.g. e2-e4.
+     *     ELALG: Enhanced long-algebraic. Includes piece names, e.g. Ng1f3,
+     *            and en-passant notation.
+     *     UCI: UCI-compatible format - actually LALG.
+     */
+typedef enum { SOURCE, SAN, EPD, CM, LALG, HALG, ELALG, UCI } OutputFormat;
+
+    /* Define a type to specify whether a move gives check, checkmate,
+     * or nocheck.
+     * checkmate implies check, but check does not imply that a move
+     * is not checkmate.
+     */
+typedef enum { NOCHECK, CHECK, CHECKMATE } CheckStatus;
+
+        /* Permit lists of strings, e.g. lists of comments,
+         * list of NAGs, etc.
+         */
+typedef struct string_list {
+    const char *str;
+    struct string_list *next;
+} StringList;
+
+/* The following function is used for linking list items together. */
+StringList *save_string_list_item(StringList *list,const char *str);
+
+typedef struct comment_list{
+    StringList *Comment;
+    struct comment_list *next;
+} CommentList;
+
+typedef struct variation{
+    CommentList *prefix_comment;
+    struct move *moves;
+    CommentList *suffix_comment;
+    struct variation *next;
+} Variation;
+
+/* Define a maximum length for the text of moves.
+ * This is generous.
+ */
+#define MAX_MOVE_LEN 15
+
+        /* Retain the text of a move and any associated 
+         * NAGs and comments.
+         */
+typedef struct move{
+    /* @@@ This array is of type unsigned char,
+     * in order to accommodate full 8-bit letters without
+     * sign extension.
+     */
+    unsigned char move[MAX_MOVE_LEN+1];
+    /* Class of move, e.g. PAWN_MOVE, PIECE_MOVE. */
+    MoveClass class;
+    Col from_col;
+    Rank from_rank;
+    Col to_col;
+    Rank to_rank;
+    Piece piece_to_move;
+    /* captured_piece is EMPTY if there is no capture. */
+    Piece captured_piece;
+    /* promoted_piece is EMPTY if class is not PAWN_MOVE_WITH_PROMOTION. */
+    Piece promoted_piece;
+    /* Whether this move gives check. */
+    CheckStatus check_status;
+    /* An EPD representation of the board immediately after this move
+     * has been played.
+     */
+    char *epd;
+    StringList *Nags;
+    CommentList *Comment;
+    /* terminating_result hold the result of the current list of moves. */
+    char *terminating_result;
+    Variation *Variants;
+    /* Pointers to the previous and next move.
+     * The extraction program does not need the prev field, but my
+     * intention is to build other interfaces that might need it.
+     * For instance, a game viewer would need to be able to move backwards
+     * and forwards through a game.
+     */
+    struct move *prev, *next;
+} Move;
+
+typedef struct {
+    /* Tags for this game. */
+    char **tags;
+    /* The maximum number of strings in tags. */
+    int tags_length;
+    /* Any comment prefixing the game, between
+     * the tags and the moves.
+     */
+    CommentList *prefix_comment;
+    /* The hash value of the final position. */
+    HashCode final_hash_value;
+    /* An accumulated hash value, used to disambiguate false clashes
+     * of final_hash_value.
+     */
+    HashCode cumulative_hash_value;
+    /* Board hash value at fuzzy_move_depth, if required. */
+    HashCode fuzzy_duplicate_hash;
+    /* The move list of the game. */
+    Move *moves;
+    /* Whether the moves have been checked, or not. */
+    Boolean moves_checked;
+    /* Whether the moves are ok, or not. */
+    Boolean moves_ok;
+    /* if !moves_ok, the first ply at which an error was found.
+     * 0 => no error found.
+     */
+    int error_ply;
+} Game;
+
+/* Define a type to distinguish between CHECK files, NORMAL files,
+ * and ECO files.
+ * CHECKFILEs are those whose contents are not output.
+ * Their contents are used to check for duplicates in NORMALFILEs.
+ * An ECOFILE consists of ECO lines for classification.
+ */
+typedef enum { NORMALFILE, CHECKFILE, ECOFILE } SourceFileType;
+
+/*    0 = don't divide on ECO code.
+ *    1 = divide by letter.
+ *    2 = divide by letter and single digit.
+ *    N > 1 = divide by letter and N-1 digits.
+ *    In principle, it should be possible to expand the ECO classification
+ *    with an arbitrary number of digits.
+ */
+typedef enum {
+    DONT_DIVIDE = 0, MIN_ECO_LEVEL = 1, MAX_ECO_LEVEL = 10
+} EcoDivision;
+
+/* Define a type to describe which tags are to be output.
+ * This used to be handled by the Boolean seven_tag_roster field
+ * in GlobalState but there are now different forms of output
+ * available.
+ */
+typedef enum {
+    ALL_TAGS = 0, SEVEN_TAG_ROSTER = 1, NO_TAGS = 2
+} TagOutputForm;
+
+/* This structure holds details of the program state.
+ * Most of these fields are set from the program's arguments.
+ */
+typedef struct {
+    /* Whether we are skipping the current game - typically because
+     * of an error in its text.
+     */
+    Boolean skipping_current_game;
+    /* Whether to check, but not write the converted output. */
+    Boolean check_only;
+    /* Whether to print a running commentary to logfile. */
+    Boolean verbose;
+    /* Whether to keep NAGs along with moves. */
+    Boolean keep_NAGs;
+    /* Whether to keep comments along with moves. */
+    Boolean keep_comments;
+    /* Whether to keep variations along with moves. */
+    Boolean keep_variations;
+    /* Which tags are to be output. */
+    TagOutputForm tag_output_format;
+    /* Whether to match permutations of textual variations or not. */
+    Boolean match_permutations;
+    /* Whether we are matching positional variations or not. */
+    Boolean positional_variations;
+    /* Whether we are using Soundex matching or not. */
+    Boolean use_soundex;
+    /* Whether to suppress duplicate game scores. */
+    Boolean suppress_duplicates;
+    /* Whether to suppress unique game scores. */
+    Boolean suppress_originals;
+    /* Whether to use fuzzy matching for duplicates. */
+    Boolean fuzzy_match_duplicates;
+    /* At what depth to use fuzzy matching. */
+    int fuzzy_match_depth;
+    /* Whether to check the tags for matches. */
+    Boolean check_tags;
+    /* Whether to add ECO codes. */
+    Boolean add_ECO;
+    /* Whether an ECO file is currently being parsed. */
+    Boolean parsing_ECO_file;
+    /* Which level to divide the output. */
+    EcoDivision ECO_level;
+    /* What form to write the output in. */
+    OutputFormat output_format;
+    /* Maximum output line length. */
+    unsigned max_line_length;
+    /* Whether to use a virtual hash table or not. */
+    Boolean use_virtual_hash_table;
+    /* Whether to match on the number of moves in a game. */
+    Boolean check_move_bounds;
+    /* Whether to match only games ending in checkmate. */
+    Boolean match_only_checkmate;
+    /* Whether to match only games ending in stalemate. */
+    Boolean match_only_stalemate;
+    /* Whether to output move numbers in the output. */
+    Boolean keep_move_numbers;
+    /* Whether to output results in the output. */
+    Boolean keep_results;
+    /* Whether to keep check and mate characters in the output. */
+    Boolean keep_checks;
+    /* Whether to output an evaluation value after each move. */
+    Boolean output_evaluation;
+    /* Whether to keep games which have incorrect moves. */
+    Boolean keep_broken_games;
+    /* Maximum depth to which to search for positional variations.
+     * This is picked up from the length of variations in the positional
+     * variations file.
+     */
+    unsigned depth_of_positional_search;
+    unsigned long num_games_processed;
+    unsigned long num_games_matched;
+    /* How many games to store in each file. */
+    unsigned games_per_file;
+    /* Which is the next file number. */
+    unsigned next_file_number;
+    /* Lower and upper bounds for moves if check_move_bounds. */
+    unsigned lower_move_bound, upper_move_bound;
+    /* Limit to the number of plies to appear in the output. */
+    int output_ply_limit;
+    /* Which single game to output (matching_game_number > 0) */
+    unsigned long matching_game_number;
+    /* Whether to output a FEN string at the end of the game. */
+    Boolean output_FEN_string;
+    /* Whether to add a FEN comment after every move. */
+    Boolean add_FEN_comments;
+    /* Whether to add a 'matching position' comment. */
+    Boolean add_position_match_comments;
+    /* Whether to include a tag with the total ply count of the game. */
+    Boolean output_total_plycount;
+    /* Whether to add a HashCode tag. */
+    Boolean add_hashcode_tag;
+    /* The comment to use for position matches, if required. */
+    const char *position_match_comment;
+    /* Current input file name. */
+    const char *current_input_file;
+    /* Whether this is a CHECKFILE or a NORMALFILE. */
+    SourceFileType current_file_type;
+    /* File of ECO lines. */
+    const char *eco_file;
+    /* Where to write the extracted games. */
+    FILE *outputfile;
+    /* Output file name. */
+    const char *output_filename;
+    /* Where to write errors and running commentary. */
+    FILE *logfile;
+    /* Where to write duplicate games. */
+    FILE *duplicate_file;
+    /* Where to write games that don't match the criteria. */
+    FILE *non_matching_file;
+} StateInfo;
+
+/* Provide access to the global state that has been set
+ * through command line arguments.
+ */
+extern StateInfo GlobalState;
+FILE *must_open_file(const char *filename,const char *mode);